0% found this document useful (0 votes)
330 views345 pages

Turbo C

This document provides an overview of a C programming tutorial. It discusses C as a high-level programming language that is well-suited for modern computers. While C shields users from machine code details, it also provides access to lower machine levels. The tutorial aims to teach C to beginners through examples and exercises while explaining the language's features and philosophy. It emphasizes C's flexibility, efficiency, and ability to clearly communicate solutions to problems.

Uploaded by

Ermercado78
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
330 views345 pages

Turbo C

This document provides an overview of a C programming tutorial. It discusses C as a high-level programming language that is well-suited for modern computers. While C shields users from machine code details, it also provides access to lower machine levels. The tutorial aims to teach C to beginners through examples and exercises while explaining the language's features and philosophy. It emphasizes C's flexibility, efficiency, and ability to clearly communicate solutions to problems.

Uploaded by

Ermercado78
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 345

Node:Top, Next:Preface, Previous:(dir), Up:(dir)

C Programming Tutorial (K&R version


4)
This is a C Programming Tutorial for people who have a little experience with an
interpreted programming language, such as Emacs isp or a !NU shell"
Edition #"$%
Cop&right ' ()*+,())) ,ar- .urgess
Permission is granted to ma-e and distri/ute ver/atim copies of this manual
provided the cop&right notice and this permission notice are preserved on all
copies"
0ntroduction:
1eserved words 2 example:
3perating s&stems:
i/raries:
Programming st&le:
4orm of a C program:
Comments:
4unctions:
5aria/les:
Parameters:
6cope:
Preprocessor:
Pointers:
6tandard 3utput and 6tandard 0nput:
7ssignments Expressions and 3perators:
8ecisions:
oops:
7rra&s:
6trings:
Putting together a program:
6pecial i/rar& 4unctions and ,acros:
9idden 3perators:
,ore on 8ata T&pes:
,achine evel 3perations:
4iles and 8evices:
6tructures and Unions:
8ata structures:
1ecursion:
Example Programs chapter:
Errors and de/ugging:
6ummar&:
reserved words list:
Comparisons :
Character Conversion Ta/le:
Emacs st&le file:
Preface
Ever& program is limited /& the language which is used to write it" C is a
programmer:s language" Unli-e .760C or Pascal, C was not written as a teaching
aid, /ut as an implementation language" C is a computer language and a
programming tool which has grown popular /ecause programmers li-e it; 0t is a
tric-& language /ut a masterful one" 6ceptics have said that it is a language in
which ever&thing which can go wrong does go wrong" True, it does not do much
hand holding, /ut also it does not hold an&thing /ac-" 0f &ou have come to C in the
hope of finding a powerful language for writing ever&da& computer programs, then
&ou will not /e disappointed" C is ideall& suited to modern computers and modern
programming"
This /oo- is a tutorial" 0ts aim is to teach C to a /eginner, /ut with enough of the
details so as not /e outgrown as the &ears go /&" 0t presumes that &ou have some
previous a<uaintance with programming == &ou need to -now what a varia/le is
and what a function is == /ut &ou do not need much experience" 0t is not essential to
follow the order of the chapters rigorousl&, /ut if &ou are a /eginner to C it is
recommended" >hen it comes down to it, most languages have /asicall& the same
-inds of features: varia/les, wa&s of ma-ing loops, wa&s of ma-ing decisions,
wa&s of accessing files etc" 0f &ou want to plan &our assault on C, thin- a/out what
&ou alread& -now a/out programming and what &ou expect to loo- for in C" ?ou
will most li-el& find all of those things and more, as &ou wor- though the chapters"
The examples programs range from <uic- one=function programs, which do no
more than illustrate the sole use of one simple feature, to complete application
examples occup&ing several pages" 0n places these examples ma-e use of features
/efore the& have properl& /een explained" These programs serve as a taster of what
is to come"
Mark Burgess. 19!" 1999
#ntro$uction
What is C? What is it for? Why is it special?
evels:
.asic ideas:
The compiler:
Errors:
Use of Upper and ower Case:
@uestions (:
%ig& 'evels an$ 'o( 'evels
7n& -ind of o/Aect that is sufficientl& complicated can /e thought of as having
levels of detailB the amount of detail we see depends upon how closel& we
scrutiniCe it" 7 computer falls definitel& into the categor& of complex o/Aects and it
can /e thought of as wor-ing at man& different levels" The terms low level and
high level are often used to descri/e these onion=la&ers of complexit& in
computers" ow level is perhaps the easiest to understand: it descri/es a level of
detail which is /uried down amongst the wor-ing parts of the machine: the low
level is the level at which the computer seems most primitive and machine=li-e" 7
higher level descri/es the same o/Aect, /ut with the detail left out" 0magine
stepping /ac- from the complexit& of the machine level pieces and grouping
together parts which wor- together, then covering up all the details" (4or instance,
in a car, a group of nuts, /olts, pistons can /e grouped together to ma-e up a new
/asic o/Aect: an engine") 7t a high level a computer /ecomes a group of /lac-
/oxes which can then /e thought of as the /asic components of the computer"
C is called a high level, compiler language" The aim of an& high level computer
language is to provide an eas& and natural wa& of giving a programme of
instructions to a computer (a computer program)" The language of the raw
computer is a stream of num/ers called machine code" 7s &ou might expect, the
action which results from a single machine code instruction is ver& primitive and
man& thousands of them are re<uired to ma-e a program which does an&thing
su/stantial" 0t is therefore the Ao/ of a high level language to provide a new set of
/lac- /ox instructions, which can /e given to the computer without us needing to
see what happens inside them = and it is the Ao/ of a compiler to fill in the details of
these D/lac- /oxesD so that the final product is a se<uence of instructions in the
language of the computer"
C is one of a large num/er of high level languages which can /e used for general
purpose programming, that is, an&thing from writing small programs for personal
amusement to writing complex applications" 0t is unusual in several wa&s" .efore
C, high level languages were criticiCed /& machine code programmers /ecause
the& shielded the user from the wor-ing details of the computer, with their /lac-
/ox approach, to such an extent that the languages /ecome inflexi/le: in other
words, the& did not not allow programmers to use all the facilities which the
machine has to offer" C, on the other hand, was designed to give access to an& level
of the machine down to raw machine code and /ecause of this it is perhaps the
most flexi/le of all high level languages"
6urprisingl&, programming /oo-s often ignore an important role of high level
languages: high level programs are not onl& a wa& to express instructions to the
computer, the& are also a means of communication among human /eings" The& are
not merel& monologues to the machine, the& are a wa& to express ideas and a wa&
to solve pro/lems" The C language has /een e<uipped with features that allow
programs to /e organiCed in an eas& and logical wa&" This is vitall& important for
writing length& programs /ecause complex pro/lems are onl& managea/le with a
clear organiCation and program structure" C allows meaningful varia/le names and
meaningful function names to /e used in programs without an& loss of efficienc&
and it gives a complete freedom of st&leB it has a set of ver& flexi/le loop
constructions (for, while, do) and neat wa&s of ma-ing decisions" These provide
an excellent /asis for controlling the flow of programs"
7nother unusual feature of C is the wa& it can express ideas concisel&" The
richness of a language shapes what it can tal- a/out" C gives us the apparatus to
/uild neat and compact programs" This sounds, first of all, either li-e a great /onus
or something a /it suspect" 0ts conciseness can /e a mixed /lessing: the aim is to
tr& to see- a /alance /etween the often conflicting interests of reada/ilit& of
programs and their conciseness" .ecause this side of programming is so often
presumed to /e understood, we shall tr& to develop a st&le which finds the right
/alance"
C allows things which are disallowed in other languages: this is no defect, /ut a
ver& powerful freedom which, when used with caution, opens up possi/ilities
enormousl&" 0t does mean however that there are aspects of C which can run awa&
with themselves unless some care is ta-en" The programmer carries an extra
responsi/ilit& to write a careful and thoughtful program" The reward for this care is
that fast, efficient programs can /e produced"
C tries to ma-e the /est of a computer /& lin-ing as closel& as possi/le to the local
environment" 0t is no longer necessar& to have to put up with hopelessl& inade<uate
inputEoutput facilities an&more (a legac& of the timesharingEmainframe computer
era): one can use ever&thing that a computer has to offer" 7/ove all it is flexi/le"
Clearl& no language can guarantee intrinsicall& good programs: there is alwa&s a
responsi/ilit& on the programmer, personall&, to ensure that a program is neat,
logical and well organiCed, /ut it can give a framewor- in which it is eas& to do so"
The aim of this /oo- is to conve& some of the C philosoph& in a practical wa& and
to provide a comprehensive introduction to the language /& appealing to a num/er
of examples and /& stic-ing to a strict structuring scheme" 0t is hoped that this will
give a flavour of the -ind of programming which C encourages"
Basic i$eas a)out C
What to do with a compiler. What can go wrong.
Using a compiler language is not the same as using an interpreted language li-e
.760C or a !NU shell" 0t differs in a num/er of wa&s" To /egin with, a C program
has to /e created in two stages:
4irstl&, the program is written in the form of a num/er of text files using a
screen editor" This form of the program is called the source program" 0t is
not possi/le to execute this file directl&"
6econdl&, the completed source file is passed to a compiler==a program
which generates a new file containing a machine code translation of the
source text" This file is called an o/Aect file or executa/le file" The
executa/le file is said to have /een compiled from the source text"
Compiler languages do not usuall& contain their own editor, nor do the& have
words li-e RUN with which to execute a finished program" ?ou use a screen editor
to create the words of a program (program text) and run the final program in its
compiled form usuall& /& simpl& t&ping the name of the executa/le file"
The compiler:
Errors:
T&e Com*iler
7 C program is made /& running a compiler which ta-es the t&ped source program
and converts it into an o/Aect file that the computer can execute" 7 compiler usuall&
operates in two or more phases (and each phase ma& have stages within it)" These
phases must /e executed one after the other" 7s we shall see later, this approach
provides a flexi/le wa& of compiling programs which are split into man& files"
7 two=phase compiler wor-s in the following wa&:
Phase ( scans a source program, perhaps generating an intermediate code
(<uadruples or pcode) which helps to simplif& the grammar of the language
for su/se<uent processing" 0t then converts the intermediate code into a file
of o/Aect code (though this is usuall& not executa/le &et)" 7 separate o/Aect
file is /uilt for each separate source file" 0n the !NU C compiler, these two
stages are run with the command gcc -cB the output is one or more .o files"
Phase % is a in-er" This program appends standard li/rar& code to the
o/Aect file so that the code is complete and can Dstand aloneD" 7 C compiler
lin-er suffers the slightl& arduous tas- of lin-ing together all the functions in
the C program" Even at this stage, the compiler can fail, if it finds that it has
a reference to a function which does not exist" >ith the !NU C compiler
this stage is activated /& the command gcc -o or ld"
To avoid the irritation of t&ping two or three separate commands (which are often
cum/ersome) &ou will normall& find a simple interface for executing compiler"
Traditionall& this is an executa/le program called cc for C Compiler:
cc filename
gcc filename
3n !NU s&stems, this results in the creation of an executa/le program with the
default name a.out" To tell the compiler what &ou would li-e the executa/le
program to /e called, use the -o option for setting the name of the o/Aect code:
gcc -o program-name filname
4or example, to create a program called myprog from a file called myprog.c, write
gcc -o myprog myprog.c
+rrors
Errors are mista-es which we the programmers ma-e" There are different -inds of
error:
Syntax
Errors in the s&ntax, or word structure of a program are caught /efore &ou
run it, at compilation time /& the compiler program" The& are listed all in
one go, with the line num/er, in the text file, at which the error occurred and
a message to sa& what was wrong"
4or example, suppose &ou write sin (x) y = ; in a program instead of y
= sin (x);, which assigns the value of the sin of x to y" Upon compilation,
&ou would see this error message:
eg.c: n function !main":
eg.c:#$: parse error %efore !y"
(0f &ou compile the program in Emacs, &ou can Aump directl& to the error")
7 program with s&ntax errors will cause a compiler program to stop tr&ing to
generate machine code and will not create an executa/le" 9owever, a
compiler will usuall& not stop at the first error it encounters /ut will attempt
to continue chec-ing the s&ntax of a program right to the last line /efore
a/orting, and it is common to su/mit a program for compilation onl& to
receive a long and ungratif&ing list of errors from the compiler"
0t is a shoc- to ever&one using a compiler for the first time how a single
error can throw the compiler off course and result in a huge and confusing
list of non=existent errors, following a single true culprit" The situation thus
loo-s much worse than it reall& is" ?ou:ll get used to this with experience,
/ut it can /e ver& disheartening"
7s a rule, loo- for the first error, fix that, and then recompile" 3f course,
after &ou have /ecome experienced, &ou will recogniCe when su/se<uent
error messages are due to independent pro/lems and when the& are due to a
cascade" .ut at the /eginning, Aust loo- for and fix the first error"
Intention
Errors in goal or purpose (logical errors) occur when &ou write a program
that wor-s, /ut does not do what &ou intend it to do" ?ou intend to send a
letter to all drivers whose licenses will expire soonB instead, &ou send a letter
to all drivers whose licenses will expire sometime"
0f the compilation of a program is successful, then a new file is created" This file
will contain machine code which can /e executed according to the rules of the
computer:s local operating s&stem"
>hen a programmer wants to ma-e alterations and corrections to a C program,
these have to /e made in the source text file itself using an editorB the program, or
the salient parts, must then /e recompiled"
,se of ,**er an$ 'o(er Case
3ne of the reasons wh& the compiler can fail to produce the executa/le file for a
program is &ou have mist&ped something, even through the careless use of upper
and lower case characters" The C language is case dependent" Unli-e languages
such as Pascal and some versions of .760C, the C compiler distinguishes /etween
small letters and capital letters" This is a potential source of <uite trivial errors
which can /e difficult to spot" 0f a letter is t&ped in the wrong case, the compiler
will complain and it will not produce an executa/le program"
-eclarations
Compiler languages re<uire us to ma-e a list of the names and t&pes of all
varia/les which are going to /e used in a program and provide information a/out
where the& are going to /e used" This is called declaring varia/les" 0t serves two
purposes: firstl&, it provides the compiler with a definitive list of the varia/les,
ena/ling it to cross chec- for errors, and secondl&, it informs the compiler how
much space must /e reserved for each varia/le when the program is run" C
supports a variet& of varia/le t&pes (varia/les which hold different -inds of data)
and allows one t&pe to /e converted into another" Conse<uentl&, the t&pe of a
varia/le is of great importance to the compiler" 0f &ou fail to declare a varia/le, or
declare it to /e the wrong t&pe, &ou will see a compilation error"
Node:@uestions (, Previous:Use of Upper and ower Case, Up:0ntroduction
.uestions
(" >hat is a compilerF
%" 9ow is a C program runF
G" 9ow is a C program compiled usuall&F
#" 7re upper and lower case e<uivalent in CF
H" >hat the two different -inds of error which can /e in a programF
Reserve$ (or$s an$ an e/am*le
C programs are constructed from a set of reserved words which provide control
and from li/raries which perform special functions" The /asic instructions are /uilt
up using a reserved set of words, such as main, for, if,while, default, dou%le,
extern, for, and int, to name Aust a few" These words ma& not /e used in Aust an&
old wa&: C demands that the& are used onl& for giving commands or ma-ing
statements" ?ou cannot use default, for example, as the name of a varia/le" 7n
attempt to do so will result in a compilation error"
6ee 7ll the 1eserved >ords, for a complete list of the reserverd words"
>ords used in included li/aries are also, effectivel&, reserved" 0f &ou use a word
which has alread& /een adopted in a li/rar&, there will /e a conflict /etween &our
choice and the li/rar&"
i/raries provide frequently used functionality and, in practice, at least one li/rar&
must /e included in ever& program: the so=called C li/rar&, of standard functions"
4or example, the stdio li/rar&, which is part of the C li/rar&, provides standard
facilities for input to and output from a program"
0n fact, most of the facilities which C offers are provided as li/raries that are
included in programs as plug=in expansion units" >hile the features provided /&
li/raries are not strictl& a part of the C language itself, the& are essential and &ou
will never find a version of C without them" 7fter a li/rar& has /een included in a
program, its functions are defined and &ou cannot use their names"
printf:
Example (:
3utput (:
@uestions %:
T&e printf() function
3ne invalua/le function provided /& the standard inputEoutput li/rar& is called
printf or Iprint=formatted:" 0t provides an super/l& versatile wa& of printing text"
The simplest wa& to use it is to print out a literal string:
printf (&..some string...&);
Text is eas&, /ut we also want to /e a/le to print out the contents of varia/les"
These can /e inserted into a text string /& using a Icontrol se<uence: inside the
<uotes and listing the varia/les after the string which get inserted into the string in
place of the control sequence" To print out an integer, the control se<uence 'd is
used:
printf (&nteger = 'd&(someinteger);
The varia/le someinteger is printed instead of 'd" The printf function is
descri/ed in full detail in the relevant chapter, /ut we:ll need it in man& places
/efore that" The example program /elow is a complete program" 0f &ou are reading
this in 0nfo, &ou can cop& this to a file, compile and execute it"
+/am*le 'isting
)***********************************************************)
)* +hort ,oem *)
)***********************************************************)
-include .stdio.h/
)***********************************************************)
main () )* ,oem *)
0
printf (&1stronomy is 'dderful 2n&(#);
printf (&1nd interesting 'd 2n&($);
printf (&3he ear'd 4ol4es around the sun 2n&(5);
printf (&1nd ma6es a year 'd you 2n&(7);
printf (&3he moon affects the sur 'd heard 2n&(8);
printf (&9y law of phy'd great 2n&(:);
printf (&t 'd when the the stars so %right 2n&(;);
printf (&<o nightly scintill'd 2n&(=);
printf (&f watchful pro4idence %e'd 2n&(>);
printf (&?ith good intentions fraught 2n&);
printf (&+hould not 6eep up her watch di4ine 2n&);
printf (&?e soon should come to 'd 2n&(@);
A

0ut*ut
1stronomy is #derful 2n&
1nd interesting $
3he ear5 4ol4es around the sun
1nd ma6es a year 7 you
3he moon affects the sur 8 heard
9y law of phy:d great
t ; when the the stars so %right
<o nightly scintill=
f watchful pro4idence %e>
?ith good intentions fraught
+hould not 6eep up her watch di4ine
?e soon should come to @
.uestions
(" >rite a command to print out the message D>ow /ig dealD"
%" >rite a command to print out the num/er %%F
G" >rite two commands to print out DThe G >ise ,enD two different wa&s"
#" >h& are there onl& a few reserved command words in CF
0*erating s1stems an$ environments
Where is a C program born? How is it created?
The /asic control of a computer rests with its operating s&stem" This is a la&er of
software which drives the hardware and provides users with a comforta/le
environment in which to wor-" 7n operating s&stem has two main components
which are of interest to users: a user interface (often a command language) and a
filing system" The operating s&stem is the route to all input and output, whether it
/e to a screen or to files on a dis-" 7 programming language has to get at this input
and output easil& so that programs can send out and receive messages from the
user and it has to /e in contact with the operating s&stem in order to do this" 0n C
the lin- /etween these two is ver& efficient"
3perating s&stems var& widel& /ut most have a command language or shell which
can /e used to t&pe in commands" 1ecentl& the tendenc& has /een to tr& to
eliminate t&ping completel& /& providing graphical user interfaces (!U0s) for
ever& purpose" !U0s are good for carr&ing out simple procedures li-e editing, /ut
the& are not well suited to giving complicated instructions to a computer" 4or that
one needs a command language" 0n the networ- version of this /oo- we shall
concentrate on Unix shell commands since the& are the most important to
programmers" 3n microcomputers command languages are usuall& ver& similar in
concept, though more primitive, with onl& slightl& different words for essentiall&
the same commands" (This is a slightl& superficial view)"
>hen most compiler languages were developed, the& were intended to /e run on
large mainframe computers which operated on a multi=user, time=sharing principle
and were incapa/le of interactive communication with the user" ,an& compiler
languages still have this inade<uac& when carried over to modern computers, /ut C
is an exception, /ecause of its uni<ue design" 0nput and output are not actuall&
defined as a fixed, unchanging part of the C language" 0nstead there is a standard
file which has to /e included in programs and defines the inputEoutput commands
that are supported /& the language for a particular computer and operating s&stem"
This file is called a standard C li/rar&" (6ee the next chapter for more information")
The li/rar& is standard in the sense that C has developed a set of functions which
all computers and operating s&stems must implement, /ut which are speciall&
adapted to &our s&stem"
4iles devices:
4ilenames:
Command languages:
@uestions G:

2iles an$ -evices
The filing s&stem is also a part of inputEoutput" 0n man& operating s&stems all
routes in and out of the computer are treated /& the operating s&stem as though
the& were files or data streams (even the -e&/oard;)" C does this implicitl& (it
comes from Unix)" The file from which C normall& gets its input from is called
stdin or standard input file and it is usuall& the -e&/oard" The corresponding route
for output is called DstdoutD or standard output file and is usuall& a monitor screen"
.oth of these are parts of stdio or standard input output" The -e&/oard and the
monitor screen are not reall& files, of course, the& are Idevices:, (it is not possi/le
to re=read what has /een sent to the monitorD, or write to the -e&/oard"), /ut
devices are represented /& files with special names, so that the -e&/oard is treated
as a read=onl& file, the monitor as a write onl& file""" The advantage of treating
devices li-e this is that it is not necessar& to -now how a particular device wor-s,
onl& that it exists somewhere, connected to the computer, and can /e written to or
read from" 0n other words, it is exactl& the same to read or write from a device as it
is to read or write from a file" This is a great simplification of inputEoutput; The
filenames of devices (often given the loft& title Ipseudo device names:) depend
upon &our particular operating s&stem" 4or instance, the printer might /e called
DP1ND or DP1TD" ?ou might have to open it explicitl& as a file" >hen input is ta-en
solel& from the -e&/oard and output is alwa&s to the screen then these details can
Aust /e forgotten"
Node:4ilenames, Next:Command languages, Previous:4iles devices, Up:3perating
s&stems
2ilenames
The compiler uses a special convention for the file names, so that we do not
confuse their contents" The name of a source program (the code which &ou write)
is filename.c" The compiler generates a file of o/Aect code from this called
filename.o, as &et unlin-ed" The final program, when lin-ed to li/raries is called
filename on Unix=li-e operating s&stems, and filename.BCB on >indows derived
s&stems" The li/raries themselves are also files of o/Aect code, t&picall& called
li%libraryname.a or li%libraryname.so" 9eader files are alwa&s called
libname.h"
The endings Idot something: (called file extensions) identif& the contents of files
for the compiler" The dotted endings mean that the compiler can generate an
executa/le file with the same name as the original source = Aust a different ending"
The <uad file and the o/Aect file are onl& wor-ing files and should /e deleted /&
the compiler at the end of compilation" The .c suffix is to tell the compiler that the
file contains a C source program and similarl& the other letters indicate non=source
files in a convenient wa&" To execute the compiler &ou t&pe,
cc filename
4or example,
cc foo.c
Node:Command languages, Next:@uestions G, Previous:4ilenames, Up:3perating
s&stems
Comman$ 'anguages an$ Consoles
0n order to do an&thing with a compiler or an editor &ou need to -now a little a/out
the command language of the operating s&stem" This means the instructions which
can /e given to the s&stem itself rather than the words which ma-e up a C program"
e"g"
ls -l
less filename
emacs filename
0n a large operating s&stem (or even a relativel& small one) it can /e a maAor feat of
recollection to -now all of the commands" 4ortunatel& it is possi/le to get /& with
-nowing Aust handful of the most common ones and having the s&stem manual
around to leaf through when necessar&"
7nother important o/Aect is the Ipanic /utton: or program interruption -e&" Ever&
s&stem will have its own wa& of halting or terminating the operation of a program
or the execution of a command" Commonl& this will involve two simultaneous -e&
presses, such as D3RE D, D3RE F or D3RE-< etc" 0n !NUEinux, D3RE-D is used"
.uestions
(" >hat is an operating s&stem forF
%" >hat is a pseudo=device nameF
G" 0f &ou had a C source program which &ou wanted to call Iaccounts: what
name would &ou save it underF
#" >hat would /e the name of the file produced /& the compiler of the program
in GF
H" 9ow would this program /e runF
'i)raries
lug!in C expansions. Header files.
The core of the C language is small and simple" 6pecial functionalit& is provided in
the form of li/raries of read&=made functions" This is what ma-es C so porta/le"
6ome li/raries are provided for &ou, giving &ou access to man& special a/ilities
without needing to reinvent the wheel" ?ou can also ma-e &our own, /ut to do so
&ou need to -now how &our operating s&stem /uilds li/raries" >e shall return to
this later"
i/raries are files of read&=compiled code which we can merge with a C program
at compilation time" Each li/rar& comes with a num/er of associated header files
which ma-e the functions easier to use" 4or example, there are li/raries of
mathematical functions, string handling functions and inputEoutput functions and
graphics li/raries" 0t is up to ever& programmer to ma-e sure that li/raries are
added at compilation time /& t&ping an optional string to the compiler" 4or
example, to merge with the math li/rar& li%m.a &ou would t&pe
cc -o program_name prog.c -lm
when &ou compile the program" The -lm means: add in li%m" 0f we wanted to add
in the soc-et li/rar& li%soc6et.a to do some networ- programming as well, we
would t&pe
cc -o program_name prog.c -lm -lsoc6et
and so on"
>h& are these li/raries not Aust included automaticall&F .ecause it would /e a
waste for the compiler to add on lots of code for maths functions, sa&, if the&
weren:t needed" >hen li/rar& functions are used in programs, the appropriate
li/rar& code is included /& the compiler, ma-ing the resulting o/Aect code often
much longer"
i/raries are supplemented /& header files which define macros, data types and
external data to /e used in conAunction with the li/raries" 3nce a header file has
/een included, it has effectivel& added to the list of reserved words and commands
in the language" ?ou cannot then use the names of functions or macros which have
alread& /een defined in li/raries or header files to mean an&thing other than what
the li/rar& specifies"
The most commonl& used header file is the standard inputEoutput li/rar& which is
called stdio.h" This /elongs to a su/set of the standard C li/rar& which deals with
file handling" The math.h header file /elongs to the mathematics li/rar& li%m.a"
9eader files for li/raries are included /& adding to the source code:
-include header.h
at the top of a program file" 4or instance:
-include &myheader.h&
includes a personal header file which is in the current director&" 3r
-include .stdio.h/
includes a file which lies in a standard director& li-e )usr)include"
The -include directive is actuall& a command to the C preprocessor, which is
dealt with more full& later, 6ee Preprocessor"
6ome functions can /e used without having to include li/rar& files or special
li/raries explicitl& since ever& program is alwa&s merged with the standard C
library, which is called li%c"
-include .stdio.h/
main ()
0
printf (&D standard )G file is included2n&);
printf (&Hello worldI&);
A
7 program wishing to use a mathematical function such as cos would need to
include a mathematics li/rar& header file"
-include .stdio.h/
-include .math.h/
main ()
0 dou%le x(y;
y = sin (x);
printf (&Jaths li%rary ready&);
A
7 particular operating s&stem might re<uire its own special li/rar& for certain
operations such as using a mouse or for opening windows in a !U0 environment,
for example" These details will /e found in the local manual for a particular C
compiler or operating s&stem"
7lthough there is no limit, in principle, to the num/er of li/raries which can /e
included in a program, there ma& /e a practical limit: namel& memor&, since ever&
li/rar& adds to the siCe of /oth source and o/Aect code" i/raries also add to the
time it ta-es to compile a program" 6ome operating s&stems are smarter than others
when running programs and can load in onl& what the& need of the large li/raries"
3thers have to load in ever&thing /efore the& can run a program at all, so man&
li/raries would slow them down"
To -now what names li/raries have in a particular operating s&stem &ou have to
search through its documentation" Unix users are luc-& in having an online manual
which is /etter than most written ones"
@uestions #:
Node:@uestions #, Previous:i/raries, Up:i/raries
.uestions
(" 9ow is a li/rar& file incorporated into a C programF
%" Name the most common li/rar& file in C"
G" 0s it possi/le to define new functions with the same names as standard
li/rar& functionsF
#" >hat is another name for a li/rar& fileF
Node:Programming st&le, Next:4orm of a C program, Previous:i/raries, Up:Top
Programming st1le
"he shape of programs to come.
C is actuall& a free format language" This means that there are no rules a/out how
it must /e t&ped, when to start new lines, where to place /rac-ets or whatever" This
has /oth advantages and dangers" The advantage is that the user is free to choose a
st&le which /est suits him or her and there is freedom in the wa& in which a
program can /e structured" The disadvantage is that, unless a strict st&le is adopted,
ver& slopp& programs can /e the result" The reasons for choosing a well structured
st&le are that:
ong programs are manageable onl& if programs are properl& organiCed"
Programs are onl& understandable if care is ta-en in choosing the names of
varia/les and functions"
0t is much easier to find parts of a program if a strict ordering convention is
maintained" 6uch a scheme /ecomes increasingl& difficult to achieve with
the siCe and complexit& of the pro/lem"
No simple set of rules can ever provide the ultimate solution to writing good
programs" 0n the end, experience and good Audgement are the factors which decide
whether a program is written well or poorl& written" The main goal of an& st&le is
to achieve clarity" Previousl& restrictions of memor& siCe, power and of particular
compilers often forced restrictions upon st&le, ma-ing programs clustered and
difficult" 7ll computers toda& are e<uipped with more than enough memor& for
their purposes, and have ver& good optimiCers which can produce faster code than
most programmers could write themselves without help, so there are few good
reasons not to ma-e programs as clear as possi/le"
Node:4orm of a C program, Next:Comments, Previous:Programming st&le,
Up:Top
T&e form of a C *rogram
What goes into a C program? What will it loo# li#e?
C is made up entirel& of /uilding /loc-s which have a particular Ishape: or form"
The form is the same ever&where in a program, whether it is the form of the main
program or of a su/routine" 7 program is made up of functions, functions are made
up of statements and declarations surrounded /& curl& /races 0 A"
The /asic /uilding /loc- in a C program is the function" Ever& C program is a
collection of one or more functions, written in some ar/itrar& order" 3ne and onl&
one of these functions in the program must have the name main()" This function is
alwa&s the starting point of a C program, so the simplest C program would /e Aust
a single function definition:
main ()
0
A
The parentheses () which follow the name of the function must /e included even
though the& apparentl& serve no purpose at this stage" This is how C distinguishes
functions from ordinar& varia/les"
The function main() does not have to /e at the top of a program so a C program
does not necessaril& start at line (" 0t alwa&s starts where main() is" 7lso, the
function main() cannot /e called from an& other function in the program" 3nl& the
operating s&stem can call the function main(): this is how a C program is started"
The next most simple C program is perhaps a program which calls a function
doKnothing and then ends"
)******************************************************)
)* *)
)* ,rogram : do nothing *)
)* *)
)******************************************************)
main() )* Jain program *)
0
doKnothing();
A
)******************************************************)
doKnothing() )* Lunction called *)
0
A
The program now consists of two functions, one of which is called /& the other"
There are several new things to notice a/out this program" 4irstl& the function
doKnothing() is called /& t&ping its name followed /& the characteristic ()
/rac-ets and a semi=colon" This is all that is re<uired to transfer control to the new
function" 0n some languages, words li-e C7 or P13C are used, or even a
s&m/ol li-e M" No such thing is needed in C" The semi=colon is vital however" 7ll
instructions in C must end with a semi=colon" This is a signal to inform the
compiler that the end of a statement has /een reached and that an&thing which
follows is meant to /e a part of another statement" This helps the compiler
diagnose errors"
The I/race: characters 0 and A mar- out a bloc# into which instructions are written"
>hen the program meets the closing /race A it then transfers /ac- to main()
where it meets another A /race and the program ends" This is the simplest wa& in
which control flows /etween functions in C" 7ll functions have the same status as
far as a program is concerned" The function main() is treated Aust as an& other
function" >hen a program is compiled, each function is compiled as a separate
entit& and then at the end the lin-er phase in the compiler attempts to sew them all
together"
The examples a/ove are o/viousl& ver& simple /ut the& illustrate how control
flows in a C program" 9ere are some more /asic elements which we shall cover"
comments
preprocessor commands
functions
declarations
varia/les
statements
The s-eleton plan of a program, shown /elow, helps to show how the elements of a
C program relate" The following chapters will then expand upon this as a -ind of
/asic plan"
)****************************************************)
)* *)
)* +6eleton program plan *)
)* *)
)****************************************************)
-include .stdio.h/ )* ,reprocessor defns *)
-include .myfile.c/
-define +DRB1J &arghhhhh&
-define NUJ9BRKGLK9GNB+ #$5
)****************************************************)
main () )* Jain program M start *)
0 int a(%; )* declaration *)
a=random();
%=function#();
function$(a(%);
A
)****************************************************)
function# () )* ,urpose *)
0
....
A
)****************************************************)
function$ (a(%) )* ,urpose *)
int a(%;
0
....
A
@uestion H:
Neither comments nor preprocessor commands have a special place in this list:
the& do not have to /e in an& one particular place within the program"
Node:@uestion H, Previous:4orm of a C program, Up:4orm of a C program
.uestions
(" >hat is a /loc-F
%" Name the six /asic things which ma-e up a C program"
G" 8oes a C program start at the /eginningF (>here is the /eginningF)
#" >hat happens when a program comes to a J characterF >hat does this
character signif&F
H" >hat vital piece of punctuation goes at the end of ever& simple C statementF
Node:Comments, Next:4unctions, Previous:4orm of a C program, Up:Top
Comments
$nnotating programs.
Comments are a wa& of inserting remar-s and reminders into a program without
affecting its content" Comments do not have a fixed place in a program: the
compiler treats them as though the& were white space or /lan- characters and the&
are conse<uentl& ignored" Programs can contain an& num/er of comments without
losing speed" This is /ecause comments are stripped out of a source program /& the
compiler when it converts the source program into machine code"
Comments are mar-ed out or delimited /& the following pairs of characters:
)* ...... comment ......*)
.ecause a comment is s-ipped over as though it were a single space, it can /e
placed an&where where spaces are valid characters, even in the middle of a
statement, though this is not to /e encouraged" ?ou should tr& to minimiCe the use
of comments in a program while tr&ing to maximiCe the reada/ilit& of the program"
0f there are too man& comments &ou o/scure &our code and it is the code which is
the main message in a program"
Example comment:
Example comment %:
@uestion +:
Node:Example comment, Next:Example comment %, Previous:Comments,
Up:Comments
+/am*le 1
main () )* 3he almost tri4ial program *)
0
)* 3his little line has no effect *)
)* 3his little line has none *)
)* 3his little line went all the way down
to the next line *)
)* 1nd so on ... *)
A
Node:Example comment %, Next:@uestion +, Previous:Example comment,
Up:Comments
+/am*le 3
-include .stdio.h/ )* header file *)
-define NG3LN+HB< @
)**********************************************)
)* 1 %ar li6e the one a%o4e can %e used to *)
)* separate functions 4isi%ly in a program *)
main ()
0 int i; )* declarations *)
do
0
)* Nothing III *)
A
while (NG3LN+HB<);
A
Node:@uestion +, Previous:Example comment %, Up:Comments
.uestion
(" >hat happens if a comment is not endedF That is if the programmer t&pes
)* "" to start /ut forgets the ""*) to closeF
2unctions
%a#ing blac# boxes. Solving problems. &etting results.
7 function is a module or /loc- of program code which deals with a particular
tas-" ,a-ing functions is a wa& of isolating one /loc- of code from other
independent /loc-s of code" 4unctions serve two purposes" The& allow a
programmer to sa&: Ithis piece of code does a specific Ao/ which stands /& itself
and should not /e mixed up with an&ting else:, and the& ma-e a /loc- of code
reusable since a function can /e reused in man& different contexts without
repeating parts of the program text"
4unctions help us to organiCe a program in a simple wa&B in Kernighan 2 1itchie
C the& are alwa&s written in the following form:
identifier (parameter1(parameter2(..)
types of parameters
0 variable declarations
statements..
......
....
A
4or example
,ythagoras(x(y(N)
dou%le x(y(N;
0 dou%le d;
d = sOrt(x*xPy*yPN*N);
printf(&3he distance to your point was 'f2n&(d);
A
0n the newer 7N60 standard, the same function is written slightl& differentl&:
,ythagoras(dou%le x( dou%le y( dou%le N)
0 dou%le d;
d = sOrt(x*xPy*yPN*N);
printf(&3he distance to your point was 'f2n&(d);
A
?ou will pro/a/l& see /oth st&les in C programs"
Each function has a name or identifier /& which is used to refer to it in a program"
7 function can accept a num/er of parameters or values which pass information
from outside, and consists of a num/er of statements and declarations, enclosed /&
curl& /races 0 A, which ma-e up the doing part of the o/Aect" The declarations and
It&pe of parameter: statements are formalities which will /e descri/ed in good time"
The name of a function in C can /e an&thing from a single letter to a long word"
The name of a function must /egin with an alpha/etic letter or the underscore K
character /ut the other characters in the name can /e chosen from the following
groups:
a .. N
(an& letter from a to C)
1 .. F
(an& letter from 7 to L)
@ .. >
(an& digit from $ to ))
K
(the underscore character)
This means that sensi/le names can easil& /e chosen for functions ma-ing a
program eas& to read" 9ere is a real example function which adds together two
integer num/ers a and % and prints the result c" 7ll the varia/les are chosen to /e
integers to -eep things simple and the result is printed out using the print=formatted
function printf, from the the standard li/rar&, with a &'d& to indicate that it is
printing a integer"
1ddK3woKNum%ers (a(%) )* 1dd a and % *)
int a(%;
0 int c;
c = a P %;
printf (&'d&(c);
A
Notice the position of the function name and where /races and semi=colons are
placed: the& are crucial" The details are <uic-l& learned with practice and
experience"
This function is not much use standing alone" 0t has to /e called from somewhere"
7 function is called (i"e" control is passed to the function) /& using its name with
the usual /rac-ets () to follow it, along with the values which are to /e passed to
the function:
main ()
0 int c(d;
c = #;
d = 85;
1ddK3woKNum%ers (c(d);
1ddK3woKNum%ers (#($);
A
The result of this program would /e to print out the num/er H# and then the
num/er G and then stop" 9ere is a simple program which ma-es use of some
functions in a pla&ful wa&" The structure diagram shows how this can /e visualiCed
and the significance of the program Ilevels:" The idea is to illustrate the wa& in
which the functions connect together:
6tructure diagram:
Program listing:
4unctions with values:
.rea-ing out earl&:
The exit function:
4unctions and t&pes:
@uestions M:
Node:6tructure diagram, Next:Program listing, Previous:4unctions, Up:4unctions
4tructure $iagram
Ee4el @: main ()
Q
Ee4el #: <ownGne ()
) 2
) 2
Ee4el $: <ownEeft() <ownRight()
Note: not all functions fit into a tid& hierarch& li-e these" 6ome functions call
themselves, while others can /e called from an&where in a program" >here would
&ou place the printf function in this hierarch&F
Node:Program listing, Next:4unctions with values, Previous:6tructure diagram,
Up:4unctions
Program 'isting
)***********************************************)
)* *)
)* Lunction +na6es M Eadders *)
)* *)
)***********************************************)
-include .stdio.h/
)***********************************************)
)* Ee4el @ *)
)***********************************************)
main ()
0
printf (&3his is le4el @: the main program2n&);
printf (&1%out to go down a le4el 2n&);
<ownGne ();
printf (&9ac6 at the end of the startII2n&);
A
)************************************************)
)* Ee4el # *)
)************************************************)
<ownGne () )* 9ranch outI *)
0
printf (&<own here at le4el #( all is well2n&);
<ownEeft ($);
printf (&3hrough le4el #....2n&);
<ownRight ($);
printf (&Roing %ac6 up a le4elI2n&);
A
)************************************************)
)* Ee4el $ *)
)************************************************)
<ownEeft (a) )* Eeft %ranch *)
int a;
0
printf (&3his is deepest le4el 'd2n&(a);
printf (&Gn the left %ranch of the picture2n&);
printf (&Roing upII&);
A
)************************************************)
<ownRight (a) )* Right %ranch *)
int a;
0
printf (&1nd le4el 'd againI2n&(a);
A
Node:4unctions with values, Next:.rea-ing out earl&, Previous:Program listing,
Up:4unctions
2unctions (it& values
0n other languages and in mathematics a function is understood to /e something
which produces a value or a num/er" That is, the whole function is thought of as
having a value" 0n C it is possi/le to choose whether or not a function will have a
value" 0t is possi/le to ma-e a function hand /ac- a value to the place at which it
was called" Ta-e the following example:
%ill = Dalculate9ill(data...);
The varia/le %ill is assigned to a function Dalculate9ill() and data are some
data which are passed to the function" This statement ma-es it loo- as though
Dalculate9ill() is a num/er" >hen this statement is executed in a program,
control will /e passed to the function Dalculate9ill() and, when it is done, this
function will then hand control /ac-" The value of the function is assigned to D/illD
and the program continues" 4unctions which wor- in this wa& are said to return a
value"
0n C, returning a value is a simple matter" Consider the function Calculate.ill()
from the statement a/ove:
Dalculate9ill(starter(main(dessert) )* 1dds up 4alues *)
int starter(main(dessert;
0 int total;
total = starter P main P dessert;
return (total);
A
7s soon as the return statement is met Dalculate9ill() stops executing and
assigns the value total to the function" 0f there were no return statement the
program could not -now which value it should associate with the name
Dalculate9ill and so it would not /e meaningful to spea- of the function as
having one value" 4orgetting a return statement can ruin a program" 4or instance
if Dalculate9ill had Aust /een:
Dalculate9ill (starter(main(dessert) )* ?RGNRI *)
int starter(main(dessert;
0 int total;
total = starter P main P dessert;
A
then the value %ill would Aust /e gar/age (no predicta/le value), presuming that
the compiler allowed this to /e written at all" 3n the other hand if the first version
were used (the one which did use the return(total) statement) and furthermore
no assignment were made:
main ()
0
Dalculate9ill (#($(5);
A
then the value of the function would Aust /e discarded, <uite legitimatel&" This is
usuall& what is done with the input output functions printf() and scanf() which
actuall& return values" 6o a function in C can return a value /ut it does not have to
/e usedB on the other hand, a value which has not /een returned cannot /e used
safel&"
'(") * +unctions do not have to return integers* you can decide whether they
should return a different data type, or even no value at all. -See next chapter.
Node:.rea-ing out earl&, Next:The exit function, Previous:4unctions with values,
Up:4unctions
Breaking out earl1
6uppose that a program is in the middle of some aw-ward process in a function
which is not main(), perhaps two or three loops wor-ing together, for example,
and suddenl& the function finds its answer" This is where the /eaut& of the return
statement /ecomes clear" The program can simpl& call return(4alue) an&where
in the function and control will Aump out of an& num/er of loops or whatever and
pass the value /ac- to the calling statement without having to finish the function
up to the closing /race A"
myfunction (a(%) )* %rea6ing out of functions early *)
int a(%;
0
while (a . %)
0
if (a / %)
0
return (%);
A
a = a P #;
A
A
The example shows this" The function is entered with some values for a and % and,
assuming that a is less than %, it starts to execute one of C:s loops called while" 0n
that loop, is a single if statement and a statement which increases a /& one on
each loop" 0f a /ecomes /igger than % at an& point the return(%) statement gets
executed and the function myfunction <uits, without having to arrive at the end
/race A, and passes the value of % /ac- to the place it was called"
Node:The exit function, Next:4unctions and t&pes, Previous:.rea-ing out earl&,
Up:4unctions
T&e exit() function
The function called exit() can /e used to terminate a program at an& point, no
matter how man& levels of function calls have /een made" This is called with a
return code, li-e this:
-define DG<B @
exit (DG<B);
This function also calls a num/er of other functions which perform tid&=up duties
such as closing open files etc"
Node:4unctions and t&pes, Next:@uestions M, Previous:The exit function,
Up:4unctions
2unctions an$ T1*es
7ll the varia/les and values used up to now have /een integers" .ut what happens
if a function is re<uired to return a different -ind of value such as a characterF 7
statement li-e:
%ill = Dalculate9ill (a(%(c);
can onl& ma-e sense if the varia/le %ill and the value of the function
Dalculate9ill() are the same -ind of o/Aect: in other words if Dalculat9ill()
returns a floating point num/er, then %ill cannot /e a character; .oth sides of an
assignment must match"
0n fact this is done /& declaring functions to return a particular t&pe of data" 6o far
no declarations have /een needed /ecause C assumes that all values are integers
unless &ou specificall& choose something different" 8eclarations are covered in the
next section"
Node:@uestions M, Previous:4unctions and t&pes, Up:4unctions
.uestions
(" >rite a function which ta-es two values a and b and returns the value of
(aNb)"
%" 0s there an&thing wrong with a function which returns no valueF
G" >hat happens if a function returns a value /ut it is not assigned to an&thingF
#" >hat happens if a function is assigned to an o/Aect /ut that function returns
no valueF
H" 9ow can a function /e made to <uit earl&F
5aria)les" T1*es an$ -eclarations
Storing data. /escriminating types. /eclaring data.
7 varia/le is a se<euence of program code with a name (also called its identifier)"
7 name or identifier in C can /e an&thing from a single letter to a word" The name
of a varia/le must /egin with an alpha/etic letter or the underscore K character /ut
the other characters in the name can /e chosen from the following groups:
a .. N
(an& letter from a to C)
1 .. F
(an& letter from 7 to L)
@ .. >
(an& digit from $ to ))
K
(the underscore character)
6ome examples of valid varia/le names are:
a total GutKofKJemory S1R integer etc...
0n C varia/les do not onl& have names: the& also have t&pes" The type of a varia/le
conve&s to the the compiler what sort of data will /e stored in it" 0n .760C and in
some older, largel& o/solete languages, li-e PE(, a special naming convention is
used to determine the sort of data which can /e held in particular varia/les" e"g" the
dollar s&m/ol T is commonl& used in .760C to mean that a varia/le is a string and
the percentage ' s&m/ol is used to indicate an integer" No such convention exists
in C" 0nstead we specif& the t&pes of varia/les in their declarations" This serves two
purposes:
0t gives a compiler precise information a/out the amount of memor& that
will have to /e given over to a varia/le when a program is finall& run and
what sort of arithmetic will have to /e used on it (e"g" integer onl& or
floating point or none)"
0t provides the compiler with a list of the varia/les in a convenient place so
that it can cross chec- names and t&pes for an& errors"
There is a lot of different possi/le t&pes in C" 0n fact it is possi/le for us to define
our own, /ut there is no need to do this right awa&: there are some /asic t&pes
which are provided /& C read& for use" The names of these t&pes are all reserved
words in C and the& are summariCed as follows:
char
7 single 76C00 character
short
7 short integer (usuall& (M=/its)
short int
7 short integer
int
7 standard integer (usuall& G%=/its)
long
7 long integer
long int
7 long integer (usuall& G%=/its, /ut increasingl& M# /its)
float
7 floating point or real num/er (short)
long float
a long floating point num/er
dou%le
7 long floating point num/er
4oid
8iscussed in a later chapter"
enum
8iscussed in a later chapter"
4olatile
8iscussed in a later chapter"
There is some repetition in these words" 0n addition to the a/ove, the word
unsigned can also /e placed in front of an& of these t&pes" Unsigned means that
onl& positive or Cero values can /e used" (i"e" there is no minus sign)" The
advantage of using this -ind of varia/le is that storing a minus sign ta-es up some
memor&, so that if no minus sign is present, larger num/ers can /e stored in the
same -ind of varia/le" The 7N60 standard also allows the word signed to /e
placed in front of an& of these t&pes, so indicate the opposite of unsigned" 3n some
s&stems varia/les are signed /& default, whereas on others the& are not"
8eclarations:
>here to declare things:
8eclarations and 0nitialiCation:
T&pes:
Choosing 5aria/les:
7ssigning varia/les to one another:
T&pes and The Cast 3perator:
6torage class register static and extern:
4unctions t&pes:
@uestionsdeclare:
Node:8eclarations, Next:>here to declare things, Previous:5aria/les,
Up:5aria/les
-eclarations
To declare a varia/le in a C program one writes the type followed /& a list of
varia/le names which are to /e treated as /eing that t&pe:
typename variablename1(..(..(variablenameN;
4or example:
int i(U;
char ch;
dou%le x(y(N(fred;
unsigned long int NameKofKSaria%le;
4ailing to declare a varia/le is more ris-& than passing through customs and failing
to declare &our six tonnes of 6wiss chocolate" 7 compiler is mar-edl& more
efficient than a customs officer: it will catch a missing declaration ever& time and
will terminate a compiling session whilst complaining /itterl&, often with a host of
messages, one for each use of the undeclared varia/le"
Node:>here to declare things, Next:8eclarations and 0nitialiCation,
Previous:8eclarations, Up:5aria/les
6&ere to $eclare t&ings
There are two -inds of place in which declarations can /e made, 6ee 6cope" 4or
now it will do to simpl& state what these places are"
(" 3ne place is outside all of the functions" That is, in the space /etween
function definitions" (7fter the -include lines, for example") 5aria/les
declared here are called glo/al varia/les" There are also called static and
external varia/les in special cases")
%" -include .stdio.h/
G"
#" int glo%alinteger; )* HereI outside 0A *)
H"
M" float glo%alKfloatingKpoint;
+"
*" main ()
)"
($"0
((" A
(%"
(G"The other place where declarations can /e made is following the opening
/race, OJ, of a /loc-" 7n& /loc- will do, as long as the declaration follows
immediatel& after the opening /race" 5aria/les of this -ind onl& wor- inside
their /races OJ and are often called local varia/les" 7nother name for them is
automatic varia/les"
(#" main ()
(H"
(M" 0 int a;
(+" float x(y(N;
(*"
()" )* statements *)
%$"
%(" A
%%"
or
function ()
0 int i;
)* .... *)
while (i . #@)
0 char ch;
int g;
)* ... *)
A
A
Node:8eclarations and 0nitialiCation, Next:T&pes, Previous:>here to declare
things, Up:5aria/les
-eclarations an$ #nitiali7ation
>hen a varia/le is declared in C, the language allows a neat piece of s&ntax which
means that varia/les can /e declared and assigned a value in one go" This is no
more efficient than doing it in two stages, /ut it is sometimes tidier" The following:
int i = @;
char ch = "a";
are e<uivalent to the more longwinded
int i;
char ch;
i = @;
ch = "a";
This is called initiali0ation of the varia/les" C alwa&s allows the programmer to
write declarationsEinitialiCers in this wa&, /ut it is not alwa&s desira/le to do so" 0f
there are Aust one or two declarations then this initialiCation method can ma-e a
program neat and tid&" 0f there are man&, then it is /etter to initialiCe separatel&, as
in the second case" 7 lot means when it starts to loo- as though there are too man&"
0t ma-es no odds to the compiler, nor (ideall&) to the final code whether the first or
second method is used" 0t is onl& for tidiness that this is allowed"
#n$ivi$ual T1*es
char:
Example special chars:
integers:
4loat:
char
7 character t&pe is a varia/le which can store a single 76C00 character" !roups of
char form strings" 0n C single characters are written enclosed /& single <uotes, e"g"
"c"; (This is in contrast to strings of man& characters which use dou/le <uotes,
e"g" &string&) 4or instance, if ch is the name of a character:
char ch;
ch = "a";
would give ch the value of the character a" The same effect can also /e achieved
/& writing:
char ch = "a";
7 character can /e an& 76C00 character, printa/le or not printa/le from values =(%*
to (%+" (.ut onl& $ to (%+ are used") Control characters i"e" non printa/le
characters are put into programs /& using a /ac-slash 2 and a special character or
num/er" The characters and their meanings are:
2%
/ac-space .6
2f
form feed 44 (also clear screen)
2n
new line N (li-e pressing return)
2r
carriage return C1 (cursor to start of line)
2t
horiContal ta/ 9T
24
vertical ta/ (not all versions)
2&
dou/le <uotes (not all versions)
2"
single <uote character :
22
/ac-slash character P
2ddd
character ddd where ddd is an 76C00 code given in octal or /ase *, 6ee
Character Conversion Ta/le"
2xddd
character ddd where ddd is an 76C00 code given in hexadecimal or /ase (M,
6ee Character Conversion Ta/le"
Node:Example special chars, Next:integers, Previous:char, Up:T&pes
'isting
)***************************************************)
)* *)
)* +pecial Dharacters *)
)* *)
)***************************************************)
-include .stdio.h/
main ()
0
printf (&9eepI 2; 2n&);
printf (&ch = 2"a2" 2n&);
printf (& .- +tart of this lineII 2r&);
A
The output of this program is:
9eepI (and the BELL sound )
ch = "a"
.- +tart of this lineII
and the text cursor is left where the arrow points" 0t is also possi/le to have the
t&pe:
unsigned char
This admits 76C00 values from $ to %HH, rather than =(%* to (%+"
Node:integers, Next:4loat, Previous:Example special chars, Up:T&pes
#ntegers
6&ole num)ers
There are five integer t&pes in C and the& are called char, int, long, long long
and short" The difference /etween these is the siCe of the integer which either can
hold and the amount of storage re<uired for them" The siCes of these o/Aects
depend on the operating s&stem of the computer" Even different flavours of Unix
can have var&ing siCes for these o/Aects" Usuall&, the two to remem/er are int and
short" int means a Inormal: integer and short means a Ishort: one, not that that
tells us much" 3n a t&pical G% /it microcomputer the siCe of these integers is the
following:
3ype 9its ,ossi%le Salues
short #: -5$;:= to 5$;:;
unsigned short #: @ to :8858
int 5$ -$#7;7=5:7= to $#7;7=5:7;
long 5$ (ditto)
unsigned int 5$ @ to 7$>7>:;$>8
long long :7 ->e#= to P =e#=
0ncreasingl& though, M# /it operating s&stems are appearing and long integers are
M# /its long" ?ou should alwa&s chec- these values" 6ome mainframe operating
s&stems are completel& M# /it, e"g" Unicos has no G% /it values" 5aria/les are
declared in the usual wa&:
int i(U;
i = U = @;
or
short i=@(U=@;
Node:4loat, Previous:integers, Up:T&pes
2loating Point
There are also long and short floating point num/ers in C" 7ll the mathematical
functions which C can use re<uire dou%le or long float arguments so it is
common to use the t&pe float for storage onl& of small floating point num/ers and
to use dou/le elsewhere" (This not alwa&s true since the C Icast: operator allows
temporar& conversions to /e made") 3n a t&pical G% /it implementation the
different t&pes would /e organiCed as follows:
3ype 9its ,ossi%le Salues
float 5$ P)- #@B-5; to P)- #@B5=
dou%le :7 P)- #@B-5@; to P)- #@B5@=
long float 5$ (ditto)
long dou%le VVV
T&pical declarations:
float x(y(N;
x = @.#;
y = $.78:B8
N = @;
dou%le %ignum(smallnum;
%ignum = $.5:B$@=;
smallnum = 5.$B-5@@;
Node:Choosing 5aria/les, Next:7ssigning varia/les to one another,
Previous:T&pes, Up:5aria/les
C&oosing 5aria)les
The sort of procedure that &ou would adopt when choosing varia/le names is
something li-e the following:
8ecide what a varia/le is for and what t&pe it needs to /e"
Choose a sensi/le name for the varia/le"
8ecide where the varia/le is allowed to exist"
8eclare that name to /e a varia/le of the chosen t&pe"
6ome local varia/les are onl& used temporaril&, for controlling loops for instance"
0t is common to give these short names (single characters)" 7 good ha/it to adopt is
to -eep to a consistent practice when using these varia/les" 7 common one, for
instance is to use the letters:
int i(U(6;
to /e integer t&pe varia/les used for counting" (There is not particular reason wh&
this should /eB it is Aust common practice") 3ther integer values should have more
meaningful names" 6imilarl& names li-e:
dou%le x(y(N;
tend to ma-e one thin- of floating point num/ers"
Node:7ssigning varia/les to one another, Next:T&pes and The Cast 3perator,
Previous:Choosing 5aria/les, Up:5aria/les
8ssigning varia)les to one anot&er
5aria/les can /e assigned to num/ers:
4ar = #@;
and assigned to each other:
4ar# = 4ar$;
0n either case the o/Aects on either side of the = s&m/ol must /e of the same t&pe" 0t
is possi/le (though not usuall& sensi/le) to assign a floating point num/er to a
character for instance" 6o
int a( % = #;
a = %;
is a valid statement, and:
float x = #.7;
char ch;
ch = x;
is a valid statement, since the truncated value ( can /e assigned to ch" This is a
<uestiona/le practice though" 0t is unclear wh& an&one would choose to do this"
Numerical values and characters will interconvert /ecause characters are stored /&
their 76C00 codes (which are integers;) Thus the following will wor-:
int i;
char ch = "1";
i = ch;
printf (&3he 1+D code of 'c is 'd&(ch(i);
The result of this would /e:
3he 1+D code of 1 is :8
Node:T&pes and The Cast 3perator, Next:6torage class register static and extern,
Previous:7ssigning varia/les to one another, Up:5aria/les
T1*es an$ T&e Cast 0*erator
0t is worth mentioning /riefl& a ver& valua/le operator in C: it is called the cast
operator and its function is to convert one t&pe of value into another" 4or instance it
would convert a character into an integer:
int i;
char ch = "2n";
i = (int) ch;
The value of the integer would /e the 76C00 code of the character" This is the onl&
integer which it would ma-e an& sense to tal- a/out in connection with the
character" 6imilarl& floating point and integer t&pes can /e interconverted:
float x = 5.5;
int i;
i = (int) x;
The value of i would /e G /ecause an integer cannot represent decimal points, so
the cast operator rounds the num/er" There is no such pro/lem the other wa&
around"
float x;
int i = #$;
x = (float) i;
The general form of the cast operator is therefore:
(type) variable
0t does not alwa&s ma-e sense to convert t&pes" This will /e seen particularl& with
regard to structures and unions" Cast operators crop up in man& areas of C" This is
not the last time the& will have to /e explained"
)***************************************************)
)* *)
)* <emo of Dast operator *)
)* *)
)***************************************************)
-include .stdio.h/
main () )* Use int float and char *)
0 float x;
int i;
char ch;
x = $.578;
i = (int) x;
ch = (char) x;
printf (&Lrom float x ='f i ='d ch ='c2n&(x(i(ch);
i = 78;
x = (float) i;
ch = (char) i;
printf (&Lrom int i='d x='f ch='c2n&(i(x(ch);
ch = "*";
i = (int) ch;
x = (float) ch;
printf (&Lrom char ch='c i='d x='f2n&(ch(i(x);
A
Node:6torage class register static and extern, Next:4unctions t&pes, Previous:T&pes
and The Cast 3perator, Up:5aria/les
4torage class static an$ extern
6ometimes C programs are written in more than one text file" 0f this is the case
then, on occasion, it will /e necessar& to get at varia/les which were defined in
another file" 0f the word extern is placed in front of a varia/le then it can /e
referenced across files:
ile 1 ile 2
int i;
main () function ()
0 0
extern int i;
A A
0n this example, the function main() in file ( can use the varia/le i from the
function main in file %"
7nother class is called static" The name static is given to varia/les which can
hold their values /etween calls of a function: the& are allocated once and once onl&
and their values are preserved /etween an& num/er of function calls" 6pace is
allocated for static varia/les in the program code itself and it is never disposed of
unless the whole program is" N3TE: Ever& glo/al varia/le, defined outside
functions has the t&pe static automaticall&" The opposite of static is auto"
Node:4unctions t&pes, Next:@uestionsdeclare, Previous:6torage class register
static and extern, Up:5aria/les
2unctions" T1*es an$ -eclarations
4unctions do not alwa&s have to return values which are integers despite the fact
that this has /een exclusivel& the case up to now" Unless something special is done
to force a function to return a different -ind of value C will alwa&s assume that the
t&pe of a function is int"
0f &ou want this to /e different, then a function has to /e declared to /e a certain
t&pe, Aust as varia/les have to /e" There are two places where this must /e done:
The name of the function must /e declared a certain t&pe where the function
is declared" e"g" a function which returns a float value must /e declared as:
float function# ()

0
return (#.$$>);
A

7 function which returns a character:


char function$ ()
0
return ("*");
A
7s well as declaring a function:s identifier to /e a certain t&pe in the function
definition, it must (irritatingl&) /e declared in the function in which it is
called too; The reasons for this are related to the wa& in which C is
compiled" 6o, if the two functions a/ove were called from main(), the&
would have to declared in the varia/les section as:
main ()

0 char ch( function$ ();


float x( function# ();

x = function# ();
ch = function$ ();
A

0f a function whose t&pe is not integer is not declared li-e this, then
compilation errors will result; Notice also that the function must /e declared
inside ever& function which calls it, not Aust main()"
Node:@uestionsdeclare, Previous:4unctions t&pes, Up:5aria/les
.uestions
(" >hat is an identifierF
%" 6a& which of the following are valid C identifiers:
(" Ralph$5
%" =@shillings
G" missionKcontrol
#" 1'
H" 1T
M" Koff
G" >rite a statement to declare two integers called i and U"
#" >hat is the difference /etween the t&pes floa and dou%le"
H" >hat is the difference /etween the t&pes int and unsigned intF
M" >rite a statement which assigns the value M+ to the integer varia/le D0D"
+" >hat t&pe does a C function return /& defaultF
*" 0f we want to declare a function to return long float, it must /e done in, at
least, two places" >here are theseF
)" >rite a statement, using the cast operator, to print out the integer part of the
num/er %G"(%HM"
($"0s it possi/le to have an automatic glo/al varia/leF
Parameters an$ 2unctions
Ways in and out of functions.
Not all functions will /e as simple as the ones which have /een given so far"
4unctions are most useful if the& can /e given information to wor- with and if the&
can reach varia/les and data which are defined outside of them" Examples of this
have alread& /een seen in a limited wa&" 4or instance the function Dalculate9ill
accepted three values a,% and c"
Dalculate9ill (a(%(c)
int a(%(c;
0 int total;
total = a P % P c;
return total;
A
>hen varia/le values are handed to a function, /& writing them inside a functions
/rac-ets li-e this, the function is said to accept parameters" 0n mathematics a
parameter is a varia/le which controls the /ehaviour of something" 0n C it is a
varia/le which carries some special information" 0n Dalculate9ill the
D/ehaviourD is the addition process" 0n other words, the value of total depends
upon the starting values of a,% and c"
Parameters are a/out communication /etween different functions in a program"
The& are li-e messengers which pass information to and from different places"
The& provide a wa& of getting information into a function, /ut the& can also /e
used to hand information /ac-" Parameters are usuall& split into two categories:
value parameters and variable parameters" 5alue parameters are one=wa&
communication carr&ing information into a function from somewhere outside"
5aria/le parameters are two=wa&"
8eclaring parameters:
5alue parameters:
4unctions as actual parameters:
Example %:
Example G:
5aria/le parameters:
Example #:
@ula-fA:
Node:8eclaring parameters, Next:5alue parameters, Previous:Parameters,
Up:Parameters
-eclaring Parameters
7 function was defined /& code which loo-s li-e this:
identifier (parameters...)
types of parameters
0
A
Parameters, li-e varia/les and functions, also have t&pes which must /e declared"
4or instance:
function# (i(U(x(y)
int i(U;
float x(y;
0
A
or
char function$ (x(ch)
dou%le x;
char ch;
0 char ch$ = "*";
return (ch$);
A
Notice that the& are declared outside the /loc- /races"
Node:5alue parameters, Next:4unctions as actual parameters, Previous:8eclaring
parameters, Up:Parameters
5alue Parameters
7 value parameter is the most common -ind of parameter" 7ll of the examples up
to -now have /een examples of value parameters" >hen a value parameter is
passes information to a function its value is copied to a new place which is
completel& isolated from the place that the information came from" 7n example
helps to show this" Consider a function which is called from main() whose
purpose is to add together two num/ers and to print out the result"
-include .stdio.h/
main ()
0
add (#(7);
A
)*******************************************)
add (a(%)
int a(%;
0
printf (&'d&( aP%);
A
>hen this program is run, two new varia/les are automaticall& created /& the
language, called a and %" The value ( is copied into a and the value # is copied into
%" 3/viousl& if a and / were given new values in the function add() then this
could not change the values ( and # in main(), /ecause ( is alwa&s ( and # is
alwa&s #" The& are constants" 9owever if instead the program had /een:
main ()
0 int a = #( % = 7;
add (a(%);
A
)**************************************)
add (a(%)
int a(%;
0
printf (&'d&( aP%);
A
then it is less clear what will happen" 0n fact exactl& the same thing happens:
>hen add() is called from main() two new varia/les a and % are created
/& the language (which have nothing to do with the varia/les a and % in
main() and are completel& isolated from them)"
The value of a in main() is copied into the value of a in add()"
The value of % in main() is copied into the value of % in add()"
Now, an& reference to a and % within the function add() refers onl& to the two
parameters of add and not to the varia/les with the same names which appeared in
main()" This means that if a and % are altered in add() the& will not affect a and %
in main()" ,ore advanced computing texts have names for the old and the& new a
and %:
$ctual arameters
These are the original values which were handed over to a function" 7nother
name for this is an argument"
+ormal arameters
These are the copies which wor- inside the function which was called"
9ere are some points a/out value parameters"
The names of formal parameters can /e an&thing at all" The& do not have to
/e the same as the actual parameters" 6o in the example a/ove it would /e
e<uall& valid to write:
-include .stdio.h/

main ()

0 int a = #( % = 7;

add (a(%);
A

)*******************************************)

add (i(U)

int i(U;

0
printf (&'d&( iPU);
A

0n this case the value of a in main() would /e copied to the value of i in


add() and the value of % in main() would /e copied to the value of U in
add()"
The parameters ought to match /& datat&pe when ta-en in an ordered
se<uence" 0t is possi/le to cop& a floating point num/er into a character
formal parameter, causing &ourself pro/lems which are hard to diagnose"
6ome compilers will spot this if it is done accidentall& and will flag it as an
error" e"g"
main ()

0
function ("*"(#.@);
A

)********************************)

function (ch(i)

char ch;
int i;

0
A

is pro/a/l& wrong /ecause ("$ is a floating point value, not an integer"


The parameters ought to, /ut need not match in num/er; This surprising fact
is important /ecause programs can go wrong if a formal parameter was
missed out" 7N60 C has a wa& of chec-ing this /& function Iprotot&ping:,
/ut in Kernighan 2 1itchie C there is no wa& to chec- this" 0f the num/er of
actual parameters is more than the num/er of formal parameters and all of
the parameters match in t&pe then the extra values are Aust discarded" 0f the
num/er of actual parameters is less than the num/er of formal parameters,
then the compiler will assign some un-nown value to the formal parameters"
This will pro/a/l& /e gar/age"
3ur use of varia/les as parameters should not leave &ou with the impression
that we can onl& use varia/les as parameters" 0n fact, we can send an& literal
value, or expression with an appropriate t&pe to a function" 4or example,
sin(5.7#7#8);
cos(aP%*$.@);
strlen(&3he length of this string&);
Node:4unctions as actual parameters, Next:Example %, Previous:5alue parameters,
Up:Parameters
2unctions as actual *arameters
The value returned /& a function can /e used directl& as a value parameter" 0t does
not have to /e assigned to a varia/le first" 4or instance:
main ()
0
,rintGut (+omeSalue());
A
)*********************************************)
,rintGut (a) )* ,rint the 4alue *)
int a;
0
printf (&'d&(a);
A
)**********************************************)
+omeSalue () )* Return an ar%itrary no *)
0
return (7$);
A
This often gives a concise wa& of passing a value to a function"
Node:Example %, Next:Example G, Previous:4unctions as actual parameters,
Up:Parameters
+/am*le 'isting
)**************************************************)
)* *)
)* Salue ,arameters *)
)* *)
)**************************************************)
)* 3oying with 4alue parameters *)
-include .stdio.h/
)**************************************************)
)* Ee4el @ *)
)**************************************************)
main () )* Bxample of 4alue parameters *)
0 int i(U;
dou%le x(xKplusKone();
char ch;
i = @;
x = @;
printf (& 'f&( xKplusKone(x));
printf (& 'f&( x);
U = resultof (i);
printf (& 'd&(U);
A
)***************************************************)
)* le4el # *)
)***************************************************)
dou%le xKplusKone(x) )* 1dd one to x I *)
dou%le x;
0
x = x P #;
return (x);
A
)****************************************************)
resultof (U) )* ?or6 out some result *)
int U;
0
return ($*U P 5); )* why not... *)
A
Node:Example G, Next:5aria/le parameters, Previous:Example %, Up:Parameters
+/am*le 'isting
)******************************************************)
)* *)
)* ,rogram : Jore Salue ,arameters *)
)* *)
)******************************************************)
)* ,rint out moc6 exam results etc *)
-include .stdio.h/
)******************************************************)
main () )* ,rint out exam results *)
0 int pupil#(pupil$(pupil5;
int ppr#(ppr$(ppr5;
float pen#(pen$(pen5;
pupil# = =;;
pupil$ = 78;
pupil5 = #$;
ppr# = $@@;
ppr$ = $5@;
ppr5 = #@;
pen# = #;
pen$ = $;
pen5 = $@;
analyse (pupil#(pupil$(pupil5(ppr#(ppr$(
ppr5(pen#(pen$(pen5);
A
)*******************************************************)
analyse (p#(p$(p5(w#(w$(w5(%#(%$(%5)
int p#(p$(p5(w#(w$(w5;
float %#(%$(%5;
0
printf (&,upil # scored 'd percent2n&(p#);
printf (&,upil $ scored 'd percent2n&(p$);
printf (&,upil 5 scored 'd percent2n&(p5);
printf (&Howe4er: 2n&);
printf (&,upil# wrote 'd sides of paper2n&(w#);
printf (&,upil$ wrote 'd sides2n&(w$);
printf (&,upil5 wrote 'd sides2n&(w5);
if (w$ / w#)
0
printf (&?hich Uust shows that Ouantity&);
printf (& does not imply Ouality2n&);
A
printf (&,upil# used 'f %iros2n&(%#);
printf (&,upil$ used 'f 2n&(%$);
printf (&,upil5 used 'f 2n&(%5);
printf (&3otal paper used = 'd&( total(w#(w$(w5));
A
)*****************************************************)
total (a(%(c) )* add up total *)
int a(%(c;
0
return (a P % P c);
A
Node:5aria/le parameters, Next:Example #, Previous:Example G, Up:Parameters
5aria)le Parameters
-$s a first time reader you may wish to omit this section until you have read about
ointers and (perators..
3ne wa& to hand information /ac- is to use the return statement" This function is
slightl& limited however in that it can onl& hand the value of one varia/le /ac- at a
time" There is another wa& of handing /ac- values which is less restrictive, /ut
more aw-ward than this" This is /& using a special -ind of parameter, often called a
varia/le parameter" 0t is most easil& explained with the aid of an example:
-include .stdio.h/
main ()
0 int i(U;
RetSalues (Mi(MU);
printf (&i = 'd and U = 'd&(i(U)
A
)************************************)
RetSalues (p(O)
int *p(*O;
0
*p = #@;
*O = $@;
A
To understand full& what is going on in this program re<uires a -nowledge of
pointers and operators, which are covered in later sections, /ut a /rief explanation
can /e given here, so that the method can /e used"
There are two new things to notice a/out this program: the s&m/ols M and *" The
ampersand M s&m/ol should /e read as Dthe address of""D" The star * s&m/ol should
/e read as Dthe contents of the address"""D" This is easil& confused with the
multiplication s&m/ol (which is identical)" The difference is onl& in the context in
which the s&m/ol is used" 4ortunatel& this is not am/iguous since multiplication
alwa&s ta-es place /etween two num/ers or varia/les, whereas the Dcontents of a
pointerD applies onl& to a single varia/le and the star precedes the varia/le name"
6o, in the program a/ove, it is not the varia/les themselves which are /eing passed
to the procedure /ut the addresses of the the varia/les" 0n other words, information
a/out where the varia/les are stored in the memor& is passed to the function
RetSalues()" These addresses are copied into two new varia/les p and O, which
are said to /e pointers to i and U" 6o, with varia/le parameters, the function does
not receive a cop& of the varia/les themselves, /ut information a/out how to get at
the original varia/le which was passed" This information can /e used to alter the
Dactual parametersD directl& and this is done with the * operator"
*p = #@;
means: ,a-e the contents of the address held in p e<ual to ($" 1ecall that the
address held in p is the address of the varia/le i, so this actuall& reads: ma-e i
e<ual to ($" 6imilarl&:
*O = $@;
means ma-e the contents of the address held in O e<ual to %$" 3ther operations are
also possi/le (and these are detailed in the section on pointers) such as finding out
the value of i and putting it into a new varia/le, sa&, a:
int a;
a = *p; )* is eOui4alent to a = i *)
Notice that the N s&m/ol is re<uired in the declaration of these parameters"
Node:Example #, Next:@ula-fA, Previous:5aria/le parameters, Up:Parameters
+/am*le 'isting
)**************************************************)
)* *)
)* ,rogram : Saria%le ,arameters *)
)* *)
)**************************************************)
)* +cale some measurements on a drawing( say *)
-include .stdio.h/
)**************************************************)
main () )* +cale measurements*)
0 int height(width;
height = 7;
width = 8;
+cale<imensions (Mheight(Mwidth);
printf (&+caled height = 'd2n&(height);
printf (&+caled width = 'd2n&(width);
A
)****************************************************)
+cale<imensions (h(w) )* return scaled 4alues *)
int *h( *w;
0 int hscale = 5; )* scale factors *)
int wscale = #;
*h = *h * hscale;
*w = *w * wscale;
A
Node:@ula-fA, Previous:Example #, Up:Parameters
.uestions
(" Name two wa&s that values and results can /e handed /ac- from a function"
%" >here are parameters declaredF
G" Can a function /e used directl& as a value parameterF
#" 8oes it mean an&thing to use a function directl& as a varia/le parameterF
H" >hat do the s&m/ols N and 2 mean, when the& are placed in front of an
identifierF
M" 8o actual and formal parameters need to have the same namesF
Node:6cope, Next:Preprocessor, Previous:Parameters, Up:Top
4co*e 9 'ocal 8n$ :lo)al
Where a program1s fingers can1t reach.
4rom the computer:s point of view, a C program is nothing more than a collection
of functions and declarations" 4unctions can /e thought of as sealed capsules of
program code which float on a /ac-ground of white space, and are connected
together /& means of function calls" >hite space is the name given to the white of
an imaginar& piece of paper upon which a program is written, in other words the
spaces and new line characters which are invisi/le to the e&e" The glo/al white
space is onl& the gaps /etween functions, not the gaps inside functions" Thin-ing
of functions as sealed capsules is a useful wa& of understanding the difference
/etween local and glo/al o/Aects and the whole idea of scope in a program"
7nother analog& is to thin- of what goes on in a function as /eing li-e watching a
realit& on television" ?ou cannot go in and change the T5 realit&, onl& o/serve the
output, /ut the television show draws its information from the world around it" ?ou
can send a parameter (e"g" switch channels) to ma-e some choices" 7 function
called /& a function, is li-e seeing someone watching a televsion, in a television
show"
!lo/al varia/les:
ocal varia/les:
Parameters again:
Example H:
6t&le note:
6cope and st&le:
@uestions ((:
Node:!lo/al varia/les, Next:ocal varia/les, Previous:6cope, Up:6cope
:lo)al 5aria)les
!lo/al varia/les are declared in the white space /etween functions" 0f ever&
function is a ship floating in this sea of white space, then glo/al varia/les (data
storage areas which also float in this sea) can enter an& ship and also enter
an&thing inside an& ship (6ee the diagram)" !lo/al varia/les are availa/le
ever&whereB" the& are created when a program is started and are not destro&ed until
a program is stopped" The& can /e used an&where in a program: there is no
restriction a/out where the& can /e used, in principle"
Node:ocal varia/les, Next:Parameters again, Previous:!lo/al varia/les,
Up:6cope
'ocal 5aria)les
ocal varia/les are more interesting" The& can not enter Aust an& region of the
program /ecause the& are trapped inside /loc-s" To use the ship analog&: if it is
imagined that on /oard ever& ship (which means inside ever& function) there is a
large swimming pool with man& to& ships floating inside, then local varia/les will
wor- an&where in the swimming pool (inside an& of the to&s ships, /ut can not get
out of the large ship into the wide /e&ond" The swimming pool is Aust li-e a
smaller sea, /ut one which is restricted to /eing inside a particular function" Ever&
function has its own swimming pool; The idea can /e ta-en further too" >hat
a/out swimming pools on/oard the to& shipsF (,eaning functions or /loc-s inside
the functions;
)* Rlo%al white space &sea& *)
function ()
0
)* Gn %oard ship *)
0
)* Gn %oard a toy ship *)
A
A
The same rules appl& for the to& ships" 5aria/les can reach an&where inside them
/ut the& cannot get out" The& cannot escape their /loc- /races OJ" >henever a pair
of /loc- /races is written into a program it is possi/le to ma-e varia/le
declarations inside the opening /race" i-e this:
0 int locali;
char localch;
)* statements *)
A
These varia/les do not exist outside the /races" The& are onl& created when the
opening /race is encountered and the& are destro&ed when the closing /race is
executed, or when control Aumps out of the /loc-" .ecause the& onl& wor- in this
local area of a program, the& are called local varia/les" 0t is a matter of st&le and
efficienc& to use local varia/les when it does not matter whether varia/les are
preserved outside of a particular /loc-, /ecause the s&stem automaticall& allocates
and disposes of them" The programmer does not have to thin- a/out this"
>here a varia/le is and is not defined is called the scope of that varia/le" 0t tells a
programmer what a varia/les horiCons are;
Node:Parameters again, Next:Example H, Previous:ocal varia/les, Up:6cope
Communication 9 *arameters
0f functions were sealed capsules and no local varia/les could ever communicate
with other parts of the program, then functions would not /e ver& useful" This is
wh& parameters are allowed" Parameters are a wa& of handing local varia/les to
other functions without letting them out; 5alue parameters (see last section) ma-e
copies of local varia/les without actuall& using them" The copied parameter is then
a local varia/le in another function" 0n other words, it can:t get out of the function
to which is it passed """ unless it is passed on as another parameter"
Node:Example H, Next:6t&le note, Previous:Parameters again, Up:6cope
+/am*le 'isting
Notice a/out the example that if there are two varia/les of the same name, which
are /oth allowed to /e in the same place (c in the example /elow) then the more
local one wins" That is, the last varia/le to /e defined ta-es priorit&" (Technicall&
adept readers will realiCe that this is /ecause it was the last one onto the varia/le
stac-")
)***************************************************************)
)* *)
)* +DG,B : 3HB DEEEB< D1,+UEB+ *)
)* *)
)***************************************************************)
-include .stdio.h/
)***************************************************************)
main ()
0 int a = #( % = $( c = 5;
if (a == #)
0 int c;
c = a P %;
printf (&'d&(c);
A
handdown (a(%);
printf (&'d&(c);
A
)**************************************************************)
handdown (a(%) )* +ome function *)
int a(%;
0
...
A
Node:6t&le note, Next:6cope and st&le, Previous:Example H, Up:6cope
4t1le ;ote
6ome programmers complain a/out the use of glo/al varia/les in a program" 3ne
complaint is that it is difficult to see what information is /eing passed to a function
unless all that information is passed as parameters" 6ometimes glo/al varia/les are
ver& useful however, and this pro/lem need not /e crippling" 7 wa& to ma-e this
clear is to write glo/al varia/les in capital letters onl&, while writing the rest of the
varia/les in mainl& small letters""
int REG91EN3BRBR;
....
0 int local integer;
A
This allows glo/al varia/les to /e spotted easil&" 7nother reason for restricting the
use of glo/al varia/les is that it is easier to de/ug a program if onl& local varia/les
are used" The reason is that once a function capsule is tested and sealed it can /e
guaranteed to wor- in all cases, provided it is not affected /& an& other functions
from outside" !lo/al varia/les punch holes in the sealed function capsules /ecause
the& allow /ugs from other functions to creep into tried and tested ones" 7n alert
and careful programmer can usuall& control this without difficult&"
The following guidelines ma& help the reader to decide whether to use local or
glo/al data:
7lwa&s thin- of using a local varia/le first" 0s it impracticalF ?es, if it means
passing doCens of parameters to functions, or reproducing a lot of varia/les"
!lo/al varia/les will sometimes tid& up a program"
ocal varia/les ma-e the flow of data in a program clearer and the& reduce
the amount of memor& used /& the program when the& are not in use"
The preference in this /oo- is to use local varia/les for all wor-, except
where a program centres around a single data structure" 0f a data structure is
the main reason for a program:s existence, it is nearl& alwa&s defined
glo/all&"
Node:6cope and st&le, Next:@uestions ((, Previous:6t&le note, Up:6cope
4co*e an$ 4t1le
7ll the programs in this /oo-, which are longer than a couple of lines, are written
in an unusual wa&: with a levelled structure There are several good reasons for this"
3ne is that the sealed capsules are shown to /e sealed, /& using a comment /ar
/etween each function"
)**************************************)
7nother good reason is that an& function hands parameters down /& onl& one level
at a time and that an& return() statement hands values up a single level" The
glo/al varia/les are -ept to a single place at the head of each program so that the&
can /e seen to reach into ever&thing"
The diagram shows how the splitting of levels implies something a/out the scope
of varia/les and the handing of parameters"
Node:@uestions ((, Previous:6cope and st&le, Up:6cope
.uestions
(" >hat is a glo/al varia/leF
%" >hat is a local varia/leF
G" >hat is meant /& calling a /loc- (enclosed /& /races 0A ) a Dsealed
capsuleDF
#" 8o parameters ma-e functions lea-&F i"e" 8o the& spoil them /& letting the
varia/les lea- out into other functionsF
H" >rite a program which declares # varia/les" Two integer varia/les called
num%erKofKhats,counter which are !3.7 and two float varia/les
called xKcoord,yKcoord which are 3C7 inside the function main()"
Then add another function called another() and pass xKcoord,yKcoord to
this function" 9ow man& different storage spaces are used when this
program runsF (9int: are xKcoord,yKcoord and their copies the sameF)
Node:Preprocessor, Next:Pointers, Previous:6cope, Up:Top
Pre*rocessor Comman$s
%a#ing programming versatile.
C is unusual in that it has a pre!processor" This comes from its Unix origins" 7s its
name might suggest, the preprocessor is a phase which occurs prior to compilation
of a program" The preprocessor has two main uses: it allows external files, such as
header files, to /e included and it allows macros to /e defined" This useful feature
traditionall& allowed constant values to /e defined in Kernighan and 1itchie C,
which had no constants in the language"
Pre=processor commands are distinguished /& the hash (num/er) s&m/ol -" 3ne
example of this has alread& /een encountered for the standard header file stdio.h"
-include .stdio.h/
is a command which tells the preprocessor to treat the file stdio.h as if it were the
actuall& part of the program text, in other words to include it as part of the program
to /e compiled"
,acros are words which can /e defined to stand in place of something
complicated: the& are a wa& of reducing the amount of t&ping in a program and a
wa& of ma-ing long ungainl& pieces of code into short words" 4or example, the
simplest use of macros is to give constant values meaningful names: e"g"
-define 3BEB,HNUJ ;$@::5
This allows us to use the word 3BEB,HNUJ in the program to mean the num/er
+%$MMG" 0n this particular case, the word is clearl& not an& shorter than the num/er
it will replace, /ut it is more meaningful and would ma-e a program read more
naturall& than if the raw num/er were used" 4or instance, a program which deals
with several different fixed num/ers li-e a telephone num/er, a postcode and a
street num/er could write:
printf(&'d 'd 'd&(3BEB,HNUJ(postcode(streetnum);
instead of
printf(&'d 'd 'd&(;$@::5(578(#7);
Using the macros instead ma-es the actions much clearer and allows the
programmer to forget a/out what the num/ers actuall& are" 0t also means that a
program is eas& to alter /ecause to change a telephone num/er, or whatever, it is
onl& necessar& to change the definition, not to ret&pe the num/er in ever& single
instance"
The important feature of macros is that the& are not merel& numerical constants
which are referenced at compile time, /ut are strings which are ph&sicall& replaced
/efore compilation /& the preprocessor; This means that almost an&thing can /e
defined:
-define +UJ # P $ P 5 P 7
would allow +UJ to /e used instead of #P$P5P7" 3r
-define +3RNR &Jary had a little lam%...&
would allow a commonl& used string to /e called /& the identifier DstringD instead
of t&ping it out afresh each time" The idea of a define statement then is:
-define macroname definition on rest of line
,acros cannot define more than a single line to /e su/stituted into a program /ut
the& can /e used an&where, except inside strings" (7n&thing enclosed in string
<uotes is assumed to /e complete and untoucha/le /& the compiler") 6ome macros
are defined alread& in the file stdio.h such as:
BGL
The end of file character (Q =( for instance)
NUEE
The null character (Cero) Q $
,acro functions:
,acros with parameters:
Example M:
Note a/out include:
3ther Preprocessor commands:
Example +:
@uestions (%:
Node:,acro functions, Next:,acros with parameters, Previous:Preprocessor,
Up:Preprocessor
Macro 2unctions
7 more advanced use of macros is also permitted /& the preprocessor" This
involves macros which accept parameters and hand /ac- values" This wor-s /&
defining a macro with some dumm& parameter, sa& x" 4or example: a macro which
is usuall& defined in one of the standard li/raries is a%s() which means the
a/solute or unsigned value of a num/er" 0t is defined /elow:
-define 19+(x) ((x) . @) V -(x) : (x)
The result of this is to give the positive (or unsigned) part of an& num/er or
varia/le" This would /e no pro/lem for a function which could accept parameters,
and it is, in fact, no pro/lem for macros" ,acros can also /e made to ta-e
parameters" Consider the 19+() example" 0f a programmer were to write 19+(7)
then the preprocessor would su/stitute # for x" 0f a program read 19+(i) then the
preprocessor would su/stitute i for x and so on" (There is no reason wh& macros
can:t ta-e more than one parameter too" The programmer Aust includes two dumm&
parameters with different names" 6ee the example listing /elow") Notice that this
definition uses a curious operator which /elongs to C:
.test/ V .true result/ : .false result/
This is li-e a compact wa& of writing an if..then..else statement, ideal for
macros" .ut it is also slightl& different: it is an expression which returns a value,
where as an if..then..else is a statement with no value" 4irstl& the test is made"
0f the test is true then the first statement is carried out, otherwise the second is
carried out" 7s a memor& aid, it could /e read as:
if .test/ then .true result/ else .false result/
(8o not /e confused /& the a/ove statement which is meant to show what a
programmer might thin-" 0t is not a valid C statement") C can usuall& produce
much more efficient code for this construction than for a corresponding if=else
statement"
Node:,acros with parameters, Next:Example M, Previous:,acro functions,
Up:Preprocessor
6&en an$ (&en not to use macros (it& *arameters
0t is tempting to forget a/out the distinction /etween macros and functions,
thin-ing that it can /e ignored" To some extent this is true for a/solute /eginners,
/ut it is not a good idea to hold on to" 0t should alwa&s /e remem/ered that macros
are su/stituted whole at ever& place where the& are used in a program: this is
potentiall& a ver& large amount of repetition of code" The advantage of a macro,
however, is speed" No time is ta-en up in passing control over to a new function,
/ecause control never leaves the home function when a macro is used: it Aust
ma-es the function a /it longer" There is a limitation with macros though" 4unction
calls cannot /e used as their parameters, such as:
19+(function())
has no meaning" 3nl& varia/les or num/er constants will /e su/stituted" ,acros
are also severel& restricted in complexit& /& the limitations of the preprocessor" 0t
is simpl& not via/le to cop& complicated se<uences of code all over programs"
Choosing /etween functions and macros is a matter of personal Audgement" No
simple rules can /e given" 0n the end (as with all programming choices) it is
experience which counts towards the final ends" 4unctions are easier to de/ug than
macros, since the& allow us to single step through the code" Errors in macros are
ver& hard to find, and can /e ver& confusing"
Node:Example M, Next:Note a/out include, Previous:,acros with parameters,
Up:Preprocessor
+/am*le 'isting
)************************************************************)
)* *)
)* J1DRG <BJGN+3R13GN *)
)* *)
)************************************************************)
-include .stdio.h/
-define +3RNR# &1 macro definition2n&
-define +3RNR$ &must %e all on one lineII2n&
-define BC,RB++GN # P $ P 5 P 7
-define BC,R$ BC,RB++GN P #@
-define 19+(x) ((x) . @) V -(x) : (x)
-define J1C(a(%) (a . %) V (%) : (a)
-define 9RRB+3(a(%(c) (J1C(a(%) . c) V (c) : (J1C(a(%))
)************************************************************)
main () )* No -definitions inside functionsI *)
0
printf (+3RNR#);
printf (+3RNR$);
printf (&'d2n&(BC,RB++GN);
printf (&'d2n&(BC,R$);
printf (&'d2n&(19+(-8));
printf (&9iggest of # $ and 5 is 'd&(9RRB+3(#($(5));
A
Node:Note a/out include, Next:3ther Preprocessor commands, Previous:Example
M, Up:Preprocessor
;ote a)out #include
>hen an include statement is written into a program, it is a sign that a compiler
should merge another file of C programming with the current one" 9owever, the
-include statement is itself valid C, so this means that a file which is included
ma& contain -includes itself" The includes are then said to /e DnestedD" This often
ma-es includes simpler"
Node:3ther Preprocessor commands, Next:Example +, Previous:Note a/out
include, Up:Preprocessor
0t&er Pre*rocessor comman$s
"his section lies somewhat outside the main development of the boo#. 2ou might
wish to omit it on a first reading.
There are a handful more preprocessor commands which can largel& /e ignored /&
the /eginner" The& are commonl& used in DincludeD files to ma-e sure that things
are not defined twice"
N3TE : true has an& non Cero value in C" false is Cero"
-undef
This undefines a macro, leaving the name free"
-if
This is followed /& some expression on the same line" 0t allows conditional
compilation" 0t is an advanced feature which can /e used to sa&: onl&
compile the code /etween -if and -endif if the value following -if is
true, else leave out that code altogether" This is different from not executing
code==the code will not even /e compiled"
-ifdef
This is followed /& a macro name" 0f that macro is defined then this is true"
-ifndef
This is followed /& a macro name" 0f that name is not defined then this is
true"
-else
This is part of an -if, -ifdef, -ifndef preprocessor statement"
-endif
This mar-s the end of a preprocessor statement"
-line
9as the form:
-line constant filename
This is for de/ugging mainl&" This statement causes the compiler to /elieve
that the next line is line num/er (constant) and is part of the file (filename)"
-error
This is a part of the proposed 7N60 standard" 0t is intended for de/ugging" 0t
forces the compiler to a/ort compilation"
Node:Example +, Next:@uestions (%, Previous:3ther Preprocessor commands,
Up:Preprocessor
+/am*le
)***********************************************************)
)* 3o compile or not to compile *)
)***********************************************************)
-define +GJB<BLN3GN :87:
-define DHGDB # )* Dhoose this %efore compiling *)
)***********************************************************)
-if (DHGDB == #)
-define G,3GN+3RNR &3he programmer selected this&
-define <33G &instead of .... &
-else
-define G,3GN+3RNR &3he alternati4e&
-define <33G &i.e. 3hisI &
-endif
)***********************************************************)
-ifdef +GJB<BLN3GN
-define ?H13BSBR &+omething was definedI&
-else
-define ?H13BSBR &Nothing was defined&
-endif
)************************************************************)
main ()
0
printf (G,3GN+3RNR);
printf (<33G);
A
Node:@uestions (%, Previous:Example +, Up:Preprocessor
.uestions
(" 8efine a macro called D/irthda&D which descri/es the da& of the month upon
which &our /irthda& falls"
%" >rite an instruction to the preprocessor to include to maths li/rar& math.h"
G" 7 macro is alwa&s a num/er" True or falseF
#" 7 macro is alwa&s a constant" True or falseF
Node:Pointers, Next:6tandard 3utput and 6tandard 0nput, Previous:Preprocessor,
Up:Top
Pointers
%a#ing maps of data.
?ou have a map (a plan) of the computer:s memor&" ?ou need to find that essential
piece of information which is stored at some un-nown location" 9ow will &ou find
itF ?ou need a pointer;
7 pointers is a special t&pe of varia/le which holds the address or location of
another varia/le" Pointers point to these locations /& -eeping a record of the spot at
which the& were stored" Pointers to varia/les are found /& recording the address at
which a varia/le is stored" 0t is alwa&s possi/le to find the address of a piece of
storage in C using the special M operator" 4or instance: if location were a float
t&pe varia/le, it would /e eas& to find a pointer to it called locationKptr"
float location;
float *locationKptr(*address;
locationKptr = M(location);
or
address = M(location);
The declarations of pointers loo- a little strange at first" The star * s&m/ol which
stands in front of the varia/le name is C:s wa& of declaring that varia/le to /e a
pointer" The four lines a/ove ma-e two identical pointers to a floating point
varia/le called location, one of them is called locationKptr and the other is
called address" The point is that a pointer is Aust a place to -eep a record of the
address of a varia/le, so the& are reall& the same thing"
7 pointer is a /undle of information that has two parts" 3ne part is the address of
the /eginning of the segment of memor& that holds whatever is pointed to" The
other part is the t&pe of value that the pointer points to the /eginning of" This tells
the computer how much of the memor& after the /eginning to read and how to
interpret it" Thus, if the pointer is of a t&pe int, the segment of memor& returned
will /e four /&tes long (G% /its) and /e interpreted as an integer" 0n the case of a
function, the t&pe is the t&pe of value that the function will return, although the
address is the address of the /eginning of the function executa/le"
0f, li-e some modern da& programmers, &ou /elieve in sanctit& of high level
languages, it is pro/a/l& a source of wonder wh& an&one >ould ever want to -now
the address of these varia/les" 9aving gone to the trou/le to design a high level
language, li-e C, in which varia/les can /e given elegant and meaningful names: it
seems li-e a step in the /ac-ward direction to want to /e a/le to find out the exact
num/er of the memor& location at which it is stored; The whole point of varia/les,
after all, is that it is not necessar& to -now exactl& where information is reall&
stored" This is not <uite fair though" 0t is certainl& rare indeed when we should
want to -now the actual num/er of the memor& location at which something is
stored" That would reall& ma-e the idea of a high level language a /it pointless"
The idea /ehind pointers is that a high level programmer can now find out the
exact location of a varia/le without ever having to -now the actual num/er
involved" 1emem/er:
$ pointer is a variable which holds the address of the storage location for another
given variable.
C provides two operators M and * which allow pointers to /e used in man& versatile
wa&s"
Pointer operators:
Uses for pointers:
Pointers and 0nitialiCation:
Example *:
T&pes Casts and Pointers:
4unction pointers:
Calling functions /& pointer:
@uestions (G:
Node:Pointer operators, Next:Uses for pointers, Previous:Pointers, Up:Pointers
& an$ *
The M and * operators have alread& /een used once to hand /ac- values to varia/le
parameters, 6ee 5alue parameters" The& can /e read in a program to have the
following meanings:
M
The address of"""
*
The contents of the address held in"""
7nother wa& of sa&ing the second of these is:
*
The contents of the location pointed to /&"""
This reinforces the idea that pointers reach out an imaginar& hand and point to
some location in the memor& and it is more usual to spea- of pointers in this wa&"
The two operators * and M are alwa&s written in front of a varia/le, clinging on, so
that the& refer, without dou/t, to that one varia/le" 4or instance:
Mx
The address at which the varia/le x is stored"
*ptr
The contents of the varia/le which is pointed to /& ptr"
The following example might help to clarif& the wa& in which the& are used:
int some4ar; )* # *)
int *ptrKtoKsome4ar; )* $ *)
some4ar = 7$; )* 5 *)
ptrKtoKsome4ar = M(some4ar); )* 7 *)
printf (&'d&(*ptrKtoKsome4ar); )* 8 *)
*ptrKtoKsome4ar = 8:; )* : *)
The -e& to these statements is as follows:
(" 8eclare an int t&pe varia/le called some4ar"
%" 8eclare a pointer to an int t&pe called ptrKtoKsome4ar" The * which stands
in front of ptrKtoKsome4ar is the wa& C declares ptrKtoKsome4ar as a
pointer to an integer, rather than an integer"
G" et some4ar ta-e the value #%"
#" This gives a value to ptrKtoKsome4ar" The value is the address of the
varia/le some4ar" Notice that onl& at this stage does is /ecome a pointer to
the particular varia/le some4ar" .efore this, its fate is <uite open" The
declaration (%) merel& ma-es it a pointer which can point to an& integer
varia/le which is around"
H" Print out Dthe contents of the location pointed to /& ptrKtoKsome4arD in
other words somevar itself" 6o this will /e Aust #%"
M" et the contents of the location pointed to /& ptrKtoKsome4ar /e HM" This
is the same as the more direct statement:
+" some4ar = 8:;
*"
Node:Uses for pointers, Next:Pointers and 0nitialiCation, Previous:Pointer
operators, Up:Pointers
,ses for Pointers
0t is possi/le to have pointers which point to an& t&pe of data whatsoever" The& are
alwa&s declared with the * s&m/ol" 6ome examples are given /elow"
int i(*ip;
char ch(*chp;
short s(*sp;
float x(*xp;
dou%le y(*yp;
Pointers are extremel& important o/Aects in C" The& are far more important in C
than in, sa&, Pascal or .760C (,BBW,,GWB are li-e pointers)" 0n particular the& are
vital when using data structures li-e strings or arra&s or lin-ed lists" >e shall meet
these o/Aects in later chapters"
3ne example of the use of pointers is the C input function, which is called
scanf()" 0t is loo-ed at in detail in the next section" scanf() is for getting
information from the -e&/oard" 0t is a /it li-e the reverse of printf(), except that
it uses pointers to varia/les, not varia/les themselves" 4or example: to read an
integer:
int i;
scanf (&'d&(Mi);
or
int *i;
scanf (&'d&(i);
The M sign or the * sign is vital" 0f it is forgotten, scanf will pro/a/l& corrupt a
program" This is one reason wh& this important function has /een ignored up to
now"
7ssem/l& language programmers might argue that there are occasions on which it
would /e nice to -now the actual address of a varia/le as a num/er" 3ne reason
wh& one might want to -now this would /e for de/ugging" 0t is not often a useful
thing to do, /ut it is not inconceiva/le that in developing some program a
programmer would want to -now the actual address" The M operator is flexi/le
enough to allow this to /e found" 0t could /e printed out as an integer:
type *ptr:
printf (&1ddress = 'd&((int) ptr);
Node:Pointers and 0nitialiCation, Next:Example *, Previous:Uses for pointers,
Up:Pointers
Pointers an$ #nitiali7ation
6omething to /e war& of with pointer varia/les is the wa& that the& are initialiCed"
0t is incorrect, logicall&, to initialiCe pointers in a declaration" 7 compiler will
pro/a/l& not prevent this however /ecause there is nothing incorrect a/out it as far
as s&ntax is concerned"
Thin- a/out what happens when the following statement is written" This statement
is reall& tal-ing a/out two different storage places in the memor&:
int *a = $;
4irst of all, what is declared is a pointer, so space for a Ipointer to int: is allocated
/& the program and to start off with that space will contain gar/age (random
num/ers), /ecause no statement li-e
a = Msomeint;
has &et /een encountered which would give it a value" 0t will then attempt to fill
the contents of some varia/le, pointed to /& a, with the value %" This is doomed to
faliure" a onl& contains gar/age so the % could /e stored an&where" There ma& not
even /e a varia/le at the place in the memor& which a points to" Nothing has /een
said a/out that &et" This -ind of initialiCation cannot possi/l& wor- and will most
li-el& crash the program or corrupt some other data"
Node:Example *, Next:T&pes Casts and Pointers, Previous:Pointers and
0nitialiCation, Up:Pointers
+/am*le 'isting
)**********************************************)
)* *)
)* +wapping ,ointers *)
)* *)
)**********************************************)
)* ,rogram swaps the 4aria%les which a(% *)
)* point to. Not pointless really I *)
-include .stdio.h/
main ()
0 int *a(*%(*c; )* <eclr ptrs *)
int 1(9; )* <eclare storage *)
1 = #$; )* nitialiNe storage *)
9 = >;
a = M1; )* nitialiNe pointers *)
% = M9;
printf (&'d 'd2n&(*a(*%);
c = a; )* swap pointers *)
a = %;
% = c;
printf (&'d 'd2n&(*a(*%);
A
Node:T&pes Casts and Pointers, Next:4unction pointers, Previous:Example *,
Up:Pointers
T1*es" Casts an$ Pointers
0t is tempting /ut incorrect to thin- that a pointer to an integer is the same -ind of
o/Aect as a pointer to a floating point o/Aect or an& other t&pe for that matter" This
is not necessaril& the case" Compilers distinguish /etween pointers to different
-inds of o/Aects" There are occasions however when it is actuall& necessar& to
convert one -ind of pointer into another" This might happen with a t&pe of varia/le
called DunionsD or even functions which allocate storage for special uses" These
o/Aects are met later on in this /oo-" >hen this situation comes a/out, the cast
operator has to /e used to ma-e sure that pointers have compati/le t&pes when the&
are assigned to one another" The cast operator for varia/les, 6ee The Cast 3perator,
is written in front of a varia/le to force it to /e a particular t&pe:
(type) variable
4or pointers it is:
(type *) pointer
oo- at the following statement:
char *ch;
int *i;
i = (int *) ch;
This copies the value of the pointer ch to the pointer i" The cast operator ma-es
sure that the pointers are in step and not tal-ing at cross purposes" The reason that
pointers have to /e Icast: into shape is a /it su/tle and depends upon particular
computers" 0n practice it ma& not actuall& do an&thing, /ut it is a necessar& part of
the s&ntax of C"
Pointer casting is discussed in greater detail in the chapter on 6tructures and
Unions"
Node:4unction pointers, Next:Calling functions /& pointer, Previous:T&pes Casts
and Pointers, Up:Pointers
Pointers to functions
"his section is somewhat outside of the main development of the boo#. 2ou might
want to omit it on first reading.
et:s now consider pointers to functions as opposed to varia/les" This is an
advanced feature which should /e used with more than a little care" The idea
/ehind pointers to functions is that &ou can pass a function as a parameter to
another function; This seems li-e a /iCarre notion at first /ut in fact it ma-es
perfect sense"
Pointers to functions ena/le &ou to tell an& function which su/=ordinate function it
should use to do its Ao/" That means that &ou can plug in a new function in place of
an old one Aust /& passing a different parameter value to the function" ?ou do not
have to rewrite an& code" 0n machine code circles this is sometimes called
indirection or vectoring"
>hen we come to loo- at arra&s, we:ll find that a pointer to the start of an arra& can
/e found /& using the name of the arra& itself without the s<uare /rac-ets XY" 4or
functions, the name of the function without the round /rac-ets wor-s as a pointer
to the start of the function, as long as the compiler understands that the name
represents the function and not a varia/le with the same name" 6o==to pass a
function as a parameter to another function &ou would write
function#(function$);
0f &ou tr& this as it stands, a stream of compilation errors will /e the result" The
reason is that &ou must declare function$() explicitl& li-e this:
int function$();
0f the function returns a different t&pe then clearl& the declaration will /e different
/ut the form will /e the same" The declaration can /e placed together with other
declarations" 0t is not important whether the varia/le is declared locall& or glo/all&,
since a function is a glo/al o/Aect regardless" >hat is important is that we declare
specificall& a pointer to a function which returns a t&pe (even if it is 4oid)" The
function which accepts a function pointer as an argument loo-s li-e this:
function# (a)
int (*a)();
0 int i;
i = (*a)(parameters);
A
This declares the formal parameter a to /e a pointer to a function returning a value
of t&pe int" 6imilarl& if &ou want to declare a pointer to a function to a general
t&pe typename with the name fnptr, &ou would do it li-e this:
typename (*fnptr)();
Node:Calling functions /& pointer, Next:@uestions (G, Previous:4unction pointers,
Up:Pointers
Calling a function )1 *ointer
!iven a pointer to a function how do we call the functionF The s&ntax is this:
variable = (*fnptr)(parameters);
7n example let us loo- at a function which ta-es an integer and returns a character"
int i;
char ch( function();
Normall& this function is called using the statement:
ch = function(i);
/ut we can also do the same thing with a pointer to the function" 4irst define
char function();
char (*fnptr)();
fnptr = function;
then call the function with
ch = (*fnptr)(i);
7 pointer to a function can /e used to provide a -ind of plug=in interface to a
logical device, i"e" a wa& of choosing the right function for the Ao/"
4oid printer()(textscreen()(windows();
switch (choice)
0
case #: fnptr = printer;
%rea6;
case $: fnptr = textscreen;
%rea6;
case 5: fnptr = windows;
A
Gutput(data(fnptr);
This is the /asis of Ipol&morphism: found in o/Aect oriented languages: a choice of
a logical (virtual) function /ased on some a/stract la/el (the choice)" The CRR
language provides an a/stract form of this with a more advanced s&ntax, /ut this is
the essence of virtual function methods in o/Aect oriented languages"
B+68R+< 7 pointer to a function is an automatic local varia/le" ocal varia/les
are never initialiCed /& the compiler in C" 0f &ou inadvertentl& forget to initialiCe
the pointer to a function, &ou will come <uic-l& to grief" ,a-e sure that &our
pointers are assigned /efore &ou use them;
Node:@uestions (G, Previous:Calling functions /& pointer, Up:Pointers
.uestions
(" >hat is a pointerF
%" 9ow is a varia/le declared to /e a pointerF
G" >hat data t&pes can pointers Dpoint toDF
#" >rite a statement which converts a pointer to a character into a pointer to a
dou%le t&pe" (This is not as pointless as it seems" 0t is useful in dealing with
unions and memor& allocation functions")
H" >h& is it incorrect to declare: float *num%er = $.:8; F
Node:6tandard 3utput and 6tandard 0nput, Next:7ssignments Expressions and
3perators, Previous:Pointers, Up:Top
4tan$ar$ 0ut*ut an$ 4tan$ar$ #n*ut
"al#ing to the user.
!etting information in and out of a computer is the most important thing that a
program can do" >ithout input and output computers would /e <uite useless"
C treats all its output as though it were reading or writing to different files" 7 file is
reall& Aust an a/traction: a place where information comes from or can /e sent to"
6ome files can onl& /e read, some can onl& /e written to, others can /e /oth read
from and written to" 0n other situations files are called 0E3 streams"
C has three files (also called streams) which are alwa&s open and read& for use"
The& are called stdin, stdout and stderr, meaning standard input and standard
output and standard error file" 6tdin is the input which usuall& arrives from the
-e&/oard of a computer" stdout is usuall& the screen" stderr is the route /& which all
error messages pass: usuall& the screen" This is onl& Iusuall&: /ecause the situation
can /e altered" 0n fact what happens is that these files are Aust handed over to the
local operating s&stem to deal with and it chooses what to do with them" Usuall&
this means the -e&/oard and the screen, /ut it can also /e redirected to a printer or
to a dis- file or to a modem etc"" depending upon how the user ran the program"
The -e&/oard and screen are referred to as the standard inputEoutput files /ecause
this is what most people use, most of the time" 7lso the programmer never has to
open or close these, /ecause C does it automaticall&" The C li/rar& functions
covered /& stdio.h provides some methods for wor-ing with stdin and stdout"
The& are simplified versions of the functions that can /e used on an& -ind of file,
6ee 4iles and 8evices" 0n order of importance, the& are:
printf ()
scanf ()
getchar()
putchar()
gets ()
puts ()
printf again:
Example ):
3utput ):
4ormatting with printf:
Example ($:
3utput ($:
6pecial Control Characters again:
@uestions (H:
scanf:
Conversion characters:
9ow does scanf see the input:
4irst account of scanf:
The dangerous function:
Keeping scanf under control:
Example ((:
,atching without assigning:
4ormal 8efinition of scanf:
6ummar& of points a/out scanf:
@uestions (H/:
ow evel 0nputE3utput:
@uestions (Hc:
Node:printf again, Next:Example ), Previous:6tandard 3utput and 6tandard 0nput,
Up:6tandard 3utput and 6tandard 0nput
printf
The printf function has /een used widel& up to now for output /ecause it
provides a neat and eas& wa& of printing text and num/ers to stdout (the screen)"
0ts name is meant to signif& formatted printing /ecause it gives the user control
over how text and numerical data are to /e laid out on the screen" ,a-ing text loo-
good on screen is important in programming" C ma-es this eas& /& allowing &ou to
decide how the text will /e printed in the availa/le space" The printf function has
general form:
printf (&string...&(variables(numbers)
0t contains a string (which is not optional) and it contains an& num/er of
parameters to follow: one for each /lan- field in the string"
The /lan- fields are control se<uences which one can put into the string to /e filled
in with num/ers or the contents of varia/les /efore the final result is printed out"
These fields are introduced /& using a ' character, followed /& some coded
information, which sa&s something a/out the siCe of the /lan- space and the t&pe
of num/er or string which will /e filled into that space" 3ften the string is called
the control string /ecause it contains these control characters"
The simplest use of printf is to Aust print out a string with no /lan- fields to /e
filled:
printf (&1 pretty ordinary string..&);
printf (&3esting #($(5...&);
The next simplest case that has /een used /efore now is to print out a single integer
num/er:
int num%er = 7$;
printf (&'d&(num%er);
The two can /e com/ined:
int num%er = 7$;
printf (&+ome num%er = 'd&(num%er);
The result of this last example is to print out the following on the screen:
+ome num%er = 7$
The text cursor is left pointing to the character Aust after the %" Notice the wa& that
'd is swapped for the num/er #%" 'd defines a field which is filled in with the
value of the varia/le"
There are other -inds of data than integers though" 7n& -ind of varia/le can /e
printed out with printf" 'd is called a conversion character for integers /ecause it
tells the compiler to treat the varia/le to /e filled into it as an integer" 6o it /etter
had /e an integer or things will go wrong; 3ther characters are used for other -inds
of data" 9ere is a list if the different letters for printf"
d
signed denar& integer
u
unsigned denar& integer
x
hexadecimal integer
o
octal integer
s
string
c
single character
f
fixed decimal floating point
e
scientific notation floating point
g
use f or e, whichever is shorter
The /est wa& to learn these is to experiment with different conversion characters"
The example program and its output /elow give some impression of how the&
wor-:
Node:Example ), Next:3utput ), Previous:printf again, Up:6tandard 3utput and
6tandard 0nput
+/am*le 'isting
)*******************************************************)
)* *)
)* printf Don4ersion Dharacters and 3ypes *)
)* *)
)*******************************************************)
-include .stdio.h/
main ()
0 int i = -#@;
unsigned int ui = #@;
float x = 5.8:;
dou%le y = 5.8$;
char ch = "N";
char *stringKptr = &any old string&;
printf (&signed integer 'd2n&( i);
printf (&unsigned integer 'u2n&(ui);
printf (&3his is wrongI 'u&(i);
printf (&+ee what happens when you get the &);
printf (&character wrongI&);
printf (&Hexadecimal 'x 'x2n&(i(ui);
printf (&Gctal 'o 'o2n&(i(ui);
printf (&Lloat and dou%le 'f 'f2n&(x(y);
printf (& ditto 'e 'e2n&(x(y);
printf (& ditto 'g 'g2n&(x(y);
printf (&single character 'c2n&(ch);
printf (&whole string -/ 's&(stringKptr);
A
Node:3utput ), Next:4ormatting with printf, Previous:Example ), Up:6tandard
3utput and 6tandard 0nput
0ut*ut
signed integer -#@
unsigned integer #@
3his is wrongI #@+ee what happens when you get the character
wrongIHexadecimal LLLLLLL: 1
Gctal 5;;;;;;;;:: #$
Lloat and dou%le 5.8:@@@@ 5.8$@@@@
ditto 5.8:@@@@BP@@ 5.8$@@@@BP@@
ditto 5.8:@@@@ 5.8$@@@@
single character N
whole string -/ any old string
Node:4ormatting with printf, Next:Example ($, Previous:3utput ), Up:6tandard
3utput and 6tandard 0nput
2ormatting (it& printf
The example program a/ove does not produce a ver& neat la&out on the screen"
The conversion specifiers in the printf string can /e extended to give more
information" The ' and the character t&pe act li-e /rac-ets around the extra
information" e"g"
'-#@.5f
is an extended version of 'f, which carries some more information" That extra
information ta-es the form:
' X-Y Xf!idthY X.pY C
where the each /rac-et is used to denote that the item is optional and the s&m/ols
inside them stand for the following"
XfwidthY
This is a num/er which specifies the field width of this D/lan- fieldD" 0n
other words, how wide a space will /e made in the string for the o/Aect
concernedF 0n fact it is the minimum field width /ecause if data need more
room than is written here the& will spill out of their /ox of fixed siCe" 0f the
siCe is /igger than the o/Aect to /e printed, the rest of the field will /e filled
out with spaces"
X-Y
0f this included the output will /e left Austified" This means it will /e aligned
with the left hand margin of the field created with XfwidthY" Normall& all
num/ers are right Austified, or aligned with the right hand margin of the field
D/oxD"
X.pY
This has different meanings depending on the o/Aect which is to /e printed"
4or a floating point t&pe (float or dou%le) p specifies the num/er of
decimal places after the point which are to /e printed" 4or a string it
specifies how man& characters are to /e printed"
6ome valid format specifiers are written /elow here"
'#@d '$.$f '$8.$#s '$.:f
The ta/le /elow helps to show the effect of changing these format controls" The
width of a field is draw in /& using the Q /ars"
"b#ect to $ontrol %pec& 'ctual "utput
be printed
7$ ':d Q 7$Q
7$ '-:d Q7$ Q
5$7 '#@d Q 5$7Q
-# '-#@d Q-# Q
-# '#d Q-#Q(o4erspill)
"N" '5c Q NQ
"N" '-5c QN Q
$.;#=$= '#@f Q $.;#=$=Q
$.;#=$= '#@.$f Q $.;#Q
$.;#=$= '-#@.$f Q$.;# Q
$.;#=$= '$.7f Q$.;#=$Q(o4erspill)
$.;#= '.7f Q$.;#=@Q
$.;#= '#@.8f Q $.;#=@@Q
$.;#=$= '#@e Q$.;#=$=eP@@Q
$.;#=$= '#@.$e Q $.#;eP@@Q
$.;#=$= '#@.$g Q $.;#Q
&printf& 's QprintfQ
&printf& '#@s Q printfQ
&printf& '$s QprintfQ(o4erspill)
&printf& '8.5s Q priQ
&printf& '-8.5s Qpri Q
&printf& '.5s QpriQ
Node:Example ($, Next:3utput ($, Previous:4ormatting with printf, Up:6tandard
3utput and 6tandard 0nput
+/am*le 'isting
)***********************************************)
)* *)
)* Jultiplication 3a%le *)
)* *)
)***********************************************)
-include .stdio.h/
main () )* ,rinting in columns *)
0 int i(U;
for (i = #; i .= #@; iPP)
0
for (U = #; U .= #@; UPP)
0
printf (&'8d&(i * U);
A
printf (&2n&);
A
A
Node:3utput ($, Next:6pecial Control Characters again, Previous:Example ($,
Up:6tandard 3utput and 6tandard 0nput
0ut*ut
# $ 5 7 8 : ; = > #@
$ 7 : = #@ #$ #7 #: #= $@
5 : > #$ #8 #= $# $7 $; 5@
7 = #$ #: $@ $7 $= 5$ 5: 7@
8 #@ #8 $@ $8 5@ 58 7@ 78 8@
: #$ #= $7 5@ 5: 7$ 7= 87 :@
; #7 $# $= 58 7$ 7> 8: :5 ;@
= #: $7 5$ 7@ 7= 8: :7 ;$ =@
> #= $; 5: 78 87 :5 ;$ =# >@
#@ $@ 5@ 7@ 8@ :@ ;@ =@ >@ #@@
Node:6pecial Control Characters again, Next:@uestions (H, Previous:3utput ($,
Up:6tandard 3utput and 6tandard 0nput
4*ecial Control C&aracters
Control characters are invisi/le on the screen" The& have special purposes usuall&
to do with cursor movement" The& are written into an ordinar& string /& t&ping a
/ac-slash character 2 followed /& some other character" These characters are listed
/elow"
2%
/ac-space .6
2f
form feed 44 (also clear screen)
2n
new line N (li-e pressing return)
2r
carriage return C1 (cursor to start of line)
2t
horiContal ta/ 9T
24
vertical ta/
2&
dou/le <uote
2"
single <uote character :
22
/ac-slash character 2
2ddd
character ddd where ddd is an 76C00 code given in octal or /ase *, 6ee
Character Conversion Ta/le"
2xddd
character ddd where ddd is an 76C00 code given in hexadecimal or /ase (M,
6ee Character Conversion Ta/le"
Node:@uestions (H, Next:scanf, Previous:6pecial Control Characters again,
Up:6tandard 3utput and 6tandard 0nput
.uestions
(" >rite a program which simpl& prints out: :.$5eP@@
%" 0nvestigate what happens when &ou t&pe the wrong conversion specifier in a
program" e"g" tr& printing an integer with 'f or a floating point num/er with
'c" This is /ound to go wrong = /ut how will it go wrongF
G" >hat is wrong with the following statementsF
(" printf (x);
%" printf (&'d&);
G" printf ();
#" printf (&Num%er = 'd&);
9int: if &ou don:t -now, tr& them in a program;
Node:scanf, Next:Conversion characters, Previous:@uestions (H, Up:6tandard
3utput and 6tandard 0nput
scanf
scanf is the input function which gets formatted input from the file stdin (the
-e&/oard)" This is a ver& versatile function /ut it is also ver& eas& to go wrong
with" 0n fact it is pro/a/l& the most difficult to understand of all the C standard
li/rar& functions"
1emem/er that C treats its -e&/oard input as a file" This ma-es <uite a difference
to the wa& that scanf wor-s" The actual mechanics of scanf are ver& similar to
those of printf in reverse
scanf (&string...&(pointers);
with one important exception: namel& that it is not varia/les which are listed after
the control string, /ut pointers to varia/les" 9ere are some valid uses of scanf:
int i;
char ch;
float x;
scanf (&'d 'c 'f&( Mi( Mch( Mx);
Notice the M characters which ma-e the arguments pointers" 7lso notice the
conversion specifiers which tell scanf what t&pes of data it is going to read" The
other possi/ilit& is that a program might alread& have pointers to a particular set of
varia/les in that case the M is not needed" 4or instance:
function (i(ch(x)
int *i;
char *ch;
float *x;
0
scanf (&'d 'c 'f&( i( ch( x);
A
0n this case it would actuall& /e wrong to write the ampersand M s&m/ol"
Node:Conversion characters, Next:9ow does scanf see the input, Previous:scanf,
Up:6tandard 3utput and 6tandard 0nput
Conversion c&aracters
The conversion characters for scanf are not identical to those for printf and it is
much more important to /e precise and totall& correct with these than it is with
printf"
d
denar& integer (int or long int)
ld
long decimal integer
x
hexadecimal integer
o
octal integer
h
short integer
f
float t&pe
lf
long float or dou/le
e
float t&pe
le
dou/le
c
single character
s
character string
The difference /etween short integer and long integer can ma-e or /rea- a
program" 0f it is found that a program:s input seems to /e /ehaving strangel&, chec-
these carefull&" (6ee the section on Errors and 8e/ugging for more a/out this")
Node:9ow does scanf see the input, Next:4irst account of scanf,
Previous:Conversion characters, Up:6tandard 3utput and 6tandard 0nput
%o( $oes scanf see t&e in*ut=
>hen scanf is called in a program it chec-s to see what is in the input file, that is,
it chec-s to see what the user has t&ped in at the -e&/oard" Ke&/oard input is
usuall& /uffered" This means that the characters are held in a -ind of waiting /a& in
the memor& until the& are read" The /uffer can /e thought of as a part of the input
file stdin, holding some characters which can /e scanned though" 0f the /uffer has
some characters in it, scanf will start to loo- through theseB if not, it will wait for
some characters to /e put into the /uffer"
There is an important point here: although scanf will start scanning through
characters as soon as the& are in the /uffer, the operating s&stem often sees to it
that scanf doesn:t get to -now a/out an& of the characters until the user has
pressed the RB3URN or BN3BR -e& on the computer or terminal" 0f the /uffer is
empt& scanf will wait for some characters to /e put into it"
To understand how scanf wor-s, it is useful to thin- of the input as coming in
Ilines:" 7 line is a /unch of characters ending in a newline character 2n" This can /e
represented /& a /ox li-e the one /elow:
--------------------------------------
Q some...chars.;5=). Q"2n"Q
--------------------------------------
7s far as scanf is concerned, the input is entirel& made out of a stream of
characters" 0f the programmer sa&s that an integer is to /e expected /& using the 'd
conversion specifier then scanf will tr& to ma-e sense of the characters as an
integer" 0n other words, it will loo- for some characters which ma-e up a valid
integer, such as a group of num/ers all /etween $ and )" 0f the user sa&s that
floating point t&pe is expected then it will loo- for a num/er which ma& or ma& not
have a decimal point in it" 0f the user Aust wants a character then an& character will
do;
Node:4irst account of scanf, Next:The dangerous function, Previous:9ow does
scanf see the input, Up:6tandard 3utput and 6tandard 0nput
2irst account of scanf
Consider the example which was give a/ove"
int i;
char ch;
float x;
scanf (&'d 'c 'f&( Mi( Mch( Mx);
9ere is a simplified, ideal view of what happens" scanf loo-s at the control string
and finds that the first conversion specifier is 'd which means an integer" 0t then
tries to find some characters which fit the description of an integer in the input file"
0t s-ips over an& white space characters (spaces, newlines) which do not constitute
a valid integer until it matches one" 3nce it has matched the integer and placed its
value in the varia/le i it carries on and loo-s at the next conversion specifier 'c
which means a character" 0t ta-es the next character and places it in ch" 4inall& it
loo-s at the last conversion specifier 'f which means a floating point num/er and
finds some characters which fit the description of a floating point num/er" 0t passes
the value onto the varia/le x and then <uits"
This /rief account of scanf does not tell the whole stor& /& a long wa&" 0t assumes
that all the characters were successfull& found and that ever&thing went smoothl&:
something which seldom happens in practice;
Node:The dangerous function, Next:Keeping scanf under control, Previous:4irst
account of scanf, Up:6tandard 3utput and 6tandard 0nput
T&e $angerous function
>hat happens if scanf doesn:t find an integer or a float t&peF The answer is that it
will <uit at the first item it fails to match, leaving that character and the rest of the
input line still to /e read in the file" 7t the first character it meets which does not fit
in with the conversion string:s interpretation scanf a/orts and control passes to the
next C statement" This is wh& scanf is a Idangerous: function: /ecause it can <uit
in the middle of a tas- and leave a lot of surplus data around in the input file" These
surplus data simpl& wait in the input file until the next scanf is /rought into
operation, where the& can also cause it to <uit" 0t is not safe, therefore, to use scanf
/& itself: without some chec- that it is wor-ing successfull&"
scanf is also dangerous for the opposite reason: what happens if scanf doesn:t use
up all the characters in the input line /efore it satisfies its needsF 7gain the answer
is that it <uits and leaves the extra characters in the input file stdin for the next
scanf to read, exactl& where it left off" 6o if the program was meant to read data
from the input and couldn:t, it leaves a mess for something else to trip over" scanf
can get out of step with its input if the user t&pes something even slightl& out of
line" 0t should /e used with caution"""
Node:Keeping scanf under control, Next:Example ((, Previous:The dangerous
function, Up:6tandard 3utput and 6tandard 0nput
Kee*ing scanf un$er control
scanf ma& /e dangerous for slopp& programs which do not chec- their input
carefull&, /ut it is easil& tamed /& using it as Aust a part of a more sophisticated
input routine and sometimes even more simpl& with the aid of a ver& short function
which can /e incorporated into an& program:
s6ipgar%() )* s6ip gar%age corrupting scanf *)
0
while (getchar() I= "2n")
0
A
A
The action of this function is simpl& to s-ip to the end of the input line so that there
are no characters left in the input" 0t cannot stop scanf from getting out of step
/efore the end of a line /ecause no function can stop the user from t&ping in
nonsense; 6o to get a single integer, for instance, a program could tr&:
int i;
scanf(&'d&(Mi);
s6ipgar%();
The programmer must police user=gar/age personall& /& using a loop to the effect
of:
while (inputisnonsense)
0
printf (&Ret your act together out thereII2n&);
scanf (..)
s6ipgar%();
A
0t is usuall& as well to use s6ipgar%() ever& time"
Node:Example ((, Next:,atching without assigning, Previous:Keeping scanf
under control, Up:6tandard 3utput and 6tandard 0nput
+/am*les
9ere are some example programs with example runs to show how scanf either
wor-s or fails"
)****************************************)
)* Bxample # *)
)****************************************)
-include .stdio.h/
main ()
0 int i = @;
char ch = "*";
float x = @;
scanf (&'d 'c 'f&(Mi(Mch(Mx);
printf (&'d 'c 'f2n&(i(ch(x);
A
This program Aust waits for a line from the user and prints out what it ma-es of that
line" Things to notice a/out these examples are the wa& in which scanf
Imisunderstands: what the user has t&ped in and also the values which the varia/les
had /efore the scanf function"
nput : #x$.5
Gutput: # x $.5@@@@@
The input gets /ro-en up in the following wa&:
------------------
Q # Q"x"Q $.5 Q"2n"Q
------------------
0n this example ever&thing wor-s properl&" There are no spaces to confuse matters"
it is simple for scanf to see what the first num/er is /ecause the next character is x
which is not a valid num/er"
nput : # x $.5
Gutput: # @.@@@@@@
------ ------
Q#Q" "Q .%rea6/ Qx $.5Q
------ ------
0n this example the integer is correctl& matched as (" The character is now a space
and the x is left in the stream" The x does not match the description of a float value
so scanf terminates, leaving x $.5 still in the input stream"
nput : .
Gutput: @ * @.@@@@@@
---
Q"."Q .%rea6/
---
7 single full=stop (period)" scanf <uits straight awa& /ecause it loo-s for an
integer" 0t leaves the whole input line (which is Aust the period .) in the input
stream"
)****************************************)
)* Bxample $ *)
)****************************************)
-include .stdio.h/
main ()
0 int i = @;
char ch = "*"(ch$(ch5;
float x = @;
scanf (&'d 'c 'f&( Mi(Mch(Mx);
scanf (&'c 'c&( Mch$(Mch5);
printf (&'d 'c 'f2n 'c 'c&);
A
The input for this program is:
: x$.5:
and the output is:
: @.@@@@@@
x $
--------- -------------
Q : Q " " Q .%rea6/ Q"x"Q"$"Q .5: Q
--------- -------------
9ere the integer is successfull& matched with M" The character is matched with a
space /ut the float character finds an x in the wa&, so the first scanf a/orts leaving
the value of x unchanged and the rest of the characters still in the file" The second
scanf function then pic-s these up" 0t can /e seen that the first two characters are
the x which caused the previous scanf to fail and the first % of the intended
floating point num/er"
)****************************************)
)* Bxample 5 *)
)****************************************)
-include .stdio.h/
main()
0 char ch#(ch$(ch5;
scanf (&'c 'c 'c&(Mch#(Mch$(Mch5);
printf (&'c 'c 'c&(ch#(ch$(ch5);
A
Trials:
input : a%c
output: a % c
input : a XreturnY
% XreturnY
c XreturnY
output: a % c
input : $.5
output: $ . 5
Node:,atching without assigning, Next:4ormal 8efinition of scanf,
Previous:Example ((, Up:6tandard 3utput and 6tandard 0nput
Matc&ing (it&out assigning
scanf allows input t&pes to /e matched /ut then discarded without /eing assigned
to an& varia/le" 0t also allows whole se<uences of characters to /e matched and
s-ipped" 4or example:
scanf (&'*c&);
would s-ip a single character" The * character means do not ma-e an assignment"
Note carefull& that the following is wrong:
scanf (&'*c&( Mch);
7 pointer should not /e given for a dumm& conversion character" 0n this simple
case a/ove it pro/a/l& does not matter, /ut in a string with several things to /e
matched, it would ma-e the conversion characters out of step with the varia/les,
since scanf does not return a value from a dumm& conversion character" 0t might
seem as though there would /e no sense in writing:
scanf (&'*s 'f 'c&(Mx(Mch);
/ecause the whole input file is one long string after all, /ut this is not true /ecause,
as far as scanf is concerned a string is terminated /& an& white space character, so
the float t&pe x and the character ch would receive values provided there were a
space or newline character after an& string"
0f an& non=conversion characters are t&ped into the string scanf will match and s-ip
over them in the input" 4or example:
scanf (& Num%er = 'd&(Mi);
0f the input were: Num%er = $8:, scanf would s-ip over the Num%er = " 7s
usual, if the string cannot /e matched, scanf will a/ort, leaving the remaining
characters in the input stream"
)****************************************)
)* Bxample 7 *)
)****************************************)
-include .stdio.h/
main()
0 float x = @;
int i = @;
char ch = "*";
scanf(&+6ipthisI '*f 'd '*c&(Mi);
printf(&'f 'd 'c&(x(i(ch);
A
nput : +6ipthisI $5
Gutput: @.@@@@@@ $5 *
nput : $:
Gutput: @.@@@@@@ @ *
0n this last case scanf a/orted /efore matching an&thing"
Node:4ormal 8efinition of scanf, Next:6ummar& of points a/out scanf,
Previous:,atching without assigning, Up:6tandard 3utput and 6tandard 0nput
2ormal -efinition of scanf
The general form of the scanf function is:
n = scanf (&string...&( pointers);
The value n returned is the num/er of items matched or the end of file character
BGL, or NUEE if the first item did not match" This value is often discarded" The
control string contains a num/er of conversion specifiers with the following
general form:
'X*YXnYC
X*Y
the optional assignment suppression character"
XnY
this is a num/er giving the maximum field width to /e accepted /& scanf for
a particular item" That is, the maximum num/er of characters which are to
/e thought of as /eing part of one the current varia/le value"
C
is one of the characters listed a/ove"
7n& white space characters in the scanf string are ignored" 7n& other characters
are matched" The pointers must /e pointers to varia/les of the correct t&pe and the&
must match the conversion specifiers in the order in which the& are written"
There are two variations on the conversion specifiers for strings, though it is ver&
li-el& that man& compilers will not support this" .oth of the following impl&
strings:
'Xset of charactersY
a string made up of the given characters onl&"
'XZset of charactersY
a string which is delimited /& the set of characters given"
4or example, to read the rest of a line of text, up to /ut not including the end of
line, into a string arra& one would write:
scanf(&'XZ2nY&(stringarray);
Node:6ummar& of points a/out scanf, Next:@uestions (H/, Previous:4ormal
8efinition of scanf, Up:6tandard 3utput and 6tandard 0nput
4ummar1 of *oints a)out scanf
6canf wor-s across input lines as though it were dealing with a file" Usuall&
the user t&pes in a line and hits return" The whole line is then thought of as
/eing part of the input file pointer stdin"
0f scanf finds the end of a line earl& it will tr& to read past it until all its
needs are satisfied"
0f scanf fails at an& stage to match the correct t&pe of string at the correct
time, it will <uit leaving the remaining input still in the file"
0f an element is not matched, no value will /e assigned to the corresponding
varia/le"
>hite space characters are ignored for all conversion characters except 'c"
3nl& a 'c t&pe can contain a white space character"
>hite space characters in
Node:@uestions (H/, Next:ow evel 0nputE3utput, Previous:6ummar& of points
a/out scanf, Up:6tandard 3utput and 6tandard 0nput
.uestions
(" >hat is a white space characterF
%" >rite a program which fetches two integers from the user and multiplies
them together" Print out the answer" Tr& to ma-e the input as safe as
possi/le"
G" >rite a program which Aust echoes all the input to the output"
#" >rite a program which strips spaces out of the input and replaces them with
a single newline character"
H" scanf alwa&s ta-es pointer arguments" True or falseF
Node:ow evel 0nputE3utput, Next:@uestions (Hc, Previous:@uestions (H/,
Up:6tandard 3utput and 6tandard 0nput
'o( 'evel #n*ut>0ut*ut
getchar and putchar:
gets and puts:
Node:getchar and putchar, Next:gets and puts, Previous:ow evel 0nputE3utput,
Up:ow evel 0nputE3utput
getchar an$ putchar
scanf() and printf() are relativel& high level functions: this means that the& are
versatile and do a lot of hidden wor- for the user" C also provides some functions
for dealing with input and output at a lower level: character /& character" These
functions are called getchar() and putchar() /ut, in fact, the& might not /e
functions: the& could /e macros instead, 6ee Preprocessor"
Q
high le4el: printf() Q scanf()
Q
) Q 2
Q
low le4el: putchar() Q getchar()
Q
getchar gets a single character from the input file stdinB putchar writes a single
character to the output file stdout" getchar returns a character t&pe: the next
character on the input file" 4or example:
char ch;
ch = getchar();
This places the next character, what ever it might /e, into the varia/le ch" Notice
that no conversion to different data t&pes can /e performed /& getchar() /ecause
it deals with single characters onl&" 0t is a low level function and does not I-now:
an&thing a/out data t&pes other than characters"
getchar was used in the function s6ipgar%() to tame the scanf() function" This
function was written in a ver& compact wa&" 7nother wa& of writing it would /e as
/elow:
s6ipgar% () )* s6ip gar%age corrupting scanf *)
0 char ch;
ch = getchar();
while (ch I= "2n")
0
ch = getchar();
A
A
The I= s&m/ol means Dis not e<ual toD and the while statement is a loop" This
function -eeps on getchar=ing until it finds the newline character and then it
<uits" This function has man& uses" 3ne of these is to cop& immediate -e&press
statements of languages li-e .760C, where a program responds to -e&s as the& are
pressed without having to wait for return to /e pressed" >ithout special li/rar&
functions to give this -ind of input (which are not universal) it is onl& possi/le to
do this with the return -e& itself" 4or example:
printf(&,ress RB3URN to continue2n&);
s6ipgar%();
s6ipgar%() does not receive an& input until the user presses RB3URN, and then it
simpl& s-ips over it in one go; The effect is that it waits for RB3URN to /e pressed"
putchar() writes a character t&pe and also returns a character t&pe" 4or example:
char ch = "*";
putchar (ch);
ch = putchar (ch);
These two alternatives have the same effect" The value returned /& putchar() is
the character which was written to the output" 0n other words it Aust hands the same
value /ac- again" This can simpl& /e discarded, as in the first line" putchar() is
not much use without loops to repeat it over and over again"
7n important point to remem/er is that putchar() and getchar() could well /e
implemented as macros, rather than functions" This means that it might not /e
possi/le to use functions as parameters inside them:
putchar( function() );
This depends entirel& upon the compiler, /ut it is something to watch out for"
Node:gets and puts, Previous:getchar and putchar, Up:ow evel 0nputE3utput
gets an$ puts
Two functions which are similar to putchar() and getchar() are puts() and
gets() which mean putstring and getstring respectivel&" Their purpose is either to
read a whole string from the input file stdin or write a whole string to the output
stdout" 6trings are groups or arra&s of characters" 4or instance:
char *stringXlengthY;
string = gets(string);
puts(string);
,ore information a/out these is given later, 6ee 6trings"
Node:@uestions (Hc, Previous:ow evel 0nputE3utput, Up:6tandard 3utput and
6tandard 0nput
.uestions
(" 0s the following statement possi/leF (0t could depend upon &our compiler:
tr& it;)
%" putchar(getchar());
G"
>hat might this doF (9int: re=read the chapter a/out the pre=processor")
#" 1e write the statement in <uestion (, assuming that putchar() and
getchar() are macros"
Node:7ssignments Expressions and 3perators, Next:8ecisions, Previous:6tandard
3utput and 6tandard 0nput, Up:Top
8ssignments" +/*ressions an$ 0*erators
"hin#ing in C. Wor#ing things out.
7n operator is something which ta-es one or more values and does something
useful with those values to produce a result" 0t operates on them" The terminolog&
of operators is the following:
operator
6omething which operates on someting"
operand
Each thing which is operated upon /& an operator is called an operand"
operation
The action which was carried out upon the operands /& the operator;
There are lots of operators in C" 6ome of them ma& alread& /e familiar:
P - * ) = M ==
,ost operators can /e thought of as /elonging to one of three groups, divided up
ar/itraril& according to what the& do with their operands" These rough groupings
are thought of as follows:
3perators which produce new values from old ones" The& ma-e a result
from their operands" e"g" P, the addition operator ta-es two num/ers or two
varia/les or a num/er and a varia/le and adds them together to give a new
num/er"
3perators which ma-e comparisons" e"g" less than, e<ual to, greater than"""
3perators which produce new varia/le t&pes: li-e the cast operator"
The maAorit& of operators fall into the first group" 0n fact the second group is a
su/set of the first, in which the result of the operation is a /oolean value of either
true of false"
C has no less than thirt& nine different operators" This is more than, sa&, Pascal and
.760C put together; The operators serve a variet& of purposes and the& can /e
used ver& freel&" The o/Aect of this chapter is to explain the /asics of operators in
C" The more a/struse operators are loo-ed at in another chapter"
Expressions and values:
Example (%:
3utput (%:
Parentheses and Priorit&:
Unar& 3perator Precedence:
6pecial 7ssignment 3perators PP --:
,ore 6pecial 7ssignments:
Example (G:
3utput (G:
The Cast 3perator:
Expressions and T&pes:
6ummar& of 3perators and Precedence:
@uestions (M:
Node:Expressions and values, Next:Example (%, Previous:7ssignments
Expressions and 3perators, Up:7ssignments Expressions and 3perators
+/*ressions an$ values
The most common operators in an& language are /asic arithmetic operators" 0n C
these are the following:
P
plus (unar&)
-
minus (force value to /e negative)
P
addition
-
su/traction
*
multiplication
)
floating point division
)
integer division DdivD
'
integer remainder DmodD
These operators would not /e useful without a partner operator which could attach
the values which the& produce to varia/les" Perhaps the most important operator
then is the assignment operator:
= assignment operator
This has /een used extensivel& up to now" 4or example:
dou%le x(y;
x = $.58:;
y = x;
x = x P $ P 5)8;
The assignment operator ta-es the value of whatever is on the right hand side of
the = s&m/ol and puts it into the varia/le on the left hand side" 7s usual there is
some standard Aargon for this, which is useful to -now /ecause compilers tend to
use this when handing out error messages" The assignment operator can /e
summariCed in the following wa&:
lvalue = e(pression;
This statement sa&s no more than what has /een said a/out assignments alread&:
namel& that it ta-es something on the right hand side and attaches it to whatever is
on the left hand side of the = s&m/ol" 7n expression is simpl& the name for an&
string of operators, varia/les and num/ers" 7ll of the following could /e called
expressions:
# P $ P 5
a P somefunction()
5$ * x)5
i ' 7
x
#
($$ P 7*(function() P $))
function () )* pro4ided it returns a sensi%le 4alue *)
3values on the other hand are simpl& names for memor& locations: in other words
varia/le names, or identifiers" The name comes from Ileft values: meaning
an&thing which can legall& /e written on the left hand side of an assignment"
Node:Example (%, Next:3utput (%, Previous:Expressions and values,
Up:7ssignments Expressions and 3perators
+/am*le
)**************************************)
)* *)
)* Gperators <emo - # *)
)* *)
)**************************************)
-include .stdio.h/
)**************************************)
main ()
0 int i;
printf (&1rithmetic Gperators2n2n&);
i = :;
printf (&i = :( -i is : 'd2n&( -i);
printf (&int # P $ = 'd2n&( # P $);
printf (&int 8 - # = 'd2n&( 8 - #);
printf (&int 8 * $ = 'd2n&( 8 * $);
printf (&2n> di4 7 = $ remainder #:2n&);
printf (&int > ) 7 = 'd2n&( > ) 7);
printf (&int > ' 7 = 'd2n&( > ' 7);
printf (&dou%le > ) 7 = 'f2n&( >.@ ) 7.@);
A
Node:3utput (%, Next:Parentheses and Priorit&, Previous:Example (%,
Up:7ssignments Expressions and 3perators
0ut*ut
1rithmetic Gperators
i = :( -i is : -:
int # P $ = 5
int 8 - # = 7
int 8 * $ = #@
> di4 7 = $ remainder #:
int > ) 7 = $
int > 7 = #
dou%le > ) 7 = $.$8@@@@
Node:Parentheses and Priorit&, Next:Unar& 3perator Precedence, Previous:3utput
(%, Up:7ssignments Expressions and 3perators
Parent&eses an$ Priorit1
Parentheses are classed as operators /& the compiler, although their position is a /it
unclear" The& have a value in the sense that the& assume the value of whatever
expression is inside them" Parentheses are used for forcing a priorit& over
operators" 0f an expression is written out in an am/iguous wa&, such as:
a P % ) 7 * $
it is not clear what is meant /& this" 0t could /e interpreted in several wa&s:
((a P %) ) 7) * $
or
(a P %)) (7 * $)
or
a P (%)7) * $
and so on" .& using parentheses, an& dou/t a/out what the expression means is
removed" Parentheses are said to have a higher priorit& than R N or E /ecause the&
are evaluated as Dsealed capsulesD /efore other operators can act on them" Putting
parentheses in ma& remove the am/iguit& of expressions, /ut it does not alter than
fact that
a P % ) 7 * $
is am/iguous" >hat will happen in this caseF The answer is that the C compiler has
a convention a/out the wa& in which expressions are evaluated: it is called operator
precedence" The convention is that some operators are stronger than others and that
the stronger ones will alwa&s /e evaluated first" 3therwise, expressions li-e the
one a/ove are evaluated from left to right: so an expression will /e dealt with from
left to right unless a strong operator overrides this rule" Use parentheses to /e sure"
7 ta/le of all operators and their priorities is given in the reference section"
Node:Unar& 3perator Precedence, Next:6pecial 7ssignment 3perators PP --,
Previous:Parentheses and Priorit&, Up:7ssignments Expressions and 3perators
,nar1 0*erator Prece$ence
Unar& operators are operators which have onl& a single operand: that is, the&
operate on onl& one o/Aect" 4or instance:
PP -- P - M
The precedence of unar& operators is from right to left so an expression li-e:
*ptrPP;
would do PP /efore *"
Node:6pecial 7ssignment 3perators PP --, Next:,ore 6pecial 7ssignments,
Previous:Unar& 3perator Precedence, Up:7ssignments Expressions and 3perators
4*ecial 8ssignment 0*erators ++ an$ --
C has some special operators which cut down on the amount of t&ping involved in
a program" This is a su/Aect in which it /ecomes important to thin- in C and not in
other languages" The simplest of these perhaps are the increment and decrement
operators:
PP
increment: add one to
--
decrement: su/tract one from
These attach to an& varia/le of integer or floating point t&pe" (character t&pes too,
with care") The& are used to simpl& add or su/tract ( from a varia/le" Normall&, in
other languages, this is accomplished /& writing:
4aria%le = 4aria%le P #;
0n C this would also /e <uite valid, /ut there is a much /etter wa& of doing this:
4aria%lePP; or
PP4aria%le;
would do the same thing more neatl&" 6imilarl&:
4aria%le = 4aria%le - #;
is e<uivalent to:
4aria%le--;
or
--4aria%le;
Notice particularl& that these two operators can /e placed in front or after the name
of the varia/le" 0n some cases the two are identical, /ut in the more advanced uses
of C operators, which appear later in this /oo-, there is a su/tle difference /etween
the two"
Node:,ore 6pecial 7ssignments, Next:Example (G, Previous:6pecial 7ssignment
3perators PP --, Up:7ssignments Expressions and 3perators
More 4*ecial 8ssignments
9ere are some of the nicest operators in C" i-e PP and -- these are short wa&s of
writing longer expressions" Consider the statement:
4aria%le = 4aria%le P $5;
0n C this would /e a long winded wa& of adding %G to 4aria%le" 0t could /e done
more simpl& using the general increment operator: P=
4aria%le P= $5;
This performs exactl& the same operation" 6imilarl& one could write:
4aria%le# = 4aria%le# P 4aria%le$;
as
4aria%le# P= 4aria%le$;
and so on" There is a handful of these
.operation/=
operators: one for each of the maAor operations which can /e performed" There is,
naturall&, one for su/traction too:
4aria%le = 4aria%le - 7$;
can /e written:
4aria%le -= 7$;
,ore surprisingl&, perhaps, the multiplicative assignment:
4aria%le = 4aria%le * $;
ma& /e written:
4aria%le *= $;
and so on" The main arithmetic operators all follow this pattern:
P=
add assign
-=
su/tract assign
*=
multipl& assign
)=
divide (dou/le) and (int) t&pes
'=
remainder (int) t&pe onl&"
and there are more exotic -inds, used for /it operations or machine level
operations, which will /e ignored at this stage:
//=
..=
Z=
Q=
M=
Node:Example (G, Next:3utput (G, Previous:,ore 6pecial 7ssignments,
Up:7ssignments Expressions and 3perators
+/am*le 'isting
)**************************************)
)* *)
)* Gperators <emo - $ *)
)* *)
)**************************************)
-include .stdio.h/
)**************************************)
main ()
0 int i;
printf (&1ssignment Gperators2n2n&);
i = #@; )* 1ssignment *)
printf(&i = #@ : 'd2n&(i);
iPP; )* i = i P # *)
printf (&iPP : 'd2n&(i);
i P= 8; )* i = i P 8 *)
printf (&i P= 8 : 'd2n&(i);
i--; )* i = i = # *)
printf (&i-- : 'd2n&(i);
i -= $; )* i = i - $ *)
printf (&i -= $ : 'd2n&(i);
i *= 8; )* i = i * 8 *)
printf (&i *= 8 :'d2n&(i);
i )= $; )* i = i ) $ *)
printf (&i )= $ : 'd2n&(i);
i '= 5; )* i = i ' 5 *)
printf (&i ''= 5 : 'd2n&(i);
A
Node:3utput (G, Next:The Cast 3perator, Previous:Example (G, Up:7ssignments
Expressions and 3perators
0ut*ut
1ssignment Gperators
i = #@ : #@
iPP : ##
i P= 8 : #:
i-- : #8
i -= $ : #5
i *= 8 ::8
i )= $ : 5$
i '= 5 : $
Node:The Cast 3perator, Next:Expressions and T&pes, Previous:3utput (G,
Up:7ssignments Expressions and 3perators
T&e Cast 0*erator
The cast operator is an operator which forces a particular t&pe mould or t&pe cast
onto a value, hence the name" 4or instance a character t&pe varia/le could /e
forced to fit into an integer t&pe /ox /& the statement:
char ch;
int i;
i = (int) ch;
This operator was introduced earlier, 6ee 5aria/les" 0t will alwa&s produce some
value, whatever the conversion: however remotel& impro/a/le it might seem" 4or
instance it is <uite possi/le to convert a character into a floating point num/er: the
result will /e a floating point representation of its 76C00 code;
Node:Expressions and T&pes, Next:6ummar& of 3perators and Precedence,
Previous:The Cast 3perator, Up:7ssignments Expressions and 3perators
+/*ressions an$ T1*es
There is a rule in C that all arithmetic and mathematical operations must /e carried
out with long varia/les: that is, the t&pes
dou%le
long float
int
long int
0f the programmer tries to use other t&pes li-e short or float in a mathematical
expression the& will /e cast into long t&pes automaticall& /& the compiler" This can
cause confusion /ecause the compiler will spot an error in the following statement:
short i( U = $;
i = U * $ P #;
7 compiler will claim that there is a t&pe mismatch /etween i and the expression
on the right hand side of the assignment" The compiler is perfectl& correct of
course, even though it appears to /e wrong" The su/tlet& is that arithmetic cannot
/e done in short t&pe varia/les, so that the expression is automaticall& converted
into long t&pe or int t&pe" 6o the right hand side is int t&pe and the left hand side
is short t&pe: hence there is indeed a t&pe mismatch" The programmer can get
around this /& using the cast operator to write:
short i( U = $;
i = (short) U * $ P #;
7 similar thing would happen with float:
float x( y = $.5;
x = y * $.8;
would also /e incorrect for the same reasons as a/ove"
Comparisons and ogic
Com*arisons an$ 'ogic
6ix operators in C are for ma-ing logical comparisons" The relevance of these
operators will <uic-l& /ecome clear in the next chapter, which is a/out decisions
and comparisons" The six operators which compare values are:
==
is e<ual to
I=
is not e<ual to
/
is greater than
.
is less than
/=
is greater than or e<ual to
.=
is less than or e<ual to
These operators /elong to the second group according to the scheme a/ove /ut
the& do actuall& result in values so that the& could /e thought of as /eing a part of
the first group of operators too" The values which the& produce are called true and
false" 7s words, DtrueD and DfalseD are not defined normall& in C, /ut it is eas& to
define them as macros and the& ma& well /e defined in a li/rar& file:
-define 3RUB #
-define L1E+B @
4alsit& is assumed to have the value Cero in C and truth is represented /& an& non=
Cero value" These comparison operators are used for ma-ing decisions, /ut the& are
themselves operators and expressions can /e /uilt up with them"
# == #
has the value DtrueD (which could /e an&thing except Cero)" The statement:
int i;
i = (# == $);
would /e false, so i would /e false" 0n other words, i would /e Cero"
Comparisons are often made in pairs or even in groups and lin-ed together with
words li-e 31 and 7N8" 4or instance, some test might want to find out whether:
(' is greater than B) 'N) (' is greater than $)
C does not have words for these operations /ut gives s&m/ols instead" The logical
operators, as the& are called, are as follows:
MM
logical 7N8
QQ
logical 31 inclusive
I
logical N3T
The statement which was written in words a/ove could /e translated as:
(1 / 9) MM (1 / D)
The statement:
(1 is greater than 9) 1N< (1 is not greater than D)
translates to:
(1 / 9) MM I(1 / D)
6ha-espeare might have /een disappointed to learn that, whatever the value of a
varia/le to%e the result of
theOuestion = to%e QQ Ito%e
must alwa&s /e true" The N3T operator alwa&s creates the logical opposite: Itrue
is false and Ifalse is true" 3n or the other of these must /e true" theOuestion is
therefore alwa&s true" 4ortunatel& this is not a matter of life or death;
Node:6ummar& of 3perators and Precedence, Next:@uestions (M,
Previous:Expressions and T&pes, Up:7ssignments Expressions and 3perators
4ummar1 of 0*erators an$ Prece$ence
The highest priorit& operators are listed first"
"perator "peration Evaluated.
() parentheses left to right
XY sOuare %rac6ets left to right
PP increment right to left
-- decrement right to left
(type) cast operator right to left
* the contents of right to left
M the address of right to left
- unary minus right to left
[ one"s complement right to left
I logical NG3 right to left
* multiply left to right
) di4ide left to right
' remainder (JG<) left to right
P add left to right
- su%tract left to right
// shift right left to right
.. shift left left to right
/ is greater than left to right
/= greater than or eOual to left to right
.= less than or eOual to left to right
. less than left to right
== is eOual to left to right
I= is not eOual to left to right
M %itwise 1N< left to right
Z %itwise exclusi4e GR left to right
Q %itwise inclusi4e GR left to right
MM logical 1N< left to right
QQ logical GR left to right
= assign right to left
P= add assign right to left
-= su%tract assign right to left
*= multiply assign right to left
)= di4ide assign right to left
'= remainder assign right to left
//= right shift assign right to left
..= left shift assign right to left
M= 1N< assign right to left
Z= exclusi4e GR assign right to left
Q= inclusi4e GR assign right to left
Node:@uestions (M, Previous:6ummar& of 3perators and Precedence,
Up:7ssignments Expressions and 3perators
.uestions
(" >hat is an operandF
%" >rite a statement which prints out the remainder of H divided /& %"
G" >rite a short statement which assigns the remainder of H divided /& % to a
varia/le called DremD"
#" >rite a statement which su/tracts =H from ($"
H" >rite in C: if ( is not e<ual to %G, print out DThan- goodness for
mathematics;D
Node:8ecisions, Next:oops, Previous:7ssignments Expressions and 3perators,
Up:Top
-ecisions
"esting and 4ranching. %a#ing conditions.
6uppose that a fictional traveller, some character in a /oo- li-e this one, came to
the end of a straight, unfinished road and waited there for the author to decide
where the road would lead" The author might decide a num/er of things a/out this
road and its traveller:
The road will carr& on in a straight line" 0f the traveller is thirst& he will stop
for a drin- /efore continuing"
The road will for- and the traveller will have to decide whether to ta-e the
left /ranch or the right /ranch"
The road might have a crossroads or a meeting point where man& roads
come together" 7gain the traveller has to decide which wa& to go"
>e are often faced with this dilemma: a situation in which a decision has to /e
made" Up to now the simple example programs in this /oo- have not had an&
choice a/out the wa& in which the& progressed" The& have all followed narrow
paths without an& choice a/out which wa& the& were going" This is a ver& limited
wa& of expressing ideas though: the a/ilit& to ma-e decisions and to choose
different options is ver& useful in programming" 4or instance, one might want to
implement the following ideas in different programs:
0f the user hits the Aac-pot, write some message to sa& so" D?ou:ve won the
game;D
0f a /an- /alance is positive then print C for credit otherwise print 8 for
de/it"
0f the user has t&ped in one of five things then do something special for each
special case, otherwise do something else"
These choices are actuall& Aust the same choices that the traveller had to ma-e on
his undecided path, thinl& disguised" 0n the first case there is a simple choice: a do
of don:t choice" The second case gives two choices: do thing ( or thing %" The final
choice has several possi/ilities"
C offers four wa&s of ma-ing decisions li-e the ones a/ove" The& are listed here
/elow" The method which is num/ered %/ was encountered in connection with the
C preprocessorB its purpose is ver& similar to %a"
#: if (somethingKisKtrue)
0
)* do something *)
A
$a: if (somethingKisKtrue)
0
)* do one thing *)
A
else
0
)* do something else *)
A
$%: V (somethingKisKtrue) :
)* do one thing *)
:
)* do something else *)
5: switch (choice)
0
case firstKpossi%ility : )* do something *)
case secondKpossi%ility : )* do something *)
....
A
if:
example f(:
if else:
Nested ifs and logic:
Example (#:
6tringing together if""else:
switch:
Example (H:
To tr&:
Node:if, Next:example f(, Previous:8ecisions, Up:8ecisions
if
The first form of the if statement is an all or nothing choice" if some condition is
satisfied, do what is in the /races, otherwise Aust s-ip what is in the /races"
4ormall&, this is written:
if (condition) statement;
or
if (condition)
0
compound statement
A
Notice that, as well as a single statement, a whole /loc- of statements can /e
written under the if statement" 0n fact, there is an unwritten rule of thum/ in C that
wherever a single statement will do, a compound statement will do instead" 7
compound statement is a /loc- of single statements enclosed /& curl& /races"
7 condition is usuall& some -ind of comparison, li-e the ones discussed in the
previous chapter" 0t must have a value which is either true or false (( or $) and it
must /e enclosed /& the parentheses ( and )" 0f the condition has the value Itrue:
then the statement or compound statement following the condition will /e carried
out, otherwise it will /e ignored" 6ome of the following examples help to show
this:
int i;
printf (&3ype in an integer&);
scanf (&'ld&(Mi);
if (i == @)
0
printf (&3he num%er was Nero&);
A
if (i / @)
0
printf (&3he num%er was positi4e&);
A
if (i . @)
0
printf (&3he num%er was negati4e&);
A
The same code could /e written more /riefl&, /ut perhaps less consistentl& in the
following wa&:
int i;
printf (&3ype in an integer&);
scanf (&'ld&(Mi);
if (i == @) printf (&3he num%er was Nero&);
if (i / @) printf (&3he num%er was positi4e&);
if (i . @) printf (&3he num%er was negati4e&);
The preference in this /oo- is to include the /loc- /races, even when the& are not
strictl& re<uired" This does no harm" 0t is no more or less efficient, /ut ver& often
&ou will find that some extra statements have to go into those /races, so it is as
well to include them from the start" 0t also has the appeal that it ma-es if
statements loo- the same as all other /loc- statements and it ma-es them stand out
clearl& in the program text" This rule of thum/ is onl& dropped in ver& simple
examples li-e:
if (i == @) iPP;
The if statement alone allows onl& a ver& limited -ind of decision: it ma-es do or
don:t decisionsB it could not decide for the traveller whether to ta-e the left for- or
the right for- of his road, for instance, it could onl& tell him whether to get up and
go at all" To do much more for programs it needs to /e extended" This is the
purpose of the else statement, descri/ed after some example listings""
Node:example f(, Next:if else, Previous:if, Up:8ecisions
+/am*le 'istings
)*****************************************)
)* *)
)* f... -# *)
)* *)
)*****************************************)
-include .stdio.h/
-define 3RUB #
-define L1E+B @
)******************************************)
main ()
0 int i;
if (3RUB)
0
printf (&3his is always printed&);
A
if (L1E+B)
0
printf (&3his is ne4er printed&);
A
A
)*******************************************)
)* *)
)* f demo -$ *)
)* *)
)*******************************************)
)* Gn %oard car computer. ?or6s out the *)
)* num%er of 6ilometers to the litre *)
)* that the car is doing at present *)
-include .stdio.h/
)*******************************************)
)* Ee4el @ *)
)*******************************************)
main ()
0 dou%le fuel(distance;
LindSalues (Mfuel(Mdistance);
Report (fuel(distance);
A
)********************************************)
)* Ee4el # *)
)********************************************)
LindSalues (fuel(distance) )* from car *)
)* 3hese 4alues would %e changing in *)
)* a real car( independently of the *)
)* program. *)
dou%le *fuel(*distance;
0
)* how much fuel used since last chec6 on 4alues *)
printf (&Bnter fuel used&);
scanf (&'lf&(fuel);
)* distance tra4elled since last chec6 on 4alues *)
printf (&Bnter distance tra4elled&);
scanf (&'lf&(distance);
A
)**********************************************)
Report (fuel(distance) )* on dash%oard *)
dou%le fuel(distance;
0 dou%le 6pl;
6pl = distance)fuel;
printf (&fuel consumption: '$.#lf&(6pl);
printf (& 6ilometers per litre2n&);
if (6pl .= #)
0
printf (&,redict fuel lea6 or car&);
printf (& needs a ser4ice2n&);
A
if (distance / 8@@)
0
printf (&Remem%er to chec6 tyres2n&);
A
if (fuel / 5@) )* 3an6 holds 7@ l *)
0
printf (&Luel getting low: 's left2n&(7@-fuel);
A
A
Node:if else, Next:Nested ifs and logic, Previous:example f(, Up:8ecisions
if ... else
The if .. else statement has the form:
if (condition) statement1; else statement2;
This is most often written in the compound statement form:
if (condition)
0
statements
A
else
0
statements
A
The if..else statement is a two wa& /ranch: it means do one thing or the other"
>hen it is executed, the condition is evaluated and if it has the value Itrue: (i"e" not
Cero) then statement5 is executed" 0f the condition is Ifalse: (or Cero) then
statement6 is executed" The if..else construction often saves an unnecessar& test
from having to /e made" 4or instance:
int i;
scanf (&'ld&(i);
if (i / @)
0
printf (&3hat num%er was positi4eI&);
A
else
0
printf (&3hat num%er was negati4e or NeroI&);
A
0t is not necessar& to test whether i was negative in the second /loc- /ecause it
was implied /& the if..else structure" That is, that /loc- would not have /een
executed unless i were N3T greater than Cero" The wear& traveller a/ove might
ma-e a decision such as:
if (rightleg / leftleg)
0
ta6eKleftK%ranch();
A
else
0
ta6eKrightK%ranch();
A
Node:Nested ifs and logic, Next:Example (#, Previous:if else, Up:8ecisions
;este$ ifs an$ logic
Consider the following statements which decide upon the value of some varia/le i"
Their purposes are exactl& the same"
if ((i / $) MM (i . 7))
0
printf (&i is three&);
A
or:
if (i / $)
0
if (i . 7)
0
printf (&i is three&);
A
A
.oth of these test i for the same information, /ut the& do it in different wa&s" The
first method might /een /orn out of the following se<uence of thought:
0f i is greater than % and i is less than four, /oth at the same time, then i has
to /e G"
The second method is more complicated" Thin- carefull&" 0t sa&s:
0f i is greater than %, do what is in the curl& /races" 0nside these curl& /races
i is alwa&s greater than % /ecause otherwise the program would never have
arrived inside them" Now, if i is also less than #, then do what is inside the
new curl& /races" 0nside these curl& /races i is alwa&s less than #" .ut wait;
The whole of the second test is held inside the Di is greater than %D /races,
which is a sealed capsule: nothing else can get in, so, if the program gets
into the Di is less than #D /races as well, then /oth facts must /e true at the
same time" There is onl& one integer which is /igger than % and less than # at
the same time: it is G" 6o i is G"
The aim of this demonstration is to show that there are two wa&s of ma-ing
multiple decisions in C" Using the logical comparison operators MM, QQ (7N8,31)
and so on"" several multiple tests can /e made" 0n man& cases though it is too
difficult to thin- in terms of these operators and the sealed capsule idea /egins to
loo- attractive" This is another advantage of using the curl& /races: it helps the
programmer to see that if statements and if..else statements are made up of
sealed capsule parts" 3nce inside a sealed capsule
if (i / $)
0
)* i is greater than $ in hereI *)
A
else
0
)* i is not greater than $ hereI *)
A
the programmer can rest assured that nothing illegal can get in" The /loc- /races
are li-e regions of grace: the& cannot /e penetrated /& an&thing which does not
satisf& the right conditions" This is an enourmous weight off the mind; The
programmer can sit /ac- and thin-: 0 have accepted that i is greater than % inside
these /races, so 0 can stop worr&ing a/out that now" This is how programmers learn
to thin- in a structured wa&" The& learn to /e satisfied that certain things have
alread& /een proven and thus save themselves from the onset of madness as the
ideas /ecome too complex to thin- of all in one go"
Node:Example (#, Next:6tringing together if""else, Previous:Nested ifs and logic,
Up:8ecisions
+/am*le 'isting
)***********************************************)
)* *)
)* f demo -5 *)
)* *)
)***********************************************)
-include .stdio.h/
)***********************************************)
main ()
0 int persnum(usernum(%alance;
persnum = ;7:$;
%alance = -#$;
printf (&3he ,lastic 9an6 Dorporation2n&);
printf (&,lease enter your personal num%er :&);
usernum = getnum%er();
if (usernum == ;7:$)
0
printf (&2n3he current state of your account2n&);
printf (&is 'd2n&(%alance);
if (%alance . @)
0
printf (&3he account is o4erdrawnI2n&);
A
A
else
0
printf (&3his is not your account2n&);
A
printf (&Ha4e a splendid dayI 3han6 you.2n&);
A
)**************************************************)
getnum%er () )* get a num%er from the user *)
0 int num = @;
scanf (&'d&(Mnum);
if ((num / >>>>) QQ (num .= @))
0
printf (&3hat is not a 4alid num%er2n&);
A
return (num);
A
Node:6tringing together if""else, Next:switch, Previous:Example (#, Up:8ecisions
4tringing toget&er if..else
>hat is the difference /etween the following programsF The& /oth interpret some
imaginar& exam result in the same wa&" The& /oth loo- identical when compiled
and run" >h& then are the& differentF
)**************************************************)
)* ,rogram # *)
)**************************************************)
-include .stdio.h/
main ()
0 int result;
printf(&3ype in exam result&);
scanf (&'d&(Mresult);
if (result . #@)
0
printf (&3hat is poor&);
A
if (result / $@)
0
printf (&\ou ha4e passed.&);
A
if (result / ;@)
0
printf (&\ou got an 1I&);
A
A
)* end *)
)**************************************************)
)* ,rogram $ *)
)**************************************************)
-include .stdio.h/
main ()
0 int result;
printf(&3ype in exam result&);
scanf (&'d&(Mresult);
if (result . #@)
0
printf (&3hat is poor&);
A
else
0
if (result / $@)
0
printf (&\ou ha4e passed.&);
A
else
0
if (result / ;@)
0
printf (&\ou got an 1I&);
A
A
A
A
The answer is that the second of these programs can /e more efficient" This
/ecause it uses the else form of the if statement which in turn means that few
things have to /e calculated" Program one ma-es ever& single test, /ecause the
program meets ever& if statement, one after the other" The second program does
not necessaril& do this however" The nested if statements ma-e sure that the
second two tests are onl& made if the first one failed" 6imilarl& the third test is onl&
performed if the first two failed" 6o the second program could end up doing a third
of the wor- of the first program, in the /est possi/le case" Nesting decisions li-e
this can /e an efficient wa& of controlling long lists of decisions li-e those a/ove"
Nested loops ma-e a program /ranch into lots of possi/le paths, /ut choosing one
path would preclude others"
Node:switch, Next:Example (H, Previous:6tringing together if""else, Up:8ecisions
switch9 integers an$ c&aracters
The switch construction is another wa& of ma-ing a program path /ranch into lots
of different lim/s" 0t can /e used as a different wa& of writing a string of if ..
else statements, /ut it is more versatile than that and it onl& wor-s for integers
and character t&pe values" 0t wor-s li-e a -ind of multi=wa& switch" (6ee the
diagram") The switch statement has the following form:
switch (int or char e(pression)
0
case constant : statement;
%rea6; )* optional *)
...
A
0t has an expression which is evaluated and a num/er of constant Icases: which are
to /e chosen from, each of which is followed /& a statement or compound
statement" 7n extra statement called %rea6 can also /e incorporated into the /loc-
at an& point" %rea6 is a reserved word"
The switch statement can /e written more specificall& for integers:
switch (integer value)
0
case #: statement1;
%rea6; )* optional line *)
case $: statement2;
%rea6; )* optional line *)
....
default: default statement
%rea6; )* optional line *)
A
>hen a switch statement is encountered, the expression in the parentheses is
evaluated and the program chec-s to see whether the result of that expression
matches an& of the constants la/elled with case" 0f a match is made (for instance,
if the expression is evaluated to %G and there is a statement /eginning Dcase
%G : """D) execution will start Aust after that case statement and will carr& on until
either the closing /race A is encountered or a /rea- statement is found" %rea6 is a
hand& wa& of Aumping straight out of the switch /loc-" 3ne of the cases is called
default" 6tatements which follow the default case are executed for all cases
which are not specificall& listed" switch is a wa& of choosing some action from a
num/er of -nown instances" oo- at the following example"
Node:Example (H, Next:To tr&, Previous:switch, Up:8ecisions
+/am*le 'isting
)************************************************)
)* *)
)* switch .. case *)
)* *)
)************************************************)
)* Jorse code program. Bnter a num%er and *)
)* find out what it is in Jorse code *)
-include .stdio.h/
-define DG<B @
)*************************************************)
main ()
0 short digit;
printf (&Bnter any digit in the range @..>&);
scanf (&'h&(Mdigit);
if ((digit . @) QQ (digit / >))
0
printf (&Num%er was not in range @..>&);
return (DG<B);
A
printf (&3he Jorse code of that digit is &);
Jorse (digit);
A
)************************************************)
Jorse (digit) )* print out Jorse code *)
short digit;
0
switch (digit)
0
case @ : printf (&-----&);
%rea6;
case # : printf (&.----&);
%rea6;
case $ : printf (&..---&);
%rea6;
case 5 : printf (&...--&);
%rea6;
case 7 : printf (&....-&);
%rea6;
case 8 : printf (&.....&);
%rea6;
case : : printf (&-....&);
%rea6;
case ; : printf (&--...&);
%rea6;
case = : printf (&---..&);
%rea6;
case > : printf (&----.&);
A
A
The program selects one of the printf statements using a switch construction" 7t
ever& case in the switch, a %rea6 statement is used" This causes control to Aump
straight out of the switch statement to its closing /race A" 0f /rea- were not
included it would go right on executing the statements to the end, testing the cases
in turn" /rea- this gives a wa& of Aumping out of a switch <uic-l&"
There might /e cases where it is not necessar& or not desira/le to Aump out of the
switch immediatel&" Thin- of a function yes() which gets a character from the
user and tests whether it was :&: or :?:"
yes () )* 1 sloppy %ut simple function *)
0
switch (getchar())
0
case "y" :
case "\" : return 3RUB
default : return L1E+B
A
A
0f the character is either :&: or :?: then the function meets the statement return
3RUB. 0f there had /een a /rea- statement after case :&: then control would not
have /een a/le to reach case :?: as well" The return statement does more than /rea-
out of switch, it /rea-s out of the whole function, so in this case /rea- was not
re<uired" The default option ensures that whatever else the character is, the
function returns false"
Node:To tr&, Previous:Example (H, Up:8ecisions
T&ings to tr1
(" >rite a program to get a lot of num/ers from the user and print out the
maximum and minimum of those"
%" Tr& to ma-e a counter which is reset to Cero when it reaches ))))"
G" Tr& to write a program incorporating the statement if (yes()) 0...A"
Node:oops, Next:7rra&s, Previous:8ecisions, Up:Top
'oo*s
Controlling repetitive processes. 'esting loops
8ecisions can also /e used to ma-e up loops" oops free a program from the
straitAac-et of doing things onl& once" The& allow the programmer to /uild a
se<uence of instructions which can /e executed again and again, with some
condition deciding when the& will stop" There are three -inds of loop in C" The&
are called:
while
do """ while
for
These three loops offer a great amount of flexi/ilit& to programmers and can /e
used in some surprising wa&s;
while:
Example (M:
Example (+:
do while:
Example (*:
for:
The flexi/le for loop:
@uitting oops and 9urr&ing Them Up;:
Nested oops:
@uestions (*:
Node:while, Next:Example (M, Previous:oops, Up:oops
while
The simplest of the three loops is the while loop" 0n common language while has a
fairl& o/vious meaning: the while=loop has a condition:
while (condition)
0
statements;
A
and the statements in the curl& /races are executed while the condition has the
value DtrueD ( ( )" There are dialects of English, however, in which DwhileD does
not have its commonplace meaning, so it is worthwhile explaining the steps which
ta-e place in a while loop"
The first important thing a/out this loop is that has a conditional expression
(something li-e (a / %) etc""") which is evaluated ever& time the loop is executed
/& the computer" 0f the value of the expression is true, then it will carr& on with the
instructions in the curl& /races" 0f the expression evaluates to false (or $) then the
instructions in the /races are ignored and the entire while loop ends" The computer
then moves onto the next statement in the program"
The second thing to notice a/out this loop is that the conditional expression comes
at the start of the loop: this means that the condition is tested at the start of ever&
Ipass:, not at the end" The reason that this is important is this: if the condition has
the value false /efore the loop has /een executed even once, the statements inside
the /races will not get executed at all = not even once"
The /est wa& to illustrate a loop is to give an example of its use" 3ne example was
snea-ed into an earlier chapter /efore its time, in order to write the s6ipgar%()
function which complemented scanf()" That was:
s6ipgar% () )* s6ip gar%age corrupting scanf *)
0
while (getchar() I= "2n")
0
A
A
This is a slightl& odd use of the while loop which is pure C, through and through" 0t
is one instance in which the programmer has to start thin-ing C and not an& other
language" 6omething which is immediatel& o/vious from listing is that the while
loop in s6ipgar%() is empt&: it contains no statements" This is <uite valid: the
loop will merel& do nothing a certain num/er of times""" at least it would do
nothing if it were not for the assignment in the conditional expression; 0t could also
/e written:
s6ipgar% () )* s6ip gar%age corrupting scanf *)
0
while (getchar() I= "2n")
0
A
A
The assignment inside the conditional expression ma-es this loop special" >hat
happens is the following" >hen the loop is encountered, the computer attempts to
evaluate the expression inside the parentheses" There, inside the parentheses, it
finds a function call to getchar(), so it calls getchar() which fetches the next
character from the input" getchar() then ta-es on the value of the character which
it fetched from the input file" Next the computer finds the I= Dis not e<ual toD
s&m/ol and the newline character 2n" This means that there is a comparison to /e
made" The computer compares the character fetched /& getchar() with the
newline character and if the& are Inot e<ual: the expression is true" 0f the& are e<ual
the expression is false" Now, if the expression is true, the while statement will loop
and start again = and it will evaluate the expression on ever& pass of the loop to
chec- whether or not it is true" >hen the expression eventuall& /ecomes false the
loop will <uit" The net result of this su/tlet& is that s6ipgar%() s-ips all the input
characters up to and including the next newline 2n character and that usuall&
means the rest of the input"
Node:Example (M, Next:Example (+, Previous:while, Up:oops
+/am*le 'isting
7nother use of while is to write a /etter function called yes()" The idea of this
function was introduced in the previous section" 0t uses a while loop which is
alwa&s true to repeat the process of getting a response from the user" >hen the
response is either &es or no it <uits using the return function to Aump right out of
the loop"
)***********************************************)
)* *)
)* Ri4e me your answerI *)
)* *)
)***********************************************)
-include .stdio.h/
-define 3RUB #
-define L1E+B @
)*************************************************)
)* Ee4el @ *)
)*************************************************)
main ()
0
printf (&\es or noV (\)N)2n&);
if (yes())
0
printf (&\B+I&);
A
else
0
printf (&NGI&);
A
A
)*************************************************)
)* Ee4el # *)
)*************************************************)
yes () )* get response \)N Ouery *)
0 char get6ey();
while (true)
0
switch (get6ey())
0
case "y" : case "\" : return (3RUB);
case "n" : case "N" : return (L1E+B);
A
A
A
)*************************************************)
)* 3ool6it *)
)*************************************************)
char get6ey () )* get a character P RB3URN *)
0 char ch;
ch = getchar();
s6ipgar%();
A
)**************************************************)
s6ipgar% ()
0
while (getchar() I= "2n")
0
A
A
)* end *)
Node:Example (+, Next:do while, Previous:Example (M, Up:oops
+/am*le 'isting
This example listing prompts the user to t&pe in a line of text and it counts all the
spaces in that line" 0t <uits when there is no more input left and printf out the
num/er of spaces"
)***********************************************)
)* *)
)* while loop *)
)* *)
)***********************************************)
)* count all the spaces in an line of input *)
-include .stdio.h/
main ()
0 char ch;
short count = @;
printf (&3ype in a line of text2n&);
while ((ch = getchar()) I= "2n")
0
if (ch == " ")
0
countPP;
A
A
printf (&Num%er of space = 'd2n&(count);
A
Node:do while, Next:Example (*, Previous:Example (+, Up:oops
do..while
The do""while loop resem/les most closel& the repeat""until loops of Pascal and
.760C except that it is the Ilogical opposite:" The do loop has the form:
do
0
statements;
A
while (condition)
Notice that the condition is at the end of this loop" This means that a do..while
loop will alwa&s /e executed at least once, /efore the test is made to determine
whether it should continue" This is the onl& difference /etween while and
do..while"
7 do..while loop is li-e the Drepeat "" untilD of other languages in the following
sense: if the condition is N3Ted using the I operator, then the two are identical"
repeat do
==
until(condition) while (Icondition)
This fact might /e useful for programmers who have not &et learned to thin- in C;
Node:Example (*, Next:for, Previous:do while, Up:oops
+/am*le 'isting
9ere is an example of the use of a do..while loop" This program gets a line of
input from the user and chec-s whether it contains a string mar-ed out with &&
<uote mar-s" 0f a string is found, the program prints out the contents of the string
onl&" 7 t&pical input line might /e:
"nceupon a time *+ere !e go round the&&&*!hat a terrible&&
The output would then /e:
+ere !e go round the&&&
0f the string has onl& one <uote mar- then the error message Istring was not closed
/efore end of line: will /e printed"
)**********************************************)
)* *)
)* do .. while demo *)
)* *)
)**********************************************)
)* print a string enclosed %y Ouotes & & *)
)* gets input from stdin i.e. 6ey%oard *)
)* s6ips anything outside the Ouotes *)
-include .stdio.h/
)*************************************************)
)* Ee4el @ *)
)*************************************************)
main ()
0 char ch(s6ipstring();
do
0
if ((ch = getchar()) == "&")
0
printf (&3he string was:2n&);
ch = s6ipstring();
A
A
while (ch I= "2n")
0
A
A
)*************************************************)
)* Ee4el # *)
)*************************************************)
char s6ipstring () )* s6ip a string &...& *)
0 char ch;
do
0
ch = getchar();
putchar(ch);
if (ch == "2n")
0
printf (&2n+tring was not closed &);
printf (&%efore end of line2n&);
%rea6;
A
A
while (ch I= "&")
0
A
return (ch);
A
Node:for, Next:The flexi/le for loop, Previous:Example (*, Up:oops
for
The most interesting and also the most difficult of all the loops is the for loop" The
name for is a hangover from earlier da&s and other languages" 0t is not altogether
appropriate for C:s version of for" The name comes from the t&pical description of
a classic for loop:
4or all values of variable from value5 to value6 in steps of 4alue5, repeat
the following se<uence of commands""""
0n .760C this loo-s li-e:
LGR variable = value1 3G value2 +3B, value,
NBC3 variable
The C for loop is much more versatile than its .760C counterpartB it is actuall&
/ased upon the while construction" 7 for loop normall& has the characteristic
feature of controlling one particular varia/le, called the control varia/le" That
varia/le is somehow associated with the loop" 4or example it might /e a varia/le
which is used to count Dfor values from $ to ($D or whatever" The form of the for
loop is:
for (statement1; condition; statement2)
0
A
4or normal usage, these expressions have the following significance"
statement5
This is some -ind of expression which initialiCes the control varia/le" This
statement is onl& carried out once /efore the start of the loop" e"g" i = @;
condition
This is a condition which /ehaves li-e the while loop" The condition is
evaluated at the /eginning of ever& loop and the loop is onl& carried out
while this expression is true" e"g" i . $@;
statement6
This is some -ind of expression for altering the value of the control varia/le"
0n languages such as Pascal this alwa&s means adding or su/tracting ( from
the varia/le" 0n C it can /e a/solutel& an&thing" e"g" iPP or i *= $@ or i )=
$.5 """
Compare a C for loop to the .760C for loop" 9ere is an example in which the loop
counts from $ to ($ in steps of $"H:
LGR C = @ 3G #@ +3B, @.8
NBC3 C
for (x = @; x .= #@; x P= @.8)
0
A
The C translation loo-s peculiar in comparison /ecause it wor-s on a su/tl&
different principle" 0t does not contain information a/out when it will stop, as the
.760C one does, instead it contains information a/out when it should /e looping"
The result is that a C for loop often has the .= s&m/ol in it" The for loop has plent&
of uses" 0t could /e used to find the sum of the first n natural num/ers ver& simpl&:
sum = @;
for (i = @; i .= n; iPP)
0
sum P= i;
A
0t generall& finds itself useful in applications where a single varia/le has to /e
controlled in a well determined wa&"
g#
+/am*le 'isting
This example program prints out all the primes num/ers /etween ( and the macro
value maxint" Prime num/ers are num/ers which cannot /e divided /& an&
num/er except ( without leaving a remainder"
)************************************************)
)* *)
)* ,rime Num%er Renerator -# *)
)* *)
)************************************************)
)* Dhec6 for prime num%er %y raw num%er *)
)* crunching. 3ry di4iding all num%ers *)
)* up to half the siNe of a gi4en i( if *)
)* remainder == @ then not primeI *)
-include .stdio.h/
-define J1CN3 8@@
-define 3RUB #
-define L1E+B @
)*************************************************)
)* Ee4el @ *)
)*************************************************)
main ()
0 int i;
for (i = $; i .= J1CN3; iPP)
0
if (prime(i))
0
printf (&'8d&(i);
A
A
A
)*************************************************)
)* Ee4el # *)
)*************************************************)
prime (i) )* chec6 for a prime num%er *)
int i;
0 int U;
for (U = $; U .= i)$; UPP)
0
if (i ' U == @)
0
return L1E+B;
A
A
return 3RUB;
A
Node:The flexi/le for loop, Next:@uitting oops and 9urr&ing Them Up;,
Previous:for, Up:oops
T&e fle/i)le for loo*
The word Istatement: was chosen carefull&, a/ove, to descri/e what goes into a for
loop" oo- at the loop again:
for (statement1; condition; statement2)
0
A
6tatement reall& means what it sa&s" C will accept an& statement in the place of
those a/ove, including the empt& statement" The while loop could /e written as a
for loop;
for (; condition; ) )* while VV *)
0
A
9ere there are two empt& statements, which are Aust wasted" This flexi/ilit& can /e
put to /etter uses though" Consider the following loop:
for (x = $; x .= #@@@; x = x * x)
0
....
A
This loop /egins from % and each time the statements in the /races are executed x
s<uares itself; 7nother odd loo-ing loop is the following one:
for (ch = "*"; ch I= "2n"; ch = getchar())
0
A
This could /e used to ma-e &et another different -ind of s6ipgar%() function"
The loop starts off /& initialiCing ch with a star character" 0t chec-s that ch I=
"2n" (which it isn:t, first time around) and proceeds with the loop" 3n each new
pass, ch is reassigned /& calling the function getchar()" 0t is also possi/le to
com/ine several incremental commands in a loop:
for (i = @( U=#@; i . U; iPP( U--)
0
printf(&i = 'd( U= 'd2n&(i(U);
A
Statement6 can /e an& statement at all which the programmer would li-e to /e
executed on ever& pass of the loop" >h& not put that statement in the curl& /racesF
0n most cases that would /e the /est thing to do, /ut in special instances it might
-eep a program tidier or more reada/le to put it in a for loop instead" There is no
good rule for when to do this, except to sa&: ma-e &ou code as clear as possi/le"
0t is not onl& the statements which are flexi/le" 7n unnerving feature of the for
construction (according to some programmers) is that even the conditional
expression in the for loop can /e altered /& the program from within the loop itself
if is written as a varia/le"
int i( num%er = $@;
for (i = @; i .= num%er; iPP)
0
if (i == >)
0
num%er = 5@;
A
A
This is so nerve shattering that man& languages for/id it outright" To /e sure, is not
often a ver& good idea to use this facilit&, /ut in the right hands, it is a powerful
one to have around"
Node:@uitting oops and 9urr&ing Them Up;, Next:Nested oops, Previous:The
flexi/le for loop, Up:oops
.uitting 'oo*s an$ %urr1ing T&em ,*<
C provides a simple wa& of Aumping out of an& of the three loops a/ove at an&
stage, whether it has finished or not" The statement which performs this action is
the same statement which was used to Aump out of switch statements in last
section"
%rea6;
0f this statement is encountered a loop will <uit where it stands" 4or instance, an
expensive wa& of assigning i to /e (% would /e:
for (i = #; i .= $@; iPP)
0
if (i == #$)
0
%rea6;
A
A
6till another wa& of ma-ing s6ipgar%() would /e to perform the following loop:
while (3RUB)
0
ch = getchar();
if (ch == "2n")
0
%rea6;
A
A
3f course, another wa& to do this would /e to use the return() statement, which
Aumps right out of a whole function" %rea6 onl& Aumps out of the loop, so it is less
drastic"
7s well as wanting to <uit a loop, a programmer might want to hurr& a loop on to
the next pass: perhaps to avoid executing a lot of irrelevant statements, for
instance" C gives a statement for this too, called:
continue;
>hen a continue statement is encountered, a loop will stop whatever it is doing
and will go straight to the start of the next loop pass" This might /e useful to avoid
dividing /& Cero in a program:
for (i = -#@; i .= #@; iPP)
0
if (i == @)
0
continue;
A
printf (&'d&( $@)i);
A
Node:Nested oops, Next:@uestions (*, Previous:@uitting oops and 9urr&ing
Them Up;, Up:oops
;este$ 'oo*s
i-e decisions, loops will also nest: that is, loops can /e placed inside other loops"
7lthough this feature will wor- with an& loop at all, it is most commonl& used with
the for loop, /ecause this is easiest to control" The idea of nested loops is important
for multi=dimensional arra&s which are examined in the next section" 7 for loop
controls the num/er of times that a particular set of statements will /e carried out"
7nother outer loop could /e used to control the num/er of times that a whole loop
is carried out" To see the /enefit of nesting loops, the example /elow shows how a
s<uare could /e printed out using two printf statements and two loops"
)*****************************************)
)* *)
)* 1 &+Ouare& *)
)* *)
)*****************************************)
-include .stdio.h/
-define +FB #@
)*****************************************)
main ()
0 int i(U;
for (i = #; i .= +FB; iPP)
0
for (U = #; U .= +FB; UPP)
0
printf(&*&);
A
printf (&2n&);
A
A
The output of this program is a D-ind ofD s<uare:
**********
**********
**********
**********
**********
**********
**********
**********
**********
**********
Node:@uestions (*, Previous:Nested oops, Up:oops
.uestions
(" 9ow man& -inds of loop does C offer, and what are the&F
%" >hen is the condition tested in each of the loopsF
G" >hich of the loops is alwa&s executed onceF
#" >rite a program which copies all input to output line /& line"
H" >rite a program to get ($ num/ers from the user and add them together"
Node:7rra&s, Next:6trings, Previous:oops, Up:Top
8rra1s
7ows and tables of storage.
7rra&s are a convenient wa& of grouping a lot of varia/les under a single varia/le
name" 7rra&s are li-e pigeon holes or chess/oards, with each compartment or
s<uare acting as a storage placeB the& can /e one dimensional, two dimensional or
more dimensional; 7n arra& is defined using s<uare /rac-ets XY" 4or example: an
arra& of three integers called DtripletD would /e declared li-e this:
int tripletX5Y;
Notice that there is no space /etween the s<uare /rac-et X and the name of the
arra&" This statement would cause space for three integers t&pe varia/les to /e
created in memor& next to each other as in the diagram /elow"
------------------------------------
int triplet: Q Q Q Q
------------------------------------
The num/er in the s<uare /rac-ets of the declaration is referred to as the Iindex:
(plural: indicies) or Isu/script: of the arra& and it must /e an integer num/er
/etween $ and (in this case) %" The three integers are called elements of the arra&
and the& are referred to in a program /& writing:
tripletX@Y
tripletX#Y
tripletX$Y
Note that the indicies start at Cero and run up to one less than the num/er which is
placed in the declaration (which is called the dimension of the arra&") The reason
for this will /ecome clear later" 7lso notice that ever& element in an arra& is of the
same t&pe as ever& other" 0t is not (at this stage) possi/le to have arra&s which
contain man& different data t&pes" >hen arra&s are declared inside a function,
storage is allocated for them, /ut that storage space is not initialiCed: that is, the
memor& space contains gar/age (random values)" 0t is usuall& necessar&, therefore,
to initialiCe the arra& /efore the program trul& /egins, to prepare it for use" This
usuall& means that all the elements in the arra& will /e set to Cero"
>h& use arra&sF:
imits and The 8imension of an arra&:
7rra&s and for loops:
Example ():
7rra&s 3f ,ore Than 3ne 8imension:
7rra&s and Nested oops:
Example %$:
3utput of !ame of ife:
0nitialiCing 7rra&s:
7rra&s and Pointers:
7rra&s as Parameters:
@uestions ():
Node:>h& use arra&sF, Next:imits and The 8imension of an arra&,
Previous:7rra&s, Up:7rra&s
6&1 use arra1s=
7rra&s are most useful when the& have a large num/er of elements: that is, in cases
where it would /e completel& impractical to have a different name for ever&
storage space in the memor&" 0t is then highl& /eneficial to move over to arra&s for
storing information for two reasons:
The storage spaces in arra&s have indicies" These num/ers can often /e
related to varia/les in a pro/lem and so there is a logical connection to /e
made /etween an arra& an a program"
0n C, arra&s can /e initialiCed ver& easil& indeed" 0t is far easier to initialiCe
an arra& than it is to initialiCe twent& or so varia/les"
The first of these reasons is pro/a/l& the most important one, as far as C is
concerned, since information can /e stored in other wa&s with e<uall& simple
initialiCation facilities in C" 3ne example of the use of an arra& might /e in ta-ing
a census of the t&pes of car passing on a road" .& defining macros for the names of
the different cars, the& could easil& /e lin-ed to the elements in an arra&"
3ype 1rray Blement
car @
auto #
%il $
The arra& could then /e used to store the num/er of cars of a given t&pe which had
driven past" e"g"
)***********************************************)
)* *)
)* Densus *)
)* *)
)***********************************************)
-include .stdio.h/
-define NG3LN+HB< #
-define D1R @
-define 1U3G #
-define 9E $
)************************************************)
main ()
0 int typeX5Y;
int index;
for (index = @; index . 5; indexPP)
0
typeXindexY = @;
A
while (NG3LN+HB<)
0
printf (&Bnter type num%er @(#( or $&);
scanf (&'d&( Mindex);
s6ipgar%();
typeXindexY P= #; )* +ee text %elow *)
A
A
This program, first of all, initialiCes the elements of the arra& to /e Cero" 0t then
enters a loop which repeatedl& fetches a num/er from the user and increases the
value stored in the arra& element, la/elled /& that num/er, /& (" The effect is to
count the cars as the& go past" This program is actuall& not a ver& good program
for two reasons in particular:
4irstl&, it does not chec- that the num/er which the user t&ped is actuall&
one of the elements of the arra&" (6ee the section /elow a/out this")
The loop goes on for ever and the program never gives up the information
which is stores" 0n short: it is not ver& useful"
7nother example, which comes readil& to mind, would /e the use of a two
dimensional arra& for storing the positions of chess pieces in a chess game" Two
dimensional arra&s have a chess/oard=li-e structure alread& and the& re<uire two
num/ers (two indicies) to pinpoint a particular storage cell" This is Aust li-e the
num/ers on chess /oard, so there is an immediate and logical connection /etween
an arra& and the pro/lem of -eeping trac- of the pieces on a chess /oard" 7rra&s
pla& an important role in the handling of string varia/les" 6trings are important
enough to have a section of their own, 6ee 6trings"
Node:imits and The 8imension of an arra&, Next:7rra&s and for loops,
Previous:>h& use arra&sF, Up:7rra&s
'imits an$ T&e -imension of an arra1
C does not do much hand holding" 0t is invaria/l& up to the programmer to ma-e
sure that programs are free from errors" This is especiall& true with arra&s" C does
not complain if &ou tr& to write to elements of an arra& which do not exist; 4or
example:
char arrayX8Y;
is an arra& with H elements" 0f &ou wrote:
arrayX;Y = "*";
C would happil& tr& to write the character * at the location which would have
corresponded to the seventh element, had it /een declared that wa&" Unfortunatel&
this would pro/a/l& /e memor& ta-en up /& some other varia/le or perhaps even
/& the operating s&stem" The result would /e either:
The value in the incorrect memor& location would /e corrupted with
unpredicta/le conse<uences"
The value would corrupt the memor& and crash the program completel&; 3n
Unix s&stems this leads to a memor& segmentation fault"
The second of these tends to /e the result on operating s&stems with proper
memor& protection" >riting over the /ounds of an arra& is a common source of
error" 1emem/er that the arra& limits run from Cero to the siCe of the arra& minus
one"
Node:7rra&s and for loops, Next:Example (), Previous:imits and The 8imension
of an arra&, Up:7rra&s
8rra1s an$ for loo*s
7rra&s have a natural partner in programs: the for loop" The for loop provides a
simple wa& of counting through the num/ers of an index in a controlled wa&"
Consider a one dimensional arra& called array" 7 for loop can /e used to initialiCe
the arra&, so that all its elements contain Cero:
-define +FB #@;
main ()
0 int i( arrayX+FBY;
for (i = @; i . +FB; iPP)
0
arrayXiY = @;
A
A
0t could e<uall& well /e used to fill the arra& with different values" Consider:
-define +FB #@;
main ()
0 int i( arrayXsiNeY;
for (i = @; i . siNe; iPP)
0
arrayXiY = i;
A
A
This fills each successive space with the num/er of its index:
index @ # $ 5 7 8 : ; = >
---------------------------------------
element Q @ Q # Q $ Q 5 Q 7 Q 8 Q : Q ; Q = Q > Q
contents ---------------------------------------
The for loop can /e used to wor- on an arra& se<uentiall& at an& time during a
program, not onl& when it is /eing initialiCed" The example listing /elow shows an
example of how this might wor- for a one dimensional arra&, called an
Eratosthenes sieve" This sieve is an arra& which is used for weeding out prime
num/ers, that is: num/ers which cannot /e divided /& an& num/er except (
without leaving a remainder or a fraction" 0t wor-s /& filling an arra& with num/ers
from $ to some maximum value in the same wa& that was shown a/ove and then
/& going through the num/ers in turn and deleting (setting e<ual to Cero) ever&
multiple of ever& num/er from the arra&" This eliminates all the num/ers which
could /e divided /& something exactl& and leaves onl& the prime num/ers at the
end" Tr& to follow the listing /elow"
Node:Example (), Next:7rra&s 3f ,ore Than 3ne 8imension, Previous:7rra&s
and for loops, Up:7rra&s
+/am*le 'isting
)******************************************************)
)* *)
)* ,rime Num%er +ie4e *)
)* *)
)******************************************************)
-include .stdio.h/
-define +FB 8@@@
-define <BEB3B< @
)*******************************************************)
)* Ee4el @ *)
)*******************************************************)
main ()
0 short sie4eX+FBY;
printf (&Bratosthenes +ie4e 2n2n&);
Lill+ei4e(sie4e);
+ort,rimes(sie4e);
,rint,rimes(sie4e);
A
)*********************************************************)
)* Ee4el # *)
)*********************************************************)
Lill+ei4e (sie4e) )* Lill with integers *)
short sie4eX+FBY;
0 short i;
for (i = $; i . +FB; iPP)
0
sie4eXiY = i;
A
A
)**********************************************************)
+ort,rimes (sie4e) )* <elete non primes *)
short sie4eX+FBY;
0 short i;
for (i = $; i . +FB; iPP)
0
if (sie4eXiY == <BEB3B<)
0
continue;
A
<eleteJultiplesGf(i(sie4e);
A
A
)***********************************************************)
,rint,rimes (sie4e) )* ,rint out array *)
short sie4eX+FBY;
0 short i;
for (i = $; i . +FB; iPP)
0
if (sie4eXiY == <BEB3B<)
0
continue;
A
else
0
printf (&'8d&(sie4eXiY);
A
A
A
)***********************************************************)
)* Ee4el $ *)
)***********************************************************)
<eleteJultiplesGf (i(sie4e) )* <elete.. of an integer *)
short i(sie4eX+FBY;
0 short U( mult = $;
for (U = i*$; U . +FB; U = i * (multPP))
0
sie4eXUY = <BEB3B<;
A
A
)* end *)
Node:7rra&s 3f ,ore Than 3ne 8imension, Next:7rra&s and Nested oops,
Previous:Example (), Up:7rra&s
8rra1s 0f More T&an 0ne -imension
There is no limit, in principle, to the num/er of indicies which an arra& can have"
(Though there is a limit to the amount of memor& availa/le for their storage") 7n
arra& of two dimensions could /e declared as follows:
float num%ersX+FBYX+FBY;
+FB is some constant" (The siCes of the two dimensions do not have to /e the
same") This is called a two dimensional arra& /ecause it has two indicies, or two
la/els in s<uare /rac-ets" 0t has (+FB N +FB) or siCe=s<uared elements in it,
which form an imaginar& grid, li-e a chess /oard, in which ever& s<uare is a
varia/le or storage area"
------------------------------------
Q @ Q # Q $ Q 5 Q 7 Q 8 Q : Q ; Q = Q ... (up to +FB)
------------------------------------
Q # Q Q Q Q Q Q Q Q Q
------------------------------------
Q $ Q Q Q Q Q Q Q Q Q
------------------------------------
Q 5 Q Q Q Q Q Q Q Q Q
------------------------------------
Q 7 Q Q Q Q Q Q Q Q Q
------------------------------------
Q 8 Q Q Q Q Q Q Q Q Q
------------------------------------
Q : Q Q Q Q Q Q Q Q Q
------------------------------------
Q ; Q Q Q Q Q Q Q Q Q
------------------------------------
.
.
(up to +FB)
Ever& element in this grid needs two indicies to pin=point it" The elements are
accessed /& giving the coordinates of the element in the grid" 4or instance to set
the element %,G to the value (%, one would write:
arrayX$YX5Y = #$;
The usual terminolog& for the two indicies is that the first gives the row num/er in
the grid and that the second gives the column num/er in the grid" (1ows go along,
columns hold up the ceiling") 7n arra& cannot /e stored in the memor& as a grid:
computer memor& is a one dimensional thing" 7rra&s are therefore stored in rows"
The following arra&:
------------
Q # Q $ Q 5 Q
------------
Q 7 Q 8 Q : Q
------------
Q ; Q = Q > Q
------------
would /e stored:
------------------------------------
Q # Q $ Q 5 Q 7 Q 8 Q : Q ; Q = Q > Q
------------------------------------
* RG? - # * RG? - $ * RG? -5 *
7nother wa& of sa&ing that arra&s are stored row=wise is to sa& that the second
index varies fastest, /ecause a two=dimensional arra& is alwa&s thought of as"""
arrayXrowYXcolumnY
so for ever& row stored, there will /e lots of columns inside that row" That means
the column index goes from $""+FB inside ever& row, so it is changing faster as
the line of storage is followed"
7 three dimensional arra&, li-e a cu/e or a cu/oid, could also /e defined in the
same -ind of wa&:
dou%le cu%eX+FBYX+FBYX+FBY;
or with different limits on each dimension:
short notcu%icX$YX:YX=Y;
Three dimensional arra&s are stored according to the same pattern as two
dimensional arra&s" The& are -ept in computer memor& as a linear se<uence of
varia/le stores and the last index is alwa&s the one which varies fastest"
Node:7rra&s and Nested oops, Next:Example %$, Previous:7rra&s 3f ,ore Than
3ne 8imension, Up:7rra&s
8rra1s an$ ;este$ 'oo*s
7rra&s of more than one dimension are usuall& handled /& nested for loops" 7 two
dimensional arra& might /e initialiCed in the following wa&:
main ()
0 int i(U;
float arrayX+FB#YX+FB$Y;
for (i = @; i . +FB#; iPP)
0
for (U = @; U . +FB$; UPP)
0
arrayXiYXUY = @;
A
A
A
0n three dimensions, three nested loops would /e needed:
main ()
0 int i(U(6;
float arrayX+FB#YX+FB$YX+FB5Y;
for (i = @; i . +FB#; iPP)
0
for (U = @; U . +FB$; UPP)
0
for (6 = @; 6 . +FB5; 6PP)
0
arrayXiYXUYX6Y = @;
A
A
A
A
7n example program helps to show how this happens in practice" The example
/elow demonstrates the so=called D!ame of ifeD" The aim is to mimic something
li-e cell reproduction /& appl&ing some rigid rules to a pattern of dots . and stars
*" 7 dot is a place where there is no life (as we -now it;) and a star is a place in
which there is a living thing" The rules will /e clear from the listing" Things to
notice are the wa& the program traverses the arra&s and the wa& in which it chec-s
that it is not overstepping the /oundaries of the arra&s"
Node:Example %$, Next:3utput of !ame of ife, Previous:7rra&s and Nested
oops, Up:7rra&s
+/am*le 'isting
)*********************************************************)
)* *)
)* Rame of Eife *)
)* *)
)*********************************************************)
)* 9ased upon an article from +cientific 1merican *)
)* in #>;@. +imulates the reproduction of cells *)
)* which depend on one another. 3he rules are *)
)* that cells will only sur4i4e if they ha4e a *)
)* certain num%er of neigh%ours to support them *)
)* %ut not too many( or there won"t %e enough *)
)* foodI *)
-include .stdio.h/
-define +FB $@
-define J1CNUJ #8
-define N9GUN<+ (a/=@)MM(a.+FB)MM(%/=@)MM(%.+FB)
-define NGRB+,GN+B #
)*********************************************************)
)* Ee4el @ *)
)*********************************************************)
main ()
0 int countX+FBYX+FBY;
char arrayX+FBYX+FBY;
int generation = @;
printf (&Rame of Eife2n2n2n&);
nitialiNe1rray(array);
while (NGRB+,GN+B)
0
DountNeigh%ours(array(count);
9uildNextReneration(array(count);
Update<isplay(array(PPgeneration);
printf (&2n2n] for Ouit. RB3URN to continue.2n&);
if(Ouit()) %rea6;
A
A
)**********************************************************)
)* Ee4el # *)
)**********************************************************)
nitialiNe1rray (array) )* Ret starting conditions *)
char arrayX+FBYX+FBY;
0 int i(U;
char ch;
printf (&2nBnter starting setup. 3ype "." for empty&);
printf (&2nand any other character for occupied.2n&);
printf (&RB3URN after each line.2n2n&);
printf (&1rray siNe guide:2n2n&);
for (i=@; iPP . +FB; printf(&'c&("Z"));
printf (&2n2n&);
for (i = @; i . +FB; iPP)
0
for (U = @; U . +FB; UPP)
0
scanf (&'c&(Mch);
if (ch == ".")
0
arrayXiYXUY = ".";
A
else
0
arrayXiYXUY = "*";
A
A
s6ipgar%();
A
printf (&2n2nnput is complete. ,ress RB3URN.&);
s6ipgar%();
A
)********************************************************)
DountNeigh%ours (array(count) )* count all neigh%ours *)
char arrayX+FBYX+FBY;
int countX+FBYX+FBY;
0 int i(U;
for (i = @; i . +FB; iPP)
0
for (U = @; U . +FB; UPP)
0
countXiYXUY = numali4e(array(i(U);
A
A
A
)*******************************************************)
9uildNextReneration (array(count)
)* 1 cell will sur4i4e if it has two or three *)
)* neigh%ours. New life will %e %orn to a dead *)
)* cell if there are exactly three neigh%ours *)
char arrayX+FBYX+FBY;
int countX+FBYX+FBY;
0 int i(U;
for (i = @; i . +FB; iPP)
0
for (U = @; U . +FB; UPP)
0
if (arrayXiYXUY == "*")
0
switch (countXiYXUY)
0
case $ :
case 5 : continue;
default: arrayXiYXUY = ".";
%rea6;
A
A
else
0
switch (countXiYXUY)
0
case 5 : arrayXiYXUY = "*";
%rea6;
default: continue;
A
A
A
A
A
)*******************************************************)
Update<isplay (array(g) )* print out life array *)
char arrayX+FBYX+FBY;
int g;
0 int i(U;
printf (&2n2nReneration 'd2n2n&(g);
for (i = @; i . +FB; iPP)
0
for (U = @; U . +FB; UPP)
0
printf(&'c&(arrayXiYXUY);
A
printf(&2n&);
A
A
)*******************************************************)
)* Ee4el $ *)
)*******************************************************)
numali4e (array(i(U)
)* <on"t count arrayXi(UY : only its neigh%ours *)
)* 1lso chec6 that ha4en"t reached the %oundary *)
)* of the array *)
char arrayX+FBYX+FBY;
int i(U;
0 int a(%(census;
census = @;
for (a = (i-#); (a .= (iP#)); aPP)
0
for (% = (U-#); (% .= (UP#)); %PP)
0
if (N9GUN<+ MM (arrayXaYX%Y == "*"))
0
censusPP;
A
A
A
if (arrayXiYXUY == "*") census--;
return (census);
A
)********************************************************)
)* 3ool6it input *)
)********************************************************)
Ouit()
0 char ch;
while (NGRB+,GN+B)
0
scanf (&'c&(Mch);
if (ch I= "2n") s6ipgar%();
switch (ch)
0
case "O" : case "]" : return (#);
default : return (@);
A
A
A
)********************************************************)
s6ipgar% ()
0
while (getchar() I= "2n")
0
A
A
Node:3utput of !ame of ife, Next:0nitialiCing 7rra&s, Previous:Example %$,
Up:7rra&s
0ut*ut of :ame of 'ife
Rame of Eife
Bnter starting setup. 3ype "." for empty
and any other character for occupied.
RB3URN after each line.
1rray +FB guide:
ZZZZZZZZZZZZZZZZZZZZ
(user types in: (t doesn"t matter if the input
.................... spills o4er the +FB guide(
.................... %ecause &s6ipgar%()& discards it.)
.....................
.....................
.....................
..........***........
...........*.........
......................
.....................
.....................
.....................
*********************
.....................
......................
....................
.....................
......................
......................
......................
...................... )
nput is complete. ,ress RB3URN.
Reneration #
....................
....................
....................
....................
...........*........
..........***.......
..........***.......
....................
....................
....................
.******************.
.******************.
.******************.
....................
....................
....................
....................
....................
....................
....................
] for Ouit. RB3URN to continue.
Reneration $
....................
....................
....................
....................
..........***.......
....................
..........*.*.......
...........*........
....................
..****************..
.*................*.
*..................*
.*................*.
..****************..
....................
....................
....................
....................
....................
....................
] for Ouit. RB3URN to continue.
Reneration 5
....................
....................
....................
...........*........
...........*........
..........*.*.......
...........*........
...........*........
...*******...****...
..****************..
.******************.
**................**
.******************.
..****************..
...**************...
....................
....................
....................
....................
....................
] for Ouit. RB3URN to continue.
Reneration 7
....................
....................
....................
....................
..........***.......
..........*.*.......
..........***.......
....*****.*.*.**....
..*..............*..
.*................*.
*..................*
*..................*
*..................*
.*................*.
..*..............*..
....************....
....................
....................
....................
....................
] for Ouit. RB3URN to continue.
etc""" Tr& experimenting with different starting patterns"
Node:0nitialiCing 7rra&s, Next:7rra&s and Pointers, Previous:3utput of !ame of
ife, Up:7rra&s
#nitiali7ing 8rra1s
7rra&s can /e initialiCed in two wa&s" The first wa& is /& assigning ever& element
to some value with a statement li-e:
arrayX$Y = 7$;
arrayX5Y = #$;
or perhaps with the aid of one or more for loops" .ecause it is tedious, to sa& the
least, not to mention uneconomical, to initialiCe the values of each element to as
different value, C provides another method, which emplo&s a single assignment
operator = and curl& /races 0 A" "his method only wor#s for static variables and
external variables.
1ecall that arra&s are stored row=wise or with the last index var&ing fastest" 7 G /&
G arra& could /e initialiCed in the following wa&:
static int arrayX5YX5Y =
0
0#@($5(7$A(
0#(:87(@A(
07@:8$($$(@A
A;
The internal /races are unnecessar&, /ut help to distinguish the rows from the
columns" The same thing could /e written:
int arrayX5YX5Y =
0
#@($5(7$(
#(:87(@
7@:8$($$(@
A;
Ta-e care to include the semicolon at the end of the curl& /race which closes the
assignment"
Note that, if there are not enough elements in the curl& /races to account for ever&
single element in an arra&, the remaining elements will /e filled out with Ceros"
6tatic varia/les are alwa&s guaranteed to /e initialiCed to Cero an&wa&, whereas
auto or local varia/les are guaranteed to /e gar/age: this is /ecause static storage is
created /& the compiler in the /od& of a program, whereas auto or local storage is
created at run time"
Node:7rra&s and Pointers, Next:7rra&s as Parameters, Previous:0nitialiCing
7rra&s, Up:7rra&s
8rra1s an$ Pointers
The information a/out how arra&s are stored was not included Aust for interest"
There is another wa& of loo-ing at arra&s which follows the .CP idea of an arra&
as simpl& a /loc- of memor&" 7n arra& can /e accessed with pointers as well as
with XY s<uare /rac-ets"
"he name of an array variable, standing alone, is actually a pointer to the first
element in the array.
4or example: if an arra& is declared
float num%ersX57Y;
then num%ers is a pointer to the first floating point num/er in the arra&B num%ers
is a pointer in its own right" (0n this case it is t&pe Ipointer to float:") 6o the first
element of the arra& could /e accessed /& writing:
num%ersX@Y = $$.5;
or /& writing
*num%ers = $$.5;
4or character arra&s, which are dealt with in some depth in chapter %$, this gives
an alternative wa& of getting at the elements in the arra&"
char arraynameX8Y;
char *ptr;
for (ptr = arrayname; ptr .= arraynameP7; ptrPP)
0
*ptr = @;
A
The code a/ove sets the arra& arrayname to Cero" This method of getting at arra&
data is not recommended /& this author except in ver& simple computer
environments" 0f a program is running on a normal microcomputer, then there
should /e few pro/lems with this alternative method of handling arra&s" 3n the
hand, if the microcomputer is multi=tas-ing, or the program is running on a larger
s&stem which has a limited manager, then memor& ceases to /e something which
can /e thought of as a se<uence of /oxes standing next to one another" 7 multi=
tas-ing s&stem shares memor& with other programs and it ta-es what it can find,
where it can find it" The upshot of this is that it is not possi/le to guarantee that
arra&s will /e stored in one simple string of memor& locations: it might /e
scattered around in different places" 6o
ptr = arrayname P 8;
might not /e a pointer to the fifth character in a character arra&" This could /e
found instead using the M operator" 7 pointer to the fifth element can /e relia/l&
found with:
ptr = M(arraynameX8Y);
.e warned;
Node:7rra&s as Parameters, Next:@uestions (), Previous:7rra&s and Pointers,
Up:7rra&s
8rra1s as Parameters
>hat happens if we want to pass an arra& as a parameterF 8oes the program cop&
the entire arra& into local storageF The answer is no /ecause it would /e a waste of
time and memor&" 7rra&s can /e passed as parameters, /ut onl& as varia/le ones"
This is a simple matter, /ecause the name of the arra& is a pointer to the arra&" The
!ame of ife program a/ove does this" Notice from that program how the
declarations for the parameters are made"
main ()
0
char arrayX$5Y;
function (array);
.....
A
function (arrayformal)
char arrayformalX$5Y;
0
A
7n& function which writes to the arra&, passed as a parameter, will affect the
original cop&" 7rra& parameters are alwa&s varia/le parameters
Node:@uestions (), Previous:7rra&s as Parameters, Up:7rra&s
.uestions
(" !iven an& arra&, how would &ou find a pointer to the start of itF
%" 9ow do &ou pass an arra& as a parameterF >hen the parameter is received
/& a function does C allocate space for a local varia/le and cop& the whole
arra& to the new locationF
G" >rite a statement which declares an arra& of t&pe dou/le which measures #
/& H" >hat num/ers can /e written in the indicies of the arra&F
Node:6trings, Next:Putting together a program, Previous:7rra&s, Up:Top
4trings
Communication with arrays.
6trings are pieces of text which can /e treated as values for varia/les" 0n C a string
is represented as some characters enclosed /& dou/le <uotes"
&3his is a string&
7 string ma& contain an& character, including special control characters, such as
2n, 2r, 2; etc"""
&9eepI 2; Newline 2n...&
Conventions and 8eclarations:
6trings 7rra&s and Pointers:
7rra&s of 6trings:
Example %(:
6trings from the user:
9andling strings:
Example %%:
6tring 0nputE3utput:
Example %G:
@uestions %$:
Node:Conventions and 8eclarations, Next:6trings 7rra&s and Pointers,
Previous:6trings, Up:6trings
Conventions an$ -eclarations
There is an important distinction /etween a string and a single character in C" The
convention is that single characters are enclosed /& single <uotes e"g" * and have
the t&pe char" 6trings, on the hand, are enclosed /& dou/le <uotes e"g"
&string...& and have the t&pe Dpointer to charD (char *) or arra& of char" 9ere
are some declarations for strings which are given without immediate explanations"
)**********************************************************)
)* *)
)* +tring <eclaration *)
)* *)
)**********************************************************)
-define +FB #@
char *glo%alKstring#;
char glo%alKstring$X+FBY;
main ()
0 char *autoKstring;
char arraystrX+FBY;
static char *statKstrng;
static char statarraystrX+FBY;
A
Node:6trings 7rra&s and Pointers, Next:7rra&s of 6trings, Previous:Conventions
and 8eclarations, Up:6trings
4trings" 8rra1s an$ Pointers
7 string is reall& an arra& of characters" 0t is stored at some place the memor& and
is given an end mar-er which standard li/rar& functions can recogniCe as /eing the
end of the string" The end mar-er is called the Cero (or NUEE) /&te /ecause it is Aust
a /&te which contains the value Cero: 2@" Programs rarel& gets to see this end
mar-er as most functions which handle strings use it or add it automaticall&"
6trings can /e declared in two main wa&sB one of these is as an arra& of characters,
the other is as a pointer to some pre=assigned arra&" Perhaps the simplest wa& of
seeing how C stores arra&s is to give an extreme example which would pro/a/l&
never /e used in practice" Thin- of how a string called string might /e used to to
store the message DTedious;D" The fact that a string is an arra& of characters might
lead &ou to write something li-e:
-define EBNR3H >;
main ()
0 char stringXEBNR3HY;
stringX@Y = "3";
stringX#Y = "e";
stringX$Y = "d";
stringX5Y = "i";
stringX7Y = "o";
stringX8Y = "u";
stringX:Y = "s";
stringX;Y = "I";
stringX=Y = "2@";
printf (&'s&( string);
A
This method of handling strings is perfectl& accepta/le, if there is time to waste,
/ut it is so la/orious that C provides a special initialiCation service for strings,
which /&passes the need to assign ever& single character with a new assignment;"
There are six wa&s of assigning constant strings to arra&s" (7 constant string is one
which is actuall& t&ped into the program, not one which in t&ped in /& the user")
The& are written into a short compila/le program /elow" The explanation follows"
)**********************************************************)
)* *)
)* +tring nitialiNation *)
)* *)
)**********************************************************)
char *glo%alKstring# = &1 string declared as a pointer&;
char glo%alKstring$XY = &<eclared as an array&;
main ()
0 char *autoKstring = &initialiNer...&;
static char *statKstrng = &initialiNer...&;
static char statarraystrXY = &initialiNer....&;
)* char arraystrXY = &initialiNer....&; + EEBR1EI *)
)* 3his is %ecause the array is an &auto& type *)
)* which cannot %e preinitialiNed( %ut... *)
char arraystrX$@Y;
printf (&'s 's&( glo%alKstring#( glo%alKstring$);
printf (&'s 's 's&( autoKstring( statKstrng( statarraystr);
A
)* end *)
The details of what goes on with strings can /e difficult to get to grips with" 0t is a
good idea to get revise pointers and arra&s /efore reading the explanations /elow"
Notice the diagrams too: the& are pro/a/l& more helpful than words"
The first of these assignments is a glo/al, static varia/le" ,ore correctl&, it is a
pointer to a glo/al, static arra&" 6tatic varia/les are assigned storage space in the
/od& of a program when the compiler creates the executa/le code" This means that
the& are saved on dis- along with the program code, so the& can /e initialiCed at
compile time" That is the reason for the rule which sa&s that onl& static arra&s can
/e initialiCed with a constant expression in a declaration" The first statement
allocates space for a pointer to an arra&" Notice that, /ecause the string which is to
/e assigned to it, is t&ped into the program, the compiler can also allocate space for
that in the executa/le file too" 0n fact the compiler stores the string, adds a Cero
/&te to the end of it and assigns a pointer to its first character to the varia/le called
glo%alKstring#"
The second statement wor-s almost identicall&, with the exception that, this time
the compiler sees the declaration of a static arra&, which is to /e initialiCed" Notice
that there is no siCe declaration in the s<uare /rac-ets" This is <uite legal in fact:
the compiler counts the num/er of characters in the initialiCation string and
allocates Aust the right amount of space, filling the string into that space, along with
its end mar-er as it goes" 1emem/er also that the name of the arra& is a pointer to
the first character, so, in fact, the two methods are identical"
The third expression is the same -ind of thing, onl& this time, the declaration is
inside the function main() so the t&pe is not static /ut auto" The difference
/etween this and the other two declarations is that this pointer varia/le is created
ever& time the function main() is called" 0t is new each time and the same thing
holds for an& other function which it might have /een defined in: when the
function is called, the pointer is created and when it ends, it is destro&ed" The string
which initialiCes it is stored in the executa/le file of the program (/ecause it is
t&ped into the text)" The compiler returns a value which is a pointer to the string:s
first character and uses that as a value to initialiCe the pointer with" This is a
slightl& round a/out wa& of defining the string constant" The normal thing to do
would /e to declare the string pointer as /eing static, /ut this is Aust a matter of
st&le" 0n fact this is what is done in the fourth example"
The fifth example is again identical, in practice to other static t&pes, /ut is written
as an Iopen: arra& with an unspecified siCe"
The sixth example is for/idden; The reason for this might seem rather trivial, /ut it
is made in the interests of efficienc&" The arra& declared is of t&pe auto: this means
that the whole arra& is created when the function is called and destro&ed
afterwards" auto=arra&s cannot /e initialiCed with a string /ecause the& would have
to /e re=initialiCed ever& time the arra& were created: that is, each time the function
were called" The final example could /e used to overcome this, if the programmer
were inclined to do so" 9ere an auto arra& of characters is declared (with a siCe this
time, /ecause there is nothing for the compiler to count the siCe of)" There is no
single assignment which will fill this arra& with a string though: the programmer
would have to do it character /& character so that the inefficienc& is made as plain
as possi/le;
Node:7rra&s of 6trings, Next:Example %(, Previous:6trings 7rra&s and Pointers,
Up:6trings
8rra1s of 4trings
0n the previous chapter we progressed from one dimensional arra&s to two
dimensional arra&s, or arra&s of arra&s; The same thing wor-s well for strings
which are declared static" Programs can ta-e advantage of C:s eas& assignment
facilities to let the compiler count the siCe of the string arra&s and define arra&s of
messages" 4or example here is a program which prints out a menu for an
application program:
)*********************************************************)
)* *)
)* JBNU : program which prints out a menu *)
)* *)
)*********************************************************)
main ()
0 int strKnum%er;
for (strKnum%er = @; strKnum%er . #5; strKnum%erPP)
0
printf (&'s&(menutext(strKnum%er));
A
A
)*********************************************************)
char *menutext(n) )* return n-th string ptr *)
int n;
0
static char *tXY =
0
& -------------------------------------- 2n&(
& Q PP JBNU PP Q2n&(
& Q [[[[[[[[[[[[ Q2n&(
& Q (#) Bdit <efaults Q2n&(
& Q ($) ,rint Dharge +heet Q2n&(
& Q (5) ,rint Eog +heet Q2n&(
& Q (7) 9ill Dalculator Q2n&(
& Q (O) ]uit Q2n&(
& Q Q2n&(
& Q Q2n&(
& Q ,lease Bnter Dhoice Q2n&(
& Q Q2n&(
& -------------------------------------- 2n&
A;
return (tXnY);
A
Notice the wa& in which the static declaration wor-s" 0t is initialiCed once at
compile time, so there is effectivel& onl& one statement in this function and that is
the return statement" This function retains the pointer information from call to call"
The ,orse coder program could /e rewritten more economicall& using static
strings, 6ee Example (H"
Node:Example %(, Next:6trings from the user, Previous:7rra&s of 6trings,
Up:6trings
+/am*le 'isting
)************************************************)
)* *)
)* static string array *)
)* *)
)************************************************)
)* Jorse code program. Bnter a num%er and *)
)* find out what it is in Jorse code *)
-include .stdio.h/
-define DG<B @
)*************************************************)
main ()
0 short digit;
printf (&Bnter any digit in the range @..>&);
scanf (&'h&(Mdigit);
if ((digit . @) QQ (digit / >))
0
printf (&Num%er was not in range @..>&);
return (DG<B);
A
printf (&3he Jorse code of that digit is &);
Jorse (digit);
A
)************************************************)
Jorse (digit) )* print out Jorse code *)
short digit;
0
static char *codeXY =
0
&dummy&( )* index starts at @ *)
&-----&(
&.----&(
&..---&(
&...--&(
&....-&(
&.....&(
&-....&(
&--...&(
&---..&(
&----.&(
A;
printf (&'s2n&(codeXdigitY);
A
Node:6trings from the user, Next:9andling strings, Previous:Example %(,
Up:6trings
4trings from t&e user
7ll the strings mentioned so far have /een t&ped into a program /& the
programmer and stored in a program file, so it has not /een necessar& to worr&
a/out where the& were stored" 3ften though we would li-e to fetch a string from
the user and store it somewhere in the memor& for later use" 0t might even /e
necessar& to get a whole /unch of strings and store them all" .ut how will the
program -now in advance how much arra& space to allocate to these stringsF The
answer is that it won:t, /ut that it doesn:t matter at all;
3ne wa& of getting a simple, single string from the user is to define an arra& and to
read the characters one /& one" 7n example of this was the !ame of ife program
the the previous chapter:
8efine the arra& to /e a certain siCe
Chec- that the user does not t&pe in too man& characters"
Use the string in that arra&"
7nother wa& is to define a static string with an initialiCer as in the following
example" The function filename() as-s the user to t&pe in a filename, for loading
or saving /& and return it to a calling function"
char *filename()
0 static char *filenm = &........................&;
do
0
printf (&Bnter filename :&);
scanf (&'$7s&(filenm);
s6ipgar%();
A
while (strlen(filenm) == @);
return (filenm);
A
The string is made static and given an initialiCing expression and this forces the
compiler to ma-e some space for the string" 0t ma-es exactl& %# characters plus a
Cero /&te in the program file, which can /e used /& an application" Notice that the
conversion string in scanf prevents the characters from spilling over the /ounds of
the string" The function strlen() is a standard li/rar& function which is descri/ed
/elowB it returns the length of a string" s6ipgar%() is the function which was
introduced in chapter (H"
Neither of the methods a/ove is an& good if a program is going to /e fetching a lot
of strings from a user" 0t Aust isn:t practical to define lots of static strings and expect
the user to t&pe into the right siCe /oxes; The next step in string handling is
therefore to allocate memor& for strings personall&: in other words to /e a/le to sa&
how much storage is needed for a string while a program is running" C has special
memor& allocation functions which can do this, not onl& for strings /ut for an&
-ind of o/Aect" 6uppose then that a program is going to get ten strings from the
user" 9ere is one wa& in which it could /e done:
(" 8efine one large, static string (or arra&) for getting one string at a time" Call
this a string /uffer, or waiting place"
%" 8efine an arra& of ten pointers to characters, so that the strings can /e
recalled easil&"
G" 4ind out how long the string in the string /uffer is"
#" 7llocate memor& for the string"
H" Cop& the string from the /uffer to the new storage and place a pointer to it in
the arra& of pointers for reference"
M" 1elease the memor& when it is finished with"
The function which allocates memor& in C is called malloc() and it wor-s li-e
this:
malloc() should /e declared as returning the t&pe pointer to character, with
the statement:
char *malloc();

malloc() ta-es one argument which should /e an unsigned integer value


telling the function how man& /&tes of storage to allocate" 0t returns a
pointer to the first memor& location in that storage:
char *ptr;
unsigned int siNe;

ptr = malloc(siNe);

The pointer returned has the value NUEE if there was no memor& left to
allocate" This should alwa&s /e chec-ed"
The fact that malloc() alwa&s returns a pointer to a character does not stop it from
/eing used for other t&pes of data too" The cast operator can force malloc() to
give a pointer to an& data t&pe" This method is used for /uilding data structures in
C with DstructD t&pes"
malloc() has a complementar& function which does precisel& the opposite: de=
allocates memor&" This function is called free()" free() returns an integer code,
so it does not have to /e declared as /eing an& special t&pe"
free() ta-es one argument: a pointer to a /loc- of memor& which has
previousl& /een allocated /& malloc()"
int returncode;

returncode = free (ptr);

The pointer should /e declared:


char *ptr;

The return code is Cero if the release was successful"


7n example of how strings can /e created using malloc() and free() is given
/elow" 4irst of all, some explanation of 6tandard i/rar& 4unctions is useful to
simplif& the program"
Node:9andling strings, Next:Example %%, Previous:6trings from the user,
Up:6trings
%an$ling strings
The C 6tandard i/rar& commonl& provides a num/er of ver& useful functions
which handle strings" 9ere is a short list of some common ones which are
immediatel& relevant (more are listed in the following chapter)" Chances are, a
good compiler will support a lot more than those listed /elow, /ut, again, it reall&
depends upon the compiler"
strlen()
This function returns a t&pe int value, which gives the length or num/er of
characters in a string, not including the NUEE /&te end mar-er" 7n example
is:
int len;
char *string;
len = strlen (string);
strcpy()
This function copies a string from one place to another" Use this function in
preference to custom routines: it is set up to handle an& peculiarities in the
wa& data are stored" 7n example is
char *to(*from;
to = strcpy (to(from);
>here to is a pointer to the place to which the string is to /e copied and
from is the place where the string is to /e copied from"
strcmp()
This function compares two strings and returns a value which indicates how
the& compared" 7n example:
int 4alue;
char *s#(*s$;
4alue = strcmp(s#(s$);
The value returned is $ if the two strings were identical" 0f the strings were
not the same, this function indicates the (76C00) alpha/etical order of the
two" s# / s$, alpha/eticall&, then the value is / @" 0f s# . s$ then the
value is . @" Note that num/ers come /efore letters in the 76C00 code
se<uence and also that upper case comes /efore lower case"
strstr()
Tests whether a su/string is present in a larger string
int n;
char *s#(*s$;
if (n = strstr(s#(s$))
0
printf(&s$ is a su%string of s#( starting at 'd&(n);
A
strncpy()
This function is li-e strcpy, /ut limits the cop& to no more than n
characters"
strncmp()
This function is li-e strcmp, /ut limits the comparison to no more than n
characters"
,ore string functions are descri/ed in the next section along with a host of
6tandard i/rar& 4unctions"
Node:Example %%, Next:6tring 0nputE3utput, Previous:9andling strings,
Up:6trings
+/am*le 'isting
This program aims to get ten strings from the user" The strings ma& not contain an&
spaces or white space characters" 0t wor-s as follows:
The user is prompted for a string which heEshe t&pes into a /uffer" The length of
the string is tested with strlen() and a /loc- of memor& is allocated for it using
malloc()" (Notice that this /loc- of memor& is one /&te longer than the value
returned /& strlen(), /ecause strlen() does not count the end of string mar-er
2@") malloc() returns a pointer to the space allocated, which is then stored in the
arra& called array" 4inall& the strings is copied from the /uffer to the new storage
with the li/rar& function strcpy()" This process is repeated for each of the ($
strings" Notice that the program exits through a low level function called
]uit+afely()" The reason for doing this is to exit from the program neatl&, while
at the same time remem/ering to perform all a programmer:s duties, such as de=
allocating the memor& which is no longer needed" ]uit+afely() uses the
function exit() which should /e provided as a standard li/rar& function" exit()
allows a program to end at an& point"
)******************************************************)
)* *)
)* +tring storage allocation *)
)* *)
)******************************************************)
-include .stdio.h/
)* -include another file for malloc() and *)
)* strlen() VVV. Dhec6 the compiler manualI *)
-define NGGL+3R #@
-define 9UL+FB $88
-define DG<B @
)******************************************************)
)* Ee4el @ *)
)******************************************************)
main ()
0 char *arrayXNGGL+3RY( *malloc();
char %ufferX9UL+FBY;
int i;
for (i = @; i . NGGL+3R; iPP)
0
printf (&Bnter string 'd :&(i);
scanf (&'$88s&(%uffer);
arrayXiY = malloc(strlen(%uffer)P#);
if (arrayXiY == NUEE)
0
printf (&Dan"t allocate memory2n&);
]uit+afely (array);
A
strcpy (arrayXiY(%uffer);
A
for (i = @; i . NGGL+3R; iPP)
0
printf (&'s2n&(arrayXiY);
A
]uit+afely(array);
A
)******************************************************)
)* +na6es M EaddersI *)
)******************************************************)
]uit+afely (array) )* ]uit M de-alloc memory *)
char *arrayXNGGL+3RY;
0 int i( len;
for (i = @; i . NGGL+3R; iPP)
0
len = strlen(arrayXiY) P #;
if (free (arrayXiY) I= @)
0
printf (&<e%ug: free failed2n&);
A
A
exit (DG<B);
A
)* end *)
Node:6tring 0nputE3utput, Next:Example %G, Previous:Example %%, Up:6trings
4tring #n*ut>0ut*ut
.ecause strings are recogniCed to /e special o/Aects in C, some special li/rar&
functions for reading and writing are provided for them" These ma-e it easier to
deal with strings, without the need for special user=routines" There are four of these
functions:
gets()
puts()
sprintf()
sscanf()
gets():
puts():
sprintf():
sscanf():
Node:gets(), Next:puts(), Previous:6tring 0nputE3utput, Up:6tring 0nputE3utput
gets()
This function fetches a string from the standard input file stdin and places it into
some /uffer which the programmer must provide"
-define +FB $88
char *sptr( %ufferX+FBY;
strptr = gets(%uffer);
0f the routine is successful in getting a string, it returns the value %uffer to the
string pointer strptr" 3therwise it returns NUEE (QQ$)" The advantage of gets()
over scanf(&'s&..) is that it will read spaces in strings, whereas scanf()
usuall& will not" gets() <uits reading when it finds a newline character: that is,
when the user presses RB3URN"
N3TE: there are valid concerns a/out using this function" 3ften it is implemented
as a macro with poor /ounds chec-ing and can /e exploited to produce memor&
corruption /& s&stem attac-ers" 0n order to write more secure code, use fgets()
instead"
Node:puts(), Next:sprintf(), Previous:gets(), Up:6tring 0nputE3utput
puts()
puts() sends a string to the output file stdout, until it finds a NUEE end of string
mar-er" The NUEE /&te is not written to stdout, instead a newline character is
written"
char *string;
int returncode;
returncode = puts(string);
puts() returns an integer value, whose value is onl& guaranteed if there is an error"
returncode == BGL if an end of file was encountered or there was an error"
Node:sprintf(), Next:sscanf(), Previous:puts(), Up:6tring 0nputE3utput
sprintf()
This is an interesting function which wor-s in almost the same wa& as printf(),
the exception /eing that it prints to a string; 0n other words it treats a string as
though it were an output file" This is useful for creating formatted strings in the
memor&" 3n most s&stems it wor-s in the following wa&:
int n;
char *sp;
n = sprintf (sp( &control string&( parameters( 4alues);
n is an integer which is the num/er of characters printed" sp is a pointer to the
destination string or the string which is to /e written to" Note carefull& that this
function does not perform an& chec- on the output string to ma-e sure that it is
long enough to contain the formatted output" 0f the string is not large enough, then
a crash could /e in store; This can also /e considered a potential securit& pro/lem,
since /uffer overflows can /e used to capture control of important programs" Note
that on s&stem 5 Unix s&stems the sprintf functionr returns a pointer to the start
of the printed string, /rea-ing the pattern of the other printf functions" To ma-e
such an implementation compati/le with the usual form &ou would have to write:
n = strlen(sprintf(parameters&&&&&&));
Node:sscanf(), Previous:sprintf(), Up:6tring 0nputE3utput
sscanf()
This function is the complement of sprintf()" 0t reads its input from a string, as
though it were an input file"
int n;
char *sp;
n = sscanf (sp(&control string&( pointers...);
sp is a pointer to the string which is to /e read from" The string must /e NUEE
terminated (it must have a Cero=/&te end mar-er :P$:)" sscanf() returns an integer
value which holds the num/er of items successfull& matched or BGL if an end of
file mar-er was read or an error occurred" The conversion specifiers are identical to
those for scanf()"
Node:Example %G, Next:@uestions %$, Previous:6tring 0nputE3utput, Up:6trings
+/am*le 'isting
)************************************************)
)* *)
)* Lormatted strings *)
)* *)
)************************************************)
)* program rewrites s# in re4erse into s$ *)
-include .stdio.h/
-define +FB $@
-define DG<B @
)************************************************)
main ()
0 static char *s# = &string $.5 88x&;
static char *s$ = &....................&;
char ch( *stringX+FBY;
int i(n;
float x;
sscanf (s#(&'s 'f 'd 'c&( string( Mx( Mi( Mch);
n = sprintf (s$(&'c 'd 'f 's&( ch( i( x( string);
if (n / +FB)
0
printf (&Brror: string o4erflowedI2n&);
exit (DG<B);
A
puts (s$);
A
Node:@uestions %$, Previous:Example %G, Up:6trings
.uestions
(" >hat are the two main wa&s of declaring strings in a programF
%" 9ow would &ou declare a static arra& of stringsF
G" >rite a program which gets a num/er /etween $ and ) and prints out a
different message for each num/er" Use a pre=initialiCed arra& to store the
strings"
Node:Putting together a program, Next:6pecial i/rar& 4unctions and ,acros,
Previous:6trings, Up:Top
Putting toget&er a *rogram
utting it all together.
argc and argv:
getopt:
envp:
Node:argc and argv, Next:getopt, Previous:Putting together a program, Up:Putting
together a program
T&e argument vector
C was written in order to implement Unix in a porta/le form" Unix was designed
with a command language which was /uilt up of independent programs" These
could /e passed arguments on the command line" 4or instance:
ls -l )etc
cc -o program prog.c
0n these examples, the first word is the command itself, while the su/se<uent
words are options and arguments to the command" >e need some wa& getting this
information into a C program" Unix solved this pro/lem /& passing C programs an
arra& of these arguments together with their num/er as parameters to the function
main()" 6ince then most other operating s&stems have adopted the same model,
since it has /ecome a part of the C language"
main (argc(arg4)
int argc;
char *arg4XY;
0
A
The traditional names for the parameters are the argument count argc and the
argument vector (arra&) arg4" The operating s&stem call which starts the C
program /rea-s up the command line into an arra&, where the first element
arg4X@Y is the name of the command itself and the last argument arg4Xargc-#Y
is the last argument" 4or example, in the case of
cc -o program prog.c
would result in the values
arg4X@Y
cc
arg4X#Y
=o
arg4X$Y
program
arg4X5Y
prog"c
The following program prints out the command line arguments:
main (argc(arg4)
int argc;
char *arg4XY;
0 int i;
printf (&3his program is called 's2n&(arg4X@Y);
if (argc / #)
0
for (i = #; i . argc; iPP)
0
printf(&arg4X'dY = 's2n&(i(arg4XiY);
A
A
else
0
printf(&Dommand has no arguments2n&);
A
A
Node:getopt, Next:envp, Previous:argc and argv, Up:Putting together a program
Processing o*tions
getopt
Node:envp, Previous:getopt, Up:Putting together a program
+nvironment varia)les
>hen we write a C program which reads command line arguments, the& are fed to
us /& the argument vector" Unix processes also a set of text varia/le associations
called environment varia/les" Each child process inherits the environment of its
parent" The static environment varia/les are stored in a special arra& which is also
passed to main() and can /e read if desired"
main (argc(arg4(en4p)
int argc;
char *arg4XY( *en4pXY;
0
A
The arra& of strings en4pXY is a list of values of the environment variables of the
s&stem, formatted /&
N1JB=4alue
This gives C programmers access to the shell:s glo/al environment"
0n addition to the en4p vector, it is possi/le to access the environment varia/les
through the call geten4()" This is used as followsB suppose we want to access the
shell environment varia/le THGJB"
char *string;
string = geten4(&HGJB&);
string is now a pointer to static /ut pu/lic data" ?ou should not use string as if
it were &ou:re own propert& /ecause it will /e used again /& the s&stem" Cop& it:s
contents to another string /efore using the data"
char %ufferX8@@Y;
strcpy (%uffer(string);
Node:6pecial i/rar& 4unctions and ,acros, Next:9idden 3perators,
Previous:Putting together a program, Up:Top
4*ecial 'i)rar1 2unctions an$ Macros
Chec#ing character types. Handling strings. /oing maths.
C provides a repertoire of standard li/rar& functions and macros for specialiCed
purposes (and for the advanced user)" These ma& /e divided into various
categories" 4or instance
Character identification (ctype.h)
6tring manipulation (string.h)
,athematical functions (math.h)
7 program generall& has to -include special header files in order to use special
functions in li/raries" The names of the appropriate files can /e found in particular
compiler manuals" 0n the examples a/ove the names of the header files are given in
parentheses"
Character 0dentification:
Example %#:
3utput %#:
6tring ,anipulation:
Example %H:
,athematical 4unctions:
Examples %M:
,aths Errors:
Example %+:
@uestions %(:
C&aracter #$entification
6ome or all of the following functionsEmacros will /e availa/le for identif&ing and
classif&ing single characters" The programmer ought to /eware that it would /e
natural for man& of these facilities to exist as macros rather than functions, so the
usual remar-s a/out macro parameters appl&, 6ee Preprocessor" 7n example of
their use is given a/ove" 7ssume that Itrue: has an& non=Cero, integer value and that
Ifalse: has the integer value Cero" ch stands for some character, or char t&pe
varia/le"
isalpha(ch)
This returns true if ch is alpha/etic and false otherwise" 7lpha/etic means
a""N or 1""F"
isupper(ch)
1eturns true if the character was upper case" 0f ch was not an alpha/etic
character, this returns false"
islower(ch)
1eturns true if the character was lower case" 0f ch was not an alpha/etic
character, this returns false"
isdigit(ch)
1eturns true if the character was a digit in the range $"")"
isxdigit(ch)
1eturns true if the character was a valid hexadecimal digit: that is, a num/er
from $"") or a letter a""f or 7""4"
isspace(ch)
1eturns true if the character was a white space character, that is: a space, a
319 character or a newline"
ispunct(ch)
1eturns true if ch is a punctuation character"
isalnum(ch)
1eturns true if a character is alphanumeric: that is, alpha/etic or digit"
isprint(ch)
1eturns true if the character is printa/le: that is, the character is not a control
character"
isgraph(ch)
1eturns true if the character is graphic" i"e" if the character is printa/le
(excluding the space)
iscntrl(ch)
1eturns true if the character is a control character" i"e" 76C00 values $ to G(
and (%+"
isascii(ch)
1eturns true if the character is a valid 76C00 character: that is, it has a code
in the range $""(%+"
iscsym(ch)
1eturns true if the character was a character which could /e used in a C
identifier"
toupper(ch)
This converts the character ch into its upper case counterpart" This does not
affect characters which are alread& upper case, or characters which do not
have a particular case, such as digits"
tolower(ch)
This converts a character into its lower case counterpart" 0t does not affect
characters which are alread& lower case"
toascii(ch)
This strips off /it + of a character so that it is in the range $""(%+: that is, a
valid 76C00 character"
Node:Example %#, Next:3utput %#, Previous:Character 0dentification, Up:6pecial
i/rar& 4unctions and ,acros
+/am*les
)********************************************************)
)* *)
)* <emonstration of character utility functions *)
)* *)
)********************************************************)
)* prints out all the 1+D characters which gi4e *)
)* the 4alue &true& for the listed character fns *)
-include .stdio.h/
-include .ctype.h/ )* contains character utilities *)
-define 1EEDH1R+ ch = @; isascii(ch); chPP
)********************************************************)
main () )* 1 criminally long main programI *)
0 char ch;
printf (&S1E< DH1R1D3BR+ LRGJ isalpha()2n2n&);
for (1EEDH1R+)
0
if (isalpha(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ isupper()2n2n&);
for (1EEDH1R+)
0
if (isupper(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ islower()2n2n&);
for (1EEDH1R+)
0
if (islower(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ isdigit()2n2n&);
for (1EEDH1R+)
0
if (isdigit(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ isxdigit()2n2n&);
for (1EEDH1R+)
0
if (isxdigit(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ ispunct()2n2n&);
for (1EEDH1R+)
0
if (ispunct(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ isalnum()2n2n&);
for (1EEDH1R+)
0
if (isalnum(ch))
0
printf (&'c &(ch);
A
A
printf (&2n2nS1E< DH1R1D3BR+ LRGJ iscsym()2n2n&);
for (1EEDH1R+)
0
if (iscsym(ch))
0
printf (&'c &(ch);
A
A
A
Node:3utput %#, Next:6tring ,anipulation, Previous:Example %#, Up:6pecial
i/rar& 4unctions and ,acros
Program 0ut*ut
S1E< DH1R1D3BR+ LRGJ isalpha()
1 9 D < B L R H ^ W E J N G , ] R + 3 U S ? C \ F a % c d e f g
h i U
6 l m n o p O r s t u 4 w x y N
S1E< DH1R1D3BR+ LRGJ isupper()
1 9 D < B L R H ^ W E J N G , ] R + 3 U S ? C \ F
S1E< DH1R1D3BR+ LRGJ islower()
a % c d e f g h i U 6 l m n o p O r s t u 4 w x y N
S1E< DH1R1D3BR+ LRGJ isdigit()
@ # $ 5 7 8 : ; = >
S1E< DH1R1D3BR+ LRGJ isxdigit()
@ # $ 5 7 8 : ; = > 1 9 D < B L a % c d e f
S1E< DH1R1D3BR+ LRGJ ispunct()
I & - T ' M " ( ) * P ( - . ) : ; . = / V _ X 2 Y Z K ! 0 Q A [
S1E< DH1R1D3BR+ LRGJ isalnum()
@ # $ 5 7 8 : ; = > 1 9 D < B L R H ^ W E J N G , ] R + 3 U S ?
C \ F a % c d e f g h i U 6 l m n o p O r s t u 4 w x y N
S1E< DH1R1D3BR+ LRGJ iscsym()
@ # $ 5 7 8 : ; = > 1 9 D < B L R H ^ W E J N G , ] R + 3 U S ?
C \ F K a % c d e f g h i U 6 l m n o p O r s t u 4 w x y N
Node:6tring ,anipulation, Next:Example %H, Previous:3utput %#, Up:6pecial
i/rar& 4unctions and ,acros
4tring Mani*ulation
The following functions perform useful functions for string handling, 6ee 6trings"
strcat()
This function DconcatenatesD two strings: that is, it Aoins them together into
one string" The effect of:
char *new(*this( ontoX$88Y;
new = strcat(onto(this);
is to Aoin the string this onto the string onto" new is a pointer to the
complete stringB it is identical to onto" ,emor& is assumed to have /een
allocated for the starting strings" The string which is to /e copied to must /e
large enough to accept the new string, tagged onto the end" 0f it is not then
unpredicta/le effects will result" (0n some programs the user might get awa&
without declaring enough space for the DontoD string, /ut in general the
results will /e gar/age, or even a crashed machine") To Aoin two static strings
together, the following code is re<uired:
char *s# = &string one&;
char *s$ = &string two&;
main ()
0 char %ufferX$88Y;
strcat(%uffer(s#);
strcat(%uffer(s$);
A
/uffer would then contain Dstring onestring twoD"
strlen()
This function returns a t&pe int value, which gives the length or num/er of
characters in a string, not including the NUEE /&te end mar-er" 7n example
is:
int len;
char *string;
len = strlen (string);
strcpy()
This function copies a string from one place to another" Use this function in
preference to custom routines: it is set up to handle an& peculiarities in the
wa& data are stored" 7n example is
char *to(*from;
to = strcpy (to(from);
>here to is a pointer to the place to which the string is to /e copied and
from is the place where the string is to /e copied from"
strcmp()
This function compares two strings and returns a value which indicates how
the& compared" 7n example:
int 4alue;
char *s#(*s$;
4alue = strcmp(s#(s$);
The value returned is $ if the two strings were identical" 0f the strings were
not the same, this function indicates the (76C00) alpha/etical order of the
two" s# / s$, alpha/eticall&, then the value is / @" 0f s# . s$ then the
value is . @" Note that num/ers come /efore letters in the 76C00 code
se<uence and also that upper case comes /efore lower case"
There are also variations on the theme of the functions a/ove which /egin with
strn instead of str" These ena/le the programmer to perform the same actions
with the first n characters of a string:
strncat()
This function concatenates two strings /& cop&ing the first n characters of
this to the end of the onto string"
char *onto(*new(*this;
new = strncat(onto(this(n);
strncpy()
This function copies the first n characters of a string from one place to
another
char *to(*from;
int n;
to = strncpy (to(from(n);
strncmp()
This function compares the first n characters of two strings
int 4alue;
char *s#(*s$;
4alue = strcmp(s#(s$(n);
The following functions perform conversions /etween strings and floating
pointEinteger t&pes, without needing to use sscanf()" The& ta-e a pre=initialiCed
string and wor- out the value represented /& that string"
atof()
76C00 to floating point conversion"
dou%le x;
char *stringptr;
x = atof(stringptr);
atoi()
76C00 to integer conversion"
int i;
char *stringptr;
i = atoi(stringptr);
atol()
76C00 to long integer conversion"
long i;
char *stringptr;
i = atol(stringptr);
Node:Example %H, Next:,athematical 4unctions, Previous:6tring ,anipulation,
Up:6pecial i/rar& 4unctions and ,acros
+/am*les
)********************************************************)
)* *)
)* +tring comparison *)
)* *)
)********************************************************)
-include .stdio.h/
-define 3RUB #
-define J1CEBN 5@
)********************************************************)
main ()
0 char string#XJ1CEBNY(string$XJ1CEBNY;
int result;
while (3RUB)
0
printf (&3ype in string #:2n2n&);
scanf (&'5@s&(string#);
printf (&3ype in string $:2n2n&);
scanf (&'5@s&(string$);
result = strcmp (string#(string$);
if (result == @)
0
printf (&3hose strings were the sameI2n&);
A
if (result / @)
0
printf (&string# / string$2n&);
A
if (result . @)
0
printf (&string# . string $2n&);
A
A
A
Node:,athematical 4unctions, Next:Examples %M, Previous:Example %H,
Up:6pecial i/rar& 4unctions and ,acros
Mat&ematical 2unctions
C has a li/rar& of standard mathematical functions which can /e accessed /&
-including the appropriate header files (math.h etc")" 0t should /e noted that all
of these functions wor- with dou%le or long float t&pe varia/les" 7ll of C:s
mathematical capa/ilities are written for long varia/le t&pes" 9ere is a list of the
functions which can /e expected in the standard li/rar& file" The varia/les used are
all to /e declared long
int i; )* long int *)
dou%le x(y(result; )* long float *)
The functions themselves must /e declared long float or dou/le (which might /e
done automaticall& in the mathematics li/rar& file, or in a separate file) and an&
constants must /e written in floating point form: for instance, write ;.@ instead of
Aust ;"
19+()
,7C13" 1eturns the unsigned value of the value in parentheses" 6ee
fa%s() for a function version"
fa%s()
4ind the a/solute or unsigned value of the value in parentheses:
result = fa%s(x);
ceil()
4ind out what the ceiling integer is: that is, the integer which is Aust a/ove
the value in parentheses" This is li-e rounding up"
i = ceil(x);
)* ceil ($.$) is 5 *)
floor()
4ind out what the floor integer is: that is, the integer which is Aust /elow the
floating point value in parentheses
i = floor(x);
)* floor($.$) is $ *)
exp()
4ind the exponential value"
result = exp(x);
result = exp($.;);
log()
4ind the natural (Naperian) logarithm" The value used in the parentheses
must /e unsigned: that is, it must /e greater than Cero" 0t does not have to /e
declared specificall& as unsigned" e"g"
result = log(x);
result = log($.;#=$=);
log#@()
4ind the /ase ($ logarithm" The value used in the parentheses must /e
unsigned: that is, it must /e greater than Cero" 0t does not have to /e declared
specificall& as unsigned"
result = log#@(x);
result = log#@(#@@@@);
pow()
1aise a num/er to the power"
result = pow(x(y); )*raise x to the power y *)
result = pow(x($); )*find x-sOuared *)
result = pow($.@(5.$); )* find $ to the power 5.$ ...*)
sOrt()
4ind the s<uare root of a num/er"
result = sOrt(x);
result = sOrt($.@);
sin()
4ind the sine of the angle in radians"
result = sin(x);
result = sin(5.#7);
cos()
4ind the cosine of the angle in radians"
result = cos(x);
result = cos(5.#7);
tan()
4ind the tangent of the angle in radians"
result = tan(x);
result = tan(5.#7);
asin()
4ind the arcsine or inverse sine of the value which must lie /etween R("$
and =("$"
result = asin(x);
result = asin(#.@);
acos()
4ind the arccosine or inverse cosine of the value which must lie /etween
R("$ and =("$"
result = acos(x);
result = acos(#.@);
atan()
4ind the arctangent or inverse tangent of the value"
result = atan(x);
result = atan($@@.@);
atan$()
This is a special inverse tangent function for calculating the inverse tangent
of x divided /& &" This function is set up to find this result more accuratel&
than atan()"
result = atan$(x(y);
result = atan$(x)5.#7);
sinh()
4ind the h&per/olic sine of the value" (Pronounced DshineD or DsinchD)
result = sinh(x);
result = sinh(8.@);
cosh()
4ind the h&per/olic cosine of the value"
result = cosh(x);
result = cosh(8.@);
tanh()
4ind the h&per/olic tangent of the value"
result = tanh(x);
result = tanh(8.@);
Node:Examples %M, Next:,aths Errors, Previous:,athematical 4unctions,
Up:6pecial i/rar& 4unctions and ,acros
+/am*les
)******************************************************)
)* *)
)* Jaths functions demo -# *)
)* *)
)******************************************************)
)* use sin(x) to wor6 out an animated model *)
-include .stdio.h/
-include .math.h/
-include .limits.h/
-define 3RUB #
-define 1J,E3U<B 5@
-define ND @.@$
dou%le pi; )* this may already %e defined *)
)* in the math file *)
)******************************************************)
)* Ee4el @ *)
)******************************************************)
main () )* 3he simple pendulum program *)
0 pi = asin(#.@)*$; )* if , is not defined *)
printf (&2n3HB +J,EB ,BN<UEUJ:2n2n2n&);
,endulum();
A
)*****************************************************)
)* Ee4el # *)
)*****************************************************)
,endulum ()
0 dou%le x( twopi = pi * $;
int i(position;
while (true)
0
for (x = @; x . twopi; x P= ND)
0
position = (int)(1J,E3U<B * sin(x));
for (i = -1J,E3U<B; i .= 1J,E3U<B; iPP)
0
if (i == position)
0
putchar("*");
A
else
0
putchar(" ");
A
A
startofline();
A
A
A
)*****************************************************)
)* 3ool6it *)
)*****************************************************)
startofline()
0
putchar("2r");
A
Node:,aths Errors, Next:Example %+, Previous:Examples %M, Up:6pecial i/rar&
4unctions and ,acros
Mat&s +rrors
,athematical functions can /e delicate animals" There exist mathematical
functions which simpl& cannot produce sensi/le answers in all possi/le cases"
,athematical functions are not Duser friendl&D; 3ne example of an unfriendl&
function is the inverse sine function asin(x) which onl& wor-s for values of x in
the range R("$ to =("$" The reason for this is a mathematical one: namel& that the
sine function (of which asin() is the opposite) onl& has values in this range" The
statement
y = asin ($8.5);
is nonsense and it cannot possi/l& produce a value for y, /ecause none exists"
6imilarl&, there is no simple num/er which is the s<uare root of a negative value,
so an expression such as:
x = sOrt(-$.@);
would also /e nonsense" This doesn:t stop the programmer from writing these
statements though and it doesn:t stop a fault& program from stra&ing out of /ounds"
>hat happens then when an erroneous statement is executedF 6ome sort of error
condition would certainl& have to result"
0n man& languages, errors, li-e the ones a/ove, are terminal: the& cause a program
to stop without an& option to recover the damage" 0n C, as the reader might have
come to expect, this is not the case" 0t is possi/le (in principle) to recover from an&
error, whilst still maintaining firm control of a program"
Errors li-e the ones a/ove are called domain errors (the set of values which a
function can accept is called the domain of the function)" There are other errors
which can occur too" 4or example, division /& Cero is illegal, /ecause dividing /&
Cero is Dmathematical nonsenseD = it can /e done, /ut the answer can /e all the
num/ers which exist at the same time; 3/viousl& a program cannot wor- with an&
idea as vague as this" 4inall&, in addition to these DpathologicalD cases,
mathematical operations can fail Aust /ecause the num/ers the& deal with get too
large for the computer to handle, or too small, as the case ma& /e"
/omain error
0llegal value put into function
/ivision by 0ero
8ividing /& Cero is nonsense"
(verflow
Num/er /ecame too large
8nderflow
Num/er /ecame too small"
3oss of accuracy
No meaningful answer could /e calculated
Errors are investigated /& calling a function called matherr()" The mathematical
functions, listed a/ove, call this function automaticall& when an error is detected"
The function responds /& returning a value which gives information a/out the
error" The exact details will depend upon a given compiler" 4or instance a
h&pothetical example: if the error could /e recovered from, matherr() returns $,
otherwise it returns =(" matherr() uses a DstructD t&pe varia/le called an
DexceptionD to diagnose faults in mathematical functions, 6ee 6tructures and
Unions" This can /e examined /& programs which trap their errors dutifull&"
0nformation a/out this structure must /e found in a given compiler manual"
7lthough it is not possi/le to generaliCe, the following remar-s a/out the
/ehaviour of mathematical functions ma& help to avoid an& surprises a/out their
/ehaviour in error conditions"
7 function which fails to produce a sensi/le answer, for an& of the reasons
a/ove, might simpl& return Cero or it might return the maximum value of the
computer" .e careful to chec- this" (8ivision /& Cero and underflow
pro/a/l& return Cero, whereas overflow returns the maximum value which
the computer can handle")
6ome functions return the value NaN" Not a form of 0ndian unleavened
/read, this stands for INot a Num/er:, i"e" no sensi/le result could /e
calculated"
6ome method of signalling errors must clearl& /e used" This is the exception
structure (a special -ind of C varia/le) which gives information a/out the
last error which occurred" 4ind out what it is and trap errors;
3/viousl&, wherever possi/le, the programmer should tr& to stop errors from
occurring in the first place"
Node:Example %+, Next:@uestions %(, Previous:,aths Errors, Up:6pecial i/rar&
4unctions and ,acros
+/am*le
9ere is an example for the mathematicall& minded" The program /elow performs
numerical integration /& the simplest possi/le method of adding up the area under
small strips of a graph of the function f(y) = $*y" The integral is found /etween
the limits $ and H and the exact answer is %H" (6ee diagram") The particular
compiler used for this program returns the largest num/er which can /e
represented /& the computer when num/ers overflow, although, in this simple case,
it is impossi/le for the num/ers to overflow"
)**********************************************************)
)* *)
)* Numerical Bstimation of ntegral *)
)* *)
)**********************************************************)
-include .stdio.h/
-include .math.h/
-include .limits.h/
-define EJ3 8
dou%le inc = @.@@#; )* ncrement width - ar%itrary *)
dou%le twopi;
)***********************************************************)
)** EBSBE @ *)
)***********************************************************)
main ()
0 dou%le y(integrand();
dou%le integral = @;
twopi = 7 * asin(#.@);
for ( y = inc)$; y . EJ3; y P= inc )
0
integral P= integrand (y) * inc;
A
printf (&ntegral 4alue = '.#@f 2n&(integral);
A
)***************************************************************)
)** EBSBE # **)
)***************************************************************)
dou%le integrand (y)
dou%le y;
0 dou%le 4alue;
4alue = $*y;
if (4alue / #e5@=)
0
printf (&G4erflow error2n&);
exit (@);
A
return (4alue);
A
Node:@uestions %(, Previous:Example %+, Up:6pecial i/rar& 4unctions and
,acros
.uestions
(" >hat t&pe of data is returned from mathematical functionsF
%" 7ll calculations are performed using long varia/les" True or falseF
G" >hat information is returned /& strlen()F
#" >hat action is performed /& strcat()F
H" Name five -inds of error which can occur in a mathematical function"
Node:9idden 3perators, Next:,ore on 8ata T&pes, Previous:6pecial i/rar&
4unctions and ,acros, Up:Top
%i$$en o*erators an$ values
Concise expressions
,an& operators in C are more versatile than the& appear to /e, at first glance" Ta-e,
for example, the following operators
= PP -- P= -= etc...
the assignment, increment and decrement operators""" These innocent loo-ing
operators can /e used in some surprising wa&s which ma-e C source code ver&
neat and compact"
The first thing to notice is that PP and -- are unar& operators: that is, the& are
applied to a single varia/le and the& affect that varia/le alone" The& therefore
produce one uni<ue value each time the& are used" The assignment operator, on the
other hand, has the unusual position of /eing /oth unar&, in the sense that it wor-s
out onl& one expression, and also /inar& or d&adic /ecause it sits /etween two
separate o/Aects: an DlvalueD on the left hand side and an expression on the right
hand side" .oth -inds of operator have one thing in common however: /oth form
statements which have values in their own right" >hat does this meanF 0t means
that certain -inds of statement, in C, do not have to /e thought of as /eing
complete and sealed off from the rest of a program" To paraphrase a famous author:
D0n C, no statement is an islandD" 7 statement can /e ta-en as a whole (as a D/lac-
/oxD) and can /e treated as a single value, which can /e assigned and compared to
things; The value of a statement is the result of the operation which was carried out
in the statement"
0ncrementEdecrement operator statements, ta-en as a whole, have a value which is
one greater E or one less than the value of the varia/le which the& act upon" 6o:
c = 8;
cPP;
The second of these statement cPP; has the value M, and similarl&:
c = 8;
c--;
The second of these statements c--; has the value #" Entire assignment statements
have values too" 7 statement such as:
c = 8;
has the value which is the value of the assignment" 6o the example a/ove has the
value H" This has some important implications"
Extended and 9idden Q:
Example %*:
9idden PP --:
7rra&s 6trings and 9idden 3perators:
Example %):
Cautions a/out 6t&le:
Example G$:
@ues %(:
Node:Extended and 9idden Q, Next:Example %*, Previous:9idden 3perators,
Up:9idden 3perators
+/ten$e$ an$ %i$$en =
The idea that assignment statement has a value, can /e used to ma-e C programs
neat and tid& for one simple reason: it means that a whole assignment statement
can /e used in place of a value" 4or instance, the value c = @; could /e assigned
to a varia/le /:
% = (c = @);
or simpl&:
% = c = @;
These e<uivalent statements set % and c to the value Cero, provided / and c are of
the same t&pe; 0t is e<uivalent to the more usual:
% = @;
c = @;
0ndeed, an& num/er of these assignments can /e strung together:
a = (% = (c = (d = (e = 8))))
or simpl&:
a = % = c = d = e = 8;
This ver& neat s&ntax compresses five lines of code into one single line; There are
other uses for the valued assignment statement, of course: it can /e used an&where
where a value can /e used" 4or instance:
0n other assignments (as a/ove)
7s a parameter for functions
0nside a comparison (QQ S T etc"")
7s an index for arra&s""""
The uses are manifold" Consider how an assignment statement might /e used as a
parameter to a function" The function /elow gets a character from the input stream
stdin and passes it to a function called ,rocessDharacter():
,rocessDharacter (ch = getchar());
This is a perfectl& valid statement in C, /ecause the hidden assignment statement
passes on the value which it assigns" The actual order of events is that the
assignment is carried out first and then the function is called" 0t would not ma-e
sense the other wa& around, /ecause, then there would /e no value to pass on as a
parameter" 6o, in fact, this is a more compact wa& of writing:
ch = getchar();
,rocessDharacter (ch);
The two methods are entirel& e<uivalent" 0f there is an& dou/t, examine a little
more of this imaginar& character processing program:
,rocessDharacter(ch = getchar());
if (ch == "*")
0
printf (&+tarry( +tarry Night...&);
A
The purpose in adding the second statement is to impress the fact that ch has /een
assigned <uite legitimatel& and it is still defined in the next statement and the one
after"""until it is re=assigned /& a new assignment statement" The fact that the
assignment was hidden inside another statement does not ma-e it an& less valid"
7ll the same remar-s appl& a/out the specialiCed assignment operators P=, *=, )=
etc""
Node:Example %*, Next:9idden PP --, Previous:Extended and 9idden Q,
Up:9idden 3perators
+/am*le
)************************************************)
)* *)
)* Hidden 1ssignment -# *)
)* *)
)************************************************)
main ()
0
do
0
switch (ch = getchar())
0
default : putchar(ch);
%rea6;
case "]" : )* ]uit *)
A
A
while (ch I= "]");
A
)* end *)
)************************************************)
)* *)
)* Hidden 1ssignment -$ *)
)* *)
)************************************************)
main ()
0 dou%le x = @;
while ((x P= @.$) . $@.@)
0
printf (&'lf&(x);
A
A
)* end *)
Node:9idden PP --, Next:7rra&s 6trings and 9idden 3perators, Previous:Example
%*, Up:9idden 3perators
%i$$en ++ an$ --
The increment and decrement operators also form statements which have intrinsic
values and, li-e assignment expressions, the& can /e hidden awa& in inconspicuous
places" These two operators are slightl& more complicated than assignments
/ecause the& exist in two forms: as a postfix and as a prefix:
-ostfi( -refi(
4arPP PP4ar
4ar-- --4ar
and these two forms have su/tl& different meanings" oo- at the following
example:
int i = 5;
,rintNum%er (iPP);
The increment operator is hidden in the parameter list of the function
,rintNum%er()" This example is not as clear cut as the assignment statement
examples however, /ecause the varia/le i has, /oth a value /efore the PP operator
acts upon it, and a different value afterwards" The <uestion is then: which value is
passed to the functionF 0s i incremented /efore or after the function is calledF The
answer is that this is where the two forms of the operator come into pla&"
#f t&e o*erator is use$ as a *refi/" t&e o*eration is *erforme$ before t&e
function call. #f t&e o*erator is use$ as a *ostfi/" t&e o*eration is *erforme$
after t&e function call.
0n the example a/ove, then, the value G is passed to the function and when the
function returns, the value of i is incremented to #" The alternative is to write:
int i = 5;
,rintNum%er (PPi);
in which case the value # is passed to the function ,rintNum%er()" The same
remar-s appl& to the decrement operator"
Node:7rra&s 6trings and 9idden 3perators, Next:Example %), Previous:9idden PP
--, Up:9idden 3perators
8rra1s" 4trings an$ %i$$en 0*erators
7rra&s and strings are one area of programming in which the increment and
decrement operators are used a lot" 9iding operators inside arra& su/scripts or
hiding assignments inside loops can often ma-e light wor- of tas-s such as
initialiCation of arra&s" Consider the following example of a one dimensional arra&
of integers"
-define +FB $@
int i( arrayX+FBY;
for (i = @; i . +FB; arrayXiPPY = @)
0
A
This is a neat wa& of initialiCing an arra& to Cero" Notice that the postfixed form of
the increment operator is used" This prevents the element arrayX@Y from assigning
Cero to memor& which is out of the /ounds of the arra&"
6trings too can /enefit from hidden operators" 0f the standard li/rar& function
strlen() (which finds the length of a string) were not availa/le, then it would /e
a simple matter to write the function
strlen (string) )* count the characters in a string *)
char *string;
0 char *ptr;
int count = @;
for (ptr = string; *(ptrPP) I= "2@"; countPP)
0
A
return (count);
A
This function increments count while the end of string mar-er 2@ is not found"
Node:Example %), Next:Cautions a/out 6t&le, Previous:7rra&s 6trings and 9idden
3perators, Up:9idden 3perators
+/am*le
)*********************************************************)
)* *)
)* Hidden Gperator <emo *)
)* *)
)*********************************************************)
)* 1ny assignment or increment operator has a 4alue *)
)* which can %e handed straight to printf() ... *)
)* 1lso compare the prefix ) postfix forms of PP)-- *)
-include .stdio.h/
)*********************************************************)
main ()
0 int a(%(c(d(e;
a = (% = (c = (d = (e = @))));
printf (&'d 'd 'd 'd 'd2n&( a( %PP( c--( d = #@( e P= 5);
a = % = c = d = e = @;
printf (&'d 'd 'd 'd 'd2n&( a( PP%( --c( d = #@( e P= 5);
A
)* end *)
)*******************************************************)
)* *)
)* Hidden Gperator demo -$ *)
)* *)
)*******************************************************)
-include .stdio.h/
)*******************************************************)
main () )* prints out NeroI *)
0
printf (&'d&(Salue());
A
)*******************************************************)
Salue() )* Dhec6 for Nero .... *)
0 int 4alue;
if ((4alue = RetSalue()) == @)
0
printf (&Salue was Nero2n&);
A
return (4alue);
A
)********************************************************)
RetSalue() )* +ome function to get a 4alue *)
0
return (@);
A
)* end *)
Node:Cautions a/out 6t&le, Next:Example G$, Previous:Example %), Up:9idden
3perators
Cautions a)out 4t1le
9iding operators awa& inside other statements can certainl& ma-e programs loo-
ver& elegant and compact, /ut, as with all neat tric-s, it can ma-e programs harder
to understand" Never forget that programming is communication to other
programmers and /e -ind to the potential reader of a program" (0t could /e &ou in
&ears or months to come;) 6tatements such as:
if ((i = (int)chPP) .= --comparison)
0
A
are not recommenda/le programming st&le and the& are no more efficient than the
more longwinded:
chPP;
i = (int)ch;
if (i .= comparison)
0
A
comparison--;
There is alwa&s a happ& medium in which to settle on a reada/le version of the
code" The statement a/ove might perhaps /e written as:
i = (int) chPP;
if (i .= --comparison)
0
A
Node:Example G$, Next:@ues %(, Previous:Cautions a/out 6t&le, Up:9idden
3perators
+/am*le
)******************************************************)
)* *)
)* 1rrays and Hidden Gperators *)
)* *)
)******************************************************)
-include .stdio.h/
-define +FB #@
)******************************************************)
)* Ee4el @ *)
)******************************************************)
main () )* <emo prefix and postfix PP in arrays *)
0 int i( arrayX+FBY;
nitialiNe(array);
i = 7;
arrayXiPPY = =;
,rint (array);
nitialiNe(array);
i = 7;
arrayXPPiY = =;
,rint(array);
A
)*******************************************************)
)* Ee4el # *)
)*******************************************************)
nitialiNe (array) )* set to Nero *)
int arrayX+FBY;
0 int i;
for (i = @; i . +FB; arrayXiPPY = @)
0
A
A
)******************************************************)
,rint (array) )* to stdout *)
int arrayX+FBY;
0 int i = @;
while (i . +FB)
0
printf (&'$d&(arrayXiPPY);
A
putchar ("2n");
A
)* end *)
)****************************************************)
)* *)
)* Hidden Gperator *)
)* *)
)****************************************************)
-include .stdio.h/
-define J1CNG $@
)*****************************************************)
main () )* ,rint out 8 x ta%le *)
0 int i( ctr = @;
for (i = #; PPctr .= J1CNG; i = ctr*8)
0
printf (&'5d&(i);
A
A
Node:@ues %(, Previous:Example G$, Up:9idden 3perators
.uestions
(" >hich operators can /e hidden inside other statementsF
%" !ive a reason wh& &ou would not want to do this in ever& possi/le case"
G" 9idden operators can /e used in return statements "e"g
7. return (PPx);
8.
>ould there /e an& point in writing:
return (xPP);
Node:,ore on 8ata T&pes, Next:,achine evel 3perations, Previous:9idden
3perators, Up:Top
More on $ata t1*es
This section is a/out the remaining data t&pes which C has to offer programmers"
6ince C allows &ou to define new data t&pes we shall not /e a/le to cover all of the
possi/lities, onl& the most important examples" The most important of these are
LEB
The t&pe which files are classified under
enum
Enumerated t&pe for a/stract data
4oid
The Dempt&D t&pe
4olatile
New 7N60 standard t&pe for memor& mapped 0E3
const
New 7N60 standard t&pe for fixed data
struct
!roups of varia/les under a single name
union
,ulti=purpose storage areas for d&namical memor& allocation
6pecial Constant Expressions:
40E:
enum:
Example G(:
Example G%:
6uggested uses for enum:
void:
volatile:
const:
struct again:
union:
t&pedef:
@uestions %G:
Node:6pecial Constant Expressions, Next:40E, Previous:,ore on 8ata T&pes,
Up:,ore on 8ata T&pes
4*ecial Constant +/*ressions
Constant expressions are often used without an& thought, until a programmer needs
to -now how to do something special with them" 0t is worth ma-ing a /rief remar-
a/out some special wa&s of writing integer constants, for the latter half of this
/oo-"
Up to now the distinction /etween long and short integer t&pes has largel& /een
ignored" Constant values can /e declared explicitl& as long values, in fact, /&
placing the letter E after the constant"
long int 4aria%le = $5E;
4aria%le = $5:8$:8>=E;
7dvanced programmers, writing s&stems software, often find it convenient to wor-
with hexadecimal or octal num/ers since these num/er /ases have a special
relationship to /inar&" 7 constant in one of these t&pes is declared /& placing either
@ (Cero) or @x in front of the appropriate value" 0f ddd is a value, then:
Gctal num%er @ddd
Hexadecimal num%er @xddd
4or example:
octK4alue = @;;; )* ;; octal *)
hexK4alue = @xLLBL; )* LLBL hex *)
This -ind of notation has alread& /een applied to strings and single character
constants with the /ac-slash notation, instead of the leading Cero character:
ch = "2ddd";
ch = "2xdd";
The values of character constants, li-e these, cannot /e an& greater than %HH"
Node:40E, Next:enum, Previous:6pecial Constant Expressions, Up:,ore on 8ata
T&pes
FILE
0n all previous sections, the files stdin, stdout and stderr alone have /een used
in programs" These special files are alwa&s handled implicitl& /& functions li-e
printf() and scanf(): the programmer never gets to -now that the& are, in fact,
files" Programs do not have to use these functions however: standard inputEoutput
files can /e treated explicitl& /& general file handling functions Aust as well" 4iles
are distinguished /& filenames and /& file pointers" 4ile pointers are varia/les
which pass the location of files to file handling functionsB /eing varia/les, the&
have to /e declared as /eing some data t&pe" That t&pe is called LEB and file
pointers have to /e declared Dpointer to LEBD" 4or example:
LEB *fp;
LEB *fp = stdin;
LEB *fopen();
4ile handling functions which return file pointers must also /e declared as pointers
to files" Notice that, in contrast to all the other reserved words LEB is written in
upper case: the reason for this is that LEB is not a simple data t&pe such as char
or int, /ut a structure which is onl& defined /& the header file stdio.h and so,
strictl& spea-ing, it is not a reserved word itself" >e shall return to loo- more
closel& at files soon"
Node:enum, Next:Example G(, Previous:40E, Up:,ore on 8ata T&pes
enum
7/stract data are usuall& the realm of exclusivel& high level languages such as
Pascal" enum is a wa& of incorporating limited Dhigh levelD data facilities into C"
enum is short for enumerated data" The user defines a t&pe of data which is made
up of a fixed set of words, instead of num/ers or characters" These words are given
su/stitute integer num/ers /& the compiler which are used to identif& and compare
enum t&pe data" 4or example:
enum countries
0
Bngland(
+cotland(
?ales(
Bire(
Norge(
+4erige(
<anmar6(
<eutschland
A;
main ()
0 enum countries 4aria%le;
4aria%le = Bngland;
A
>h& go to all this trou/leF The point a/out enumerated data is that the& allow the
programmer to forget a/out an& num/ers which the computer might need in order
to deal with a list of words, li-e the ones a/ove, and simpl& concentrate on the
logic of using them" Enumerated data are called a/stract /ecause the low level
num/er form of the words is removed from the users attention" 0n fact, enumerated
data are made up of integer constants, which the compiler generates itself" 4or this
reason, the& have a natural partner in programs: the switch statement" 9ere is an
example, which uses the countries a/ove to ma-e a -ind of airport Dhelp computerD
in age of electronic passports;
Node:Example G(, Next:Example G%, Previous:enum, Up:,ore on 8ata T&pes
+/am*le
)**********************************************************)
)* *)
)* Bnumerated <ata *)
)* *)
)**********************************************************)
-include .stdio.h/
enum countries
0
Bngland(
reland(
+cotland(
?ales(
<anmar6(
sland(
Norge(
+4erige
A;
)**********************************************************)
main () )* Blectronic ,assport ,rogram *)
0 enum countries %irthplace( getinfo();
printf (&nsert electronic passport2n&);
%irthplace = getinfo();
switch (%irthplace)
0
case Bngland : printf (&?elcome homeI2n&);
%rea6;
case <anmar6 :
case Norge : printf (&Sel6ommen til Bngland2n&);
%rea6;
A
A
)************************************************************)
enum countries getinfo() )* interrogate passport *)
0
return (Bngland);
A
)* end *)
enum ma-es words into constant integer values for a programmer" 8ata which are
declared enum are not the -ind of data which it ma-es sense to do arithmetic with
(even integer arithmetic), so in most cases it should not /e necessar& to -now or
even care a/out what num/ers the compiler gives to the words in the list" 9owever,
some compilers allow the programmer to force particular values on words" The
compiler then tries to give the values successive integer num/ers unless the
programmer states otherwise" 4or instance:
enum planets
0
Jercury(
Senus(
Barth = #$(
Jars(
^upiter(
+aturn(
Uranus(
Neptune(
,luto
A;
This would pro/a/l& &ield values Jercury = @, Senus = #, Barth = #$, Jars
= #5, ^upiter = #7 """ etc" 0f the user tries to force a value which the compiler
has alread& used then the compiler will complain"
The following example program listing shows two points:
enum t&pes can /e local or glo/al"
The la/els can /e forced to have certain values
Node:Example G%, Next:6uggested uses for enum, Previous:Example G(, Up:,ore
on 8ata T&pes
+/am*le
)**********************************************************)
)* *)
)* Bnumerated <ata *)
)* *)
)**********************************************************)
)* 3he smallest ad4enture game in the world *)
-include .stdio.h/
-define 3RUB #
-define L1E+B @
enum treasures )* 1d4enture 3reasures *)
0
ru%ies(
sapphires(
gold(
sil4er(
mas6(
scroll(
lamp
A;
)***********************************************************)
)* Ee4el @ *)
)***********************************************************)
main () )* 3iny 1d4entureI *)
0 enum treasures o%Uect = gold;
if (geto%Uect(o%Uect))
0
printf (&Dongratulations you"4e found the goldI2n&);
A
else
0
printf (&3oo %ad -- you Uust missed your %ig chance&);
A
A
)***********************************************************)
)* Ee4el # *)
)***********************************************************)
geto%Uect (o%) )* yes or no V *)
enum treasures o%;
0 enum answer
0
no = false(
yes = true
A;
if (o% == gold)
0
printf (&,ic6 up o%UectV \)N2n&);
switch (getchar())
0
case "y" :
case "\" : return ((int) yes); )* true and false *)
default : return ((int) no); )* are integers *)
A
A
else
0
printf (&\ou grapple with the dirt2n&);
return (false);
A
A
)* end *)
Node:6uggested uses for enum, Next:void, Previous:Example G%, Up:,ore on
8ata T&pes
4uggeste$ uses for enum
9ere are some suggested uses for enum"
enum num%ers
0
Nero(
one(
two(
three
A;
enum animals
0
cat(
dog(
cow(
sheep(
A;
enum plants
0
grass(
roses(
ca%%ages(
oa6tree
A;
enum diseases
0
heart(
s6in(
malnutrition(
circulatory
A;
enum Ouar6s
0
up(
down(
charmed(
strange(
top(
%ottom(
truth(
%eauty
A;
3ther suggestions: colours, names of roads or t&pes of train"
Node:void, Next:volatile, Previous:6uggested uses for enum, Up:,ore on 8ata
T&pes
oid
4oid is a peculiar data t&pe which has some de/ata/le uses" The void datat&pes
was introduced in order to ma-e C s&ntacticall& consistent" The main idea of 4oid
is to /e a/le to declare functions which have no return value" The word Ivoid: is
intended in the meaning Iempt&: rather than Iinvalid:" 0f &ou recall, the default is
for C functions to return a value of t&pe int" The value returned /& a function did
not have to /e specified could alwa&s /e discarded, so this was not a pro/lem in
practice" 0t did ma-e compiler chec-s more difficult however: how do &ou warn
someone a/out inconsistent return values if it is legal to ignore return valuesF
The 7N60 solution was to introduce a new data t&pe which was called 4oid for
functions with no value" The word 4oid is perhaps an unfortunate choice, since it
has several implicit meanings none of which reall& express what is intended" The
words Inovalue: or Inot&pe: would have /een /etter choices" 7 varia/le or function
can /e declared 4oid in the following wa&s"
4oid function();
4oid 4aria%le;
4oid *ptr;
(4oid) return4alue();
The following are true of 4oid:
7 varia/le which is declared 4oid is useless: it cannot /e used in an
expression and it cannot /e assigned to a value" The data t&pe was
introduced with functions in mind /ut the grammar of C allows us to define
varia/les of this t&pe also, even though there is no point"
7 function which is declared 4oid has no return value and returns simpl&
with:
return;

7 function call can /e cast (4oid) in order to explicitl& discard a return


value (though this is done /& the compiler an&wa&)" 4or instance, scanf()
returns the num/er of items it matches in the control string, /ut this is
usuall& discarded"
scanf (&'c&(Mch);

or
(4oid) scanf(&'c&(Mch);
4ew programmers would do this since it merel& clutters up programs with
irrelevant ver/iage"
7 4oid pointer can point to to an& -ind of o/Aect" This means that an&
pointer can /e assigned to a 4oid pointer, regardless of its t&pe" This is also
a highl& <uestiona/le feature of the 7N60 draft" 0t replaces the meaning of
4oid from Ino t&pe or value: to Ino particular t&pe:" 0t allows assignments
/etween incompati/le pointer t&pes without a cast operator" This is also
rather du/ious"
Node:volatile, Next:const, Previous:void, Up:,ore on 8ata T&pes
olatile
4olatile is a t&pe which has /een proposed in the 7N60 standard" The idea
/ehind this t&pe is to allow memor& mapped inputEoutput to /e held in C varia/les"
5aria/les which are declared volatile will /e a/le to have their values altered in
wa&s which a program does not explicitl& define: that is, /& external influences
such as cloc-s, external ports, hardware, interrupts etc"""
The 4olatile datat&pe has found another use since the arrival of multiprocessor,
multithreaded operating s&stems" 0ndependent processes which share common
memor& could each change a varia/le independentl&" 0n other words, in a
multithreaded environment the value of a varia/le set /& one process in shared
memor& might /e altered /& another process without its -nowledge" The -e&word
4olatile servers as a warning to the compiler that an& optimiCing code it
produces should not rel& on caching the value of the varia/le, it should alwa&s
reread its value"
Node:const, Next:struct again, Previous:volatile, Up:,ore on 8ata T&pes
const
The reserved word const is used to declare data which can onl& /e assigned once,
either /ecause the& are in 13, (for example) or /ecause the& are data whose
values must not /e corrupted" T&pes declared const must /e assigned when the& are
first initialiCed and the& exist as stored values onl& at compile time:
const dou%le pi = 5.#7;
const int one = #;
6ince a constant arra& onl& exists at compile time, it can /e initialiCed /& the
compiler"
const int arrayXY =
0
#(
$(
5(
7
A;
arrayX@Y then has the value (, arrayX#Y has the value % """ and so on" 7n&
attempt to assign values to const t&pes will result in compilation errors"
0t is worth comparing the const declaration to enumerated data, since the& are
connected in a ver& simple wa&" The following two sets of of statements are the
same:
enum num%ers
0
Nero(
one(
two(
three(
four
A;
and
const Nero = @;
const one = #;
const two = $;
const three = 5;
const four = 7;
Constant t&pes and enumerated data are therefore Aust different aspects of the same
thing" Enumerated data provide a convenient wa& of classif&ing constants,
however, while the compiler -eeps trac- of the values and t&pes" >ith const &ou
have to -eep trac- of constant values personall&"
Node:struct again, Next:union, Previous:const, Up:,ore on 8ata T&pes
struct
6tructures are called records in Pascal and man& other languages" The& are
pac-ages of varia/les which are all wrapped up under a single name" 6tructures are
descri/ed in detail in chapter %H"
Node:union, Next:t&pedef, Previous:struct again, Up:,ore on 8ata T&pes
union
Unions are often grouped together with structures, /ut the& are <uite unli-e them in
almost all respects" The& are li-e general purpose storage containers, which can
hold a variet& of different varia/le t&pes, at different times" The compiler ma-es a
container which is large enough to ta-e an& of these, 6ee 6tructures and Unions"
Node:t&pedef, Next:@uestions %G, Previous:union, Up:,ore on 8ata T&pes
t!pedef
C allows us to define our own data t&pes or to rename existing ones /& using a
compiler directive called typedef" This statement is used as follows:
typedef type newtypename;
6o, for example, we could define a t&pe called %yte, which was exactl& one /&te
in siCe /& redefining the word char:
typedef unsigned char %yte;
The compiler t&pe chec-ing facilities then treat /&te as a new t&pe which can /e
used to declare varia/les:
%yte 4aria%le( function();
The t&pedef statement ma& /e written inside functions or in the glo/al white space
of a program"
)**************************************************)
)* ,rogram *)
)**************************************************)
typedef int newname#;
main ()
0
typedef char newname$;
A
This program will compile and run (though it will not do ver& much)"
0t is not ver& often that &ou want to rename existing t&pes in the wa& shown a/ove"
The most important use for t&pedef is in conAunction with structures and unions"
6tructures and unions can, /& their ver& definition, /e all -inds of shape and siCe
and their names can /ecome long and tedious to declare" t&pedef ma-es dealing
with these simple /ecause it means that the user can define a structure or union
with a simple t&pename"
Node:@uestions %G, Previous:t&pedef, Up:,ore on 8ata T&pes
.uestions
(" 0s LEB a reserved wordF 0f so wh& is it in upper caseF
%" >rite a statement which declares a file pointer called fp"
G" Enumerated data are given values /& the compiler so that it can do
arithmetic with them" True or falseF
#" 8oes 4oid do an&thing which C cannot alread& do without this t&peF
H" >hat t&pe might a timer device /e declared if it were to /e called /& a
varia/le nameF
M" >rite a statement which declares a new t&pe DrealD to /e li-e the usual t&pe
Ddou/leD"
+" 5aria/les declared const can /e of an& t&pe" True or falseF
Node:,achine evel 3perations, Next:4iles and 8evices, Previous:,ore on 8ata
T&pes, Up:Top
Mac&ine 'evel 0*erations
4its and 4ytes. +lags9messages. Shifting.
8own in the depths of &our computer, /elow even the operating s&stem are /its of
memor&" These da&s we are used to wor-ing at such a high level that it is eas& to
forget them" .its (or /inar& digits) are the lowest level software o/Aects in a
computer: there is nothing more primitive" 4or precisel& this reason, it is rare for
high level languages to even ac-nowledge the existence of /its, let alone
manipulate them" ,anipulating /it patterns is usuall& the preserve of assem/l&
language programmers" C, however, is <uite different from most other high level
languages in that it allows a programmer full access to /its and even provides high
level operators for manipulating them"
6ince this /oo- is an introductor& text, we shall treat /it operations onl&
superficiall&" ,an& of the facilities which are availa/le for /it operations need not
concern the maAorit& of programs at all" This section concerns the main uses of /it
operations for high level programs and it assumes a certain amount of -nowledge
a/out programming at the low level" ?ou ma& wish to consult a /oo- on assem/l&
language programming to learn a/out low level memor& operations, in more detail"
.it Patterns:
4lags registers:
.it 3perators and 7ssignments:
.it operators:
6hift 3perations:
Truth Ta/les and ,as-ing:
Example GG:
3utput GG:
Example G#:
Example GH:
@uestions %#:
Node:.it Patterns, Next:4lags registers, Previous:,achine evel 3perations,
Up:,achine evel 3perations
Bit Patterns
7ll computer data, of an& t&pe, are /it patterns" The onl& difference /etween a
string and a floating point varia/le is the wa& in which we choose to interpret the
patterns of /its in a computer:s memor&" 4or the most part, it is <uite unnecessar&
to thin- of computer data as /it patternsB s&stems programmers, on the other hand,
fre<uentl& find that the& need to handle /its directl& in order to ma-e efficient use
of memor& when using flags" 7 flag is a message which is either one thing or the
other: in s&stem terms, the flag is said to /e Ion: or Ioff: or alternativel& set or
cleared" The usual place to find flags is in a status register of a CPU (central
processor unit) or in a pseudo=register (this is a status register for an imaginar&
processor, which is held in memor&)" 7 status register is a group of /its (a /&te
perhaps) in which each /it signifies something special" 0n an ordinar& /&te of data,
/its are grouped together and are interpreted to have a collective meaningB in a
status register the& are thought of as /eing independent" Programmers are
interested to -now a/out the contents of /its in these registers, perhaps to find out
what happened in a program after some special operation is carried out" 3ther uses
for /it patterns are listed /elow here:
,essages sent /etween devices in a complex operating environment use /its
for efficienc&"
6eriall& transmitted data"
9andling /it=planes in screen memor&" (1aster ports and devices)
Performing fast arithmetic in simple cases"
Programmers who are interested in performing /it operations often wor- in
hexadecimal /ecause ever& hexadecimal digit convenientl& handles four /its in one
go ((M is % to the power #)"
Node:4lags registers, Next:.it 3perators and 7ssignments, Previous:.it Patterns,
Up:,achine evel 3perations
2lags" Registers an$ Messages
7 register is a place inside a computer processor chip, where data are wor-ed upon
in some wa&" 7 status register is a register which is used to return information to a
programmer a/out the operations which too- place in other registers" 6tatus
registers contain flags which give &es or no answers to <uestions concerning the
other registers" 0n advanced programming, there ma& /e call for Dpseudo registersD
in addition to DrealD ones" 7 pseudo register is merel& a register which is created /&
the programmer in computer memor& (it does not exist inside a processor)"
,essages are Aust li-e pseudo status registers: the& are collections of flags which
signal special information /etween different devices andEor different programs in a
computer s&stem" ,essages do not necessaril& have fixed locations: the& ma& /e
passed a parameters" ,essages are a ver& compact wa& of passing information to
low level functions in a program" 4lags, registers, pseudo=registers and messages
are all treated as /it patterns" 7 program which ma-es use of them must therefore
/e a/le to assign these o/Aects to C varia/les for use" 7 /it pattern would normall&
/e declared as a character or some -ind of integer t&pe in C, perhaps with the aid
of a t&pedef statement"
typedef char %yte;
typedef int %itpattern;
%itpattern 4aria%le;
%yte message;
The flags or /its in a registerEmessage""" have the values ( or $, depending upon
whether the& are on or off (set or cleared)" 7 program can test for this /& using
com/inations of the operators which C provides"
Node:.it 3perators and 7ssignments, Next:.it operators, Previous:4lags registers,
Up:,achine evel 3perations
Bit 0*erators an$ 8ssignments
C provides the following operators for handling /it patterns:
..
.it shift left (a specified num/er or /it positions)
//
.it shift right(a specified num/er of /it positions)
Q
.itwise 0nclusive 31
Z
.itwise Exclusive 31
M
.itwise 7N8
[
.itwise one:s complement
M=
7N8 assign (varia/le Q varia/le 2 value)
Q=
Exclusive 31 assign (varia/le Q varia/le U value)
Z=
0nclusive 31 assign (varia/le Q varia/le V value)
//=
6hift right assign (varia/le Q varia/le SS value)
..=
6hift left assign (varia/le Q varia/le TT value)
The meaning and the s&ntax of these operators is given /elow"
Node:.it operators, Next:6hift 3perations, Previous:.it 3perators and
7ssignments, Up:,achine evel 3perations
T&e Meaning of Bit 0*erators
.itwise operations are not to /e confused with logical operations (MM, QQ""") 7 /it
pattern is made up of $s and (s and /itwise operators operate individuall& upon
each /it in the operand" Ever& $ or ( undergoes the operations individuall&" .itwise
operators (7N8, 31) can /e used in place of logical operators (MM,QQ), /ut the&
are less efficient, /ecause logical operators are designed to reduce the num/er of
comparisons made, in an expression, to the optimum: as soon as the truth or falsit&
of an expression is -nown, a logical comparison operator <uits" 7 /itwise operator
would continue operating to the last /efore the final result were -nown"
.elow is a /rief summar& of the operations which are performed /& the a/ove
operators on the /its of their operands"
Node:6hift 3perations, Next:Truth Ta/les and ,as-ing, Previous:.it operators,
Up:,achine evel 3perations
4&ift 0*erations
0magine a /it pattern as /eing represented /& the following group of /oxes" Ever&
/ox represents a /itB the num/ers inside represent their values" The values written
over the top are the common integer values which the whole group of /its would
have, if the& were interpreted collectivel& as an integer"
#$= :7 5$ #: = 7 $ #
-------------------------------
Q @ Q @ Q @ Q @ Q @ Q @ Q @ Q # Q = #
-------------------------------
6hift operators move whole /it patterns left or right /& shunting them /etween
/oxes" The s&ntax of this operation is:
4alue .. num%er of positions
4alue // num%er of positions
6o for example, using the /oxed value (() a/ove:
# .. #
would have the value %, /ecause the /it pattern would have /een moved one place
the the left:
#$= :7 5$ #: = 7 $ #
-------------------------------
Q @ Q @ Q @ Q @ Q @ Q @ Q # Q @ Q = $
-------------------------------
6imilarl&:
# .. 7
has the value (M /ecause the original /it pattern is moved /& four places:
#$= :7 5$ #: = 7 $ #
-------------------------------
Q @ Q @ Q @ Q # Q @ Q @ Q @ Q @ Q = #:
-------------------------------
7nd:
: .. $ == #$
#$= :7 5$ #: = 7 $ #
-------------------------------
Q @ Q @ Q @ Q @ Q @ Q # Q # Q @ Q = :
-------------------------------
6hift left % places:
#$= :7 5$ #: = 7 $ #
-------------------------------
Q @ Q @ Q @ Q @ Q # Q # Q @ Q @ Q = #$
-------------------------------
Notice that ever& shift left multiplies /& % and that ever& shift right would divide
/& two, integerwise" 0f a /it reaches the edge of the group of /oxes then it falls out
and is lost forever" 6o:
# // # == @
$ // # == #
$ // $ == @
n // n == @
7 common use of shifting is to scan through the /its of a /itpattern one /& one in a
loop: this is done /& using mas#s"
Node:Truth Ta/les and ,as-ing, Next:Example GG, Previous:6hift 3perations,
Up:,achine evel 3perations
Trut& Ta)les an$ Masking
The operations 7N8, 31 (inclusive 31) and W31EE31 (exclusive 31) perform
comparisons or Dmas-ingD operations /etween two /its" The& are /inar& or d&adic
operators" 7nother operation called C3,PE,ENT is a unar& operator" The
operations performed /& these /itwise operators are /est summariCed /& truth
tables" Truth ta/les indicate what the results of all possi/le operations are /etween
two single /its" The same operation is then carried out for all the /its in the
varia/les which are operated upon"
Complement X:
7N8:
31:
W31:
Node:Complement X, Next:7N8, Previous:Truth Ta/les and ,as-ing, Up:Truth
Ta/les and ,as-ing
Com*lement "
The complement of a num/er is the logical opposite of the num/er" C provides a
Done:s complementD operator which simpl& changes all (s into $s and all $s into (s"
[# has the 4alue @ (for each %it)
[@ has the 4alue #
7s a truth ta/le this would /e summariCed as follows:
[value == result
@ #
# @
Node:7N8, Next:31, Previous:Complement X, Up:Truth Ta/les and ,as-ing
8;- &
This wor-s /etween two values" e"g" (# M @)
value 1 M value 2 == result
@ @ @
@ # @
# @ @
# # #
.oth value ( 7N8 value % have to /e ( in order for the result or /e ("
Node:31, Next:W31, Previous:7N8, Up:Truth Ta/les and ,as-ing
0R #
This wor-s /etween two values" e"g" (# Q @)
value 1 Q value 2 == result
@ @ @
@ # #
# @ #
# # #
The result is ( if one 31 the other 31 /oth of the values is ("
Node:W31, Previous:31, Up:Truth Ta/les and ,as-ing
?0R>+0R $
3perates on two values" e"g" (# Z @)
value 1 Z value 2 == result
@ @ @
@ # #
# @ #
# # @
The result is ( if one 31 the other (/ut not /oth) of the values is ("
.it patterns and logic operators are often used to ma-e mas#s" 7 mas- is as a thing
which fits over a /it pattern and modifies the result in order perhaps to single out
particular /its, usuall& to cover up part of a /it pattern" This is particularl& pertinent
for handling flags, where a programmer wishes to -now if one particular flag is set
or not set and does not care a/out the values of the others" This is done /&
deli/eratel& inventing a value which onl& allows the particular flag of interest to
have a non=Cero value and then 7N8ing that value with the flag register" 4or
example: in s&m/olic language:
J1+W = @@@@@@@#
S1EUB# = #@@##@##
S1EUB$ = #@@###@@
J1+W M S1EUB# == @@@@@@@#
J1+W M S1EUB$ == @@@@@@@@
The Ceros in the mas- mas#s off the first seven /its and leave onl& the last one to
reveal its true value" 7lternativel&, mas-s can /e /uilt up /& specif&ing several
flags:
LE1R# = @@@@@@@#
LE1R$ = @@@@@@#@
LE1R5 = @@@@@#@@
JB++1RB = LE1R# Q LE1R$ Q LE1R5
JB++1RB == @@@@@###
0t should /e emphasiCed that these expressions are onl& written in s&m/olic
language: it is not possi/le to use /inar& values in C" The programmer must
convert to hexadecimal, octal or denar& first" (6ee the appendices for conversion
ta/les)"
Node:Example GG, Next:3utput GG, Previous:Truth Ta/les and ,as-ing,
Up:,achine evel 3perations
+/am*le
7 simple example helps to show how logical mas-s and shift operations can /e
com/ined" The first program gets a denar& num/er from the user and converts it
into /inar&" The second program gets a value from the user in /inar& and converts
it into hexadecimal"
)***************************************************)
)* *)
)* 9it Janipulation -# *)
)* *)
)***************************************************)
)* Don4ert denary num%ers into %inary *)
)* Weep shifting i %y one to the left *)
)* and test the highest %it. 3his does*)
)* NG3 preser4e the 4alue of i *)
-include .stdio.h/
-define NUJ9BRGL93+ =
)****************************************************)
main ()
0 short i(U(%it(;
short J1+W = @x=@;
printf (&Bnter any num%er less than #$=: &);
scanf (&'h&( Mi);
if (i / #$=)
0
printf (&3oo %ig2n&);
return (@);
A
printf (&9inary 4alue = &);
for (U = @; U . NUJ9BRGL93+; UPP)
0
%it = i M J1+W;
printf (&'#d&(%it)J1+W);
i ..= #;
A
printf (&2n&);
A
)* end *)
Node:3utput GG, Next:Example G#, Previous:Example GG, Up:,achine evel
3perations
0ut*ut
Bnter any num%er less than #$=: 8:
9inary 4alue = @@###@@@
Bnter any 4alue less than #$=: 5
9inary 4alue = @@@@@@##
Node:Example G#, Next:Example GH, Previous:3utput GG, Up:,achine evel
3perations
+/am*le
)***************************************************)
)* *)
)* 9it Janipulation -$ *)
)* *)
)***************************************************)
)* Don4ert %inary num%ers into hex *)
-include .stdio.h/
-define NUJ9BRGL93+ =
)****************************************************)
main ()
0 short U(hex = @;
short J1+W;
char %inaryXNUJ9BRGL93+Y;
printf (&Bnter an =-%it %inary num%er: &);
for (U = @; U . NUJ9BRGL93+; UPP)
0
%inaryXUY = getchar();
A
for (U = @; U . NUJ9BRGL93+; UPP)
0
hex ..= #;
switch (%inaryXUY)
0
case "#" : J1+W = #;
%rea6;
case "@" : J1+W = @;
%rea6;
default : printf(&Not %inary2n&);
return(@);
A
hex Q= J1+W;
A
printf (&Hex 4alue = '#x2n&(hex);
A
)* end *)
Node:Example GH, Next:@uestions %#, Previous:Example G#, Up:,achine evel
3perations
+/am*le
Bnter any num%er less than #$=: 8:
9inary 4alue = @@###@@@
Bnter any 4alue less than #$=: 5
9inary 4alue = @@@@@@##
Node:@uestions %#, Previous:Example GH, Up:,achine evel 3perations
.uestions
(" >hat distinguishes a /it pattern from an ordinar& varia/leF Can an& varia/le
/e a /it patternF
%" >hat is the difference /etween an inclusive 31 operation and an exclusive
31 operationF
G" 0f &ou saw the following function call in a program, could &ou guess what its
parameter wasF
7. Gpen?indow (9GR<BR Q R1<RB3+ Q JGU+BDGN3RGE Q +FNR);
8.
M" 4ind out what the denar& (decimal) values of the following operations are:
(" ; M $
%" # M #
G" #8 M 5
#" #8 M ;
H" #8 M ; M 5
Tr& to explain the results" (9int: draw out the num/ers as /inar& patterns,
using the program listed")
+" 4ind out what the denar& (decimal) values of the following operations are:
(" # Q $
%" # Q $ Q 5
*" 4ind out the values of:
(" # M ([#)
%" $5 M ([$5)
G" $@#$ M ([$@#$)
(9int: write a short program to wor- them out" Use short t&pe varia/les for
all the num/ers)"
Node:4iles and 8evices, Next:6tructures and Unions, Previous:,achine evel
3perations, Up:Top
2iles an$ -evices
4iles are places for reading data from or writing data to" This includes dis- files
and it includes devices such as the printer or the monitor of a computer" C treats all
information which enters or leaves a program as though it were a stream of /&tes: a
file" The most commonl& used file streams are stdin (the -e&/oard) and stdout
(the screen), /ut more sophisticated programs need to /e a/le to read or write to
files which are found on a dis- or to the printer etc"
7n operating s&stem allows a program to see files in the outside world /&
providing a num/er of channels or Iportals: (Iinlets: and Ioutlets:) to wor- through"
0n order to examine the contents of a file or to write information to a file, a
program has to open one of these portals" The reason for this slightl& indirect
method of wor-ing is that channelsEportals hide operating s&stem dependent details
of filing from the programmer" Thin- of it as a protocol" 7 program which writes
information does no more than pass that information to one of these portals and the
operating s&stem:s filing su/s&stem does the rest" 7 program which reads data
simpl& reads values from its file portal and does not have to worr& a/out how the&
got there" This is extremel& simple to wor- in practice" To use a file then, a
program has to go through the following routine:
3pen a file for reading or writing" (1eserve a portal and locate the file on
dis- or whatever")
1ead or write to the file using file handling functions provided /& the
standard li/rar&"
Close the file to free the operating s&stem DportalD for use /& another
program or file"
7 program opens a file /& calling a standard li/rar& function and is returned a file
pointer, /& the operating s&stem, which allows a program to address that particular
file and to distinguish it from all others"
4iles !enerall&:
4ile Positions:
9igh evel 4ile 9andling 4unctions:
3pening files:
Closing a file:
fprintf:
fscanf:
s-ipfilegar/F:
6ingle Character 0E3:
getc and fgetc:
ungetc:
putc and fputc:
fgets and fputs:
feof:
Printer 3utput:
Example GM:
3utput GM:
Converting example:
4ile Errors:
3ther 4acilities for 9igh evel 4iles:
fread() and fwrite():
ftell and fsee-:
rewind:
fflush:
ow evel 4iling 3perations:
4ile 9andles:
open:
close:
creat:
read:
write:
lsee-:
unlin- remove:
Example G+:
@uestions %H:
Node:4iles !enerall&, Next:4ile Positions, Previous:4iles and 8evices, Up:4iles
and 8evices
2iles :enerall1
C provides two levels of file handlingB these can /e called high level and low level"
9igh level files are all treated as text files" 0n fact, the data which go into the files
are exactl& what would /e seen on the screen, character /& character, except that
the& are stored in a file instead" This is true whether a file is meant to store
characters, integers, floating point t&pes" 7n& file, which is written to /& high level
file handling functions, ends up as a text file which could /e edited /& a text editor"
9igh level text files are also read /ac- as character files, in the same wa& that input
is ac<uired from the -e&/oard" This all means that high level file functions are
identical in concept to -e&/oardEscreen inputEoutput"
The alternative to these high level functions, is o/viousl& low level functions"
These are more efficient, in principle, at filing data as the& can store data in large
lumps, in raw memor& format, without converting to text files first" ow level
inputEoutput functions have the disadvantage that the& are less Iprogrammer
friendl&: than the high level ones, /ut the& are li-el& to wor- faster"
4ile Positions:
9igh evel 4ile 9andling 4unctions:
3pening files:
Closing a file:
fprintf:
fscanf:
s-ipfilegar/F:
6ingle Character 0E3:
getc and fgetc:
ungetc:
putc and fputc:
fgets and fputs:
feof:
Converting example:
4ile Errors:
3ther 4acilities for 9igh evel 4iles:
fread() and fwrite():
ftell and fsee-:
rewind:
fflush:
ow evel 4iling 3perations:
4ile 9andles:
open:
close:
creat:
read:
write:
lsee-:
unlin- remove:
Node:4ile Positions, Next:9igh evel 4ile 9andling 4unctions, Previous:4iles
!enerall&, Up:4iles and 8evices
2ile Positions
>hen data are read from a file, the operating s&stem -eeps trac- of the current
position of a program within that file so that it onl& needs to ma-e a standard
li/rar& call to Iread the next part of the file: and the operating s&stem o/liges /&
reading some more and advancing its position within the file, until it reaches the
end" Each single character which is read causes the position in a file to /e
advanced /& one"
7lthough the operating s&stem does a great deal of hand holding regarding file
positions, a program can control the wa& in which that position changes with
functions such as ungetc() if need /e" 0n most cases it is not necessar& and it
should /e avoided, since complex movements within a file can cause complex
movements of a dis- drive mechanism which in turn can lead to wear on dis-s and
the occurrence of errors"
Node:9igh evel 4ile 9andling 4unctions, Next:3pening files, Previous:4ile
Positions, Up:4iles and 8evices
%ig& 'evel 2ile %an$ling 2unctions
,ost of the high level inputEoutput functions which deal with files are easil&
recogniCa/le in that the& start with the letter If:" 6ome of these functions will
appear stri-ingl& familiar" 4or instance:
fprintf()
fscanf()
fgets()
fputs()
These are all generaliCed file handling versions of the standard inputEoutput li/rar&"
The& wor- with generaliCed files, as opposed to the specific files stdin and stdout
which printf() and scanf() use" The file versions differ onl& in that the& need
an extra piece of information: the file pointer to a particular portal" This is passed
as an extra parameter to the functions" the& process data in an identical wa& to their
standard 0E3 counterparts" 3ther filing functions will not loo- so familiar" 4or
example:
fopen()
fclose()
getc()
ungetc();
putc()
fgetc()
fputc()
feof()
.efore an& wor- can /e done with high level files, these functions need to /e
explained in some detail"
Node:3pening files, Next:Closing a file, Previous:9igh evel 4ile 9andling
4unctions, Up:4iles and 8evices
0*ening files
7 file is opened /& a call to the li/rar& function fopen(): this is availa/le
automaticall& when the li/rar& file Tstdio"hS is included" There are two stages to
opening a file: firstl& a file portal must /e found so that a program can access
information from a file at all" 6econdl& the file must /e ph&sicall& located on a
dis- or as a device or whatever" The fopen() function performs /oth of these
services and, if, in fact, the file it attempts to open does not exist, that file is created
anew" The s&ntax of the fopen() function is:
LEB *returnpointer;
returnpointer = fopen(&filename&(&mode&);
or
LEB returnpointer;
char *fname( *mode;
returnpointer = fopen(fname(mode);
The filename is a string which provides the name of the file to /e opened"
4ilenames are s&stem dependent so the details of this must /e sought from the local
operating s&stem manual" The operation mode is also a string, chosen from one of
the following:
r
3pen file for reading
w
3pen file for writing
a
3pen file for appending
rw
3pen file for reading and writing (some s&stems)
This mode string specifies the wa& in which the file will /e used" 4inall&,
returnpointer is a pointer to a LEB structure which is the whole o/Aect of
calling this function" 0f the file (which was named) opened successfull& when
fopen() was called, returnpointer is a pointer to the file portal" 0f the file could not
/e opened, this pointer is set to the value NUEE" This should /e tested for, /ecause it
would not ma-e sense to attempt to write to a file which could not /e opened or
created, for whatever reason"
7 read onl& file is opened, for example, with some program code such as:
LEB *fp;
if ((fp = fopen (&filename&(&r&)) == NUEE)
0
printf (&Lile could not %e opened2n&);
errorKhandler();
A
7 <uestion which springs to mind is: what happens if the user has to t&pe in the
name of a file while the program is runningF The solution to this pro/lem is <uite
simple" 1ecall the function filename() which was written in chapter %$"
char *filename() )* return filename *)
0 static char *filenm = &........................&;
do
0
printf (&Bnter filename :&);
scanf (&'$7s&(filenm);
s6ipgar%();
A
while (strlen(filenm) == @);
return (filenm);
A
This function ma-es file opening simple" The programmer would now write
something li-e:
LEB *fp;
char *filename();
if ((fp = fopen (filename()(&r&)) == NUEE)
0
printf (&Lile could not %e opened2n&);
errorKhandler();
A
and then the user of the program would automaticall& /e prompted for a filename"
3nce a file has /een opened, it can /e read from or written to using the other
li/rar& functions (such as fprintf() and fscanf()) and then finall& the file has
to /e closed again"
Node:Closing a file, Next:fprintf, Previous:3pening files, Up:4iles and 8evices
Closing a file
7 file is closed /& calling the function fclose()" fclose() has the s&ntax:
int returncode;
LEB *fp;
returncode = fclose (fp);
fp is a pointer to the file which is to /e closed and returncode is an integer value
which is $ if the file was closed successfull&" fclose() prompts the file manager
to finish off its dealings with the named file and to close the portal which the
operating s&stem reserved for it" >hen closing a file, a program needs to do
something li-e the following:
if (fclose(fp) I= @)
0
printf (&Lile did not exist.2n&);
errorKhandler();
A
Node:fprintf, Next:fscanf, Previous:Closing a file, Up:4iles and 8evices
fprintf()
This is the highest level function which writes to files" 0ts name is meant to signif&
Dfile=print=formattedD and it is almost identical to its stdout counterpart printf()"
The form of the fprintf() statement is as follows:
fprintf (fp(&string&(4aria%les);
where fp is a file pointer, string is a control string which is to /e formatted and the
varia/les are those which are to /e su/stituted into the /lan- fields of the format
string" 4or example, assume that there is an open file, pointed to /& fp:
int i = #$;
float x = $.58:;
char ch = "s";
fprintf (fp( &'d 'f 'c&( i( x( ch);
The conversion specifiers are identical to those for printf()" 0n fact fprintf()
is related to printf() in a ver& simple wa&: the following two statements are
identical"
printf (&Hello world 'd&( #);
fprintf (stdout(&Hello world 'd&( #);
Node:fscanf, Next:s-ipfilegar/F, Previous:fprintf, Up:4iles and 8evices
fscanf()
The analogue of scanf() is fscanf() and, as with fprintf(), this function
differs from its standard 0E3 counterpart onl& in one extra parameter: a file pointer"
The form of an fscanf() statement is:
LEB *fp;
int n;
n = fscanf (fp(&string&(pointers);
where n is the num/er of items matched in the control string and fp is a pointer to
the file which is to /e read from" 4or example, assuming that fp is a pointer to an
open file:
int i = #@;
float x = -$.58:;
char ch = "x";
fscanf (fp( &'d 'f 'c&( Mi( Mx( Mch);
The remar-s which were made a/out scanf() also appl& to this function:
fscanf() is a Idangerous: function in that it can easil& get out of step with the
input data unless the input is properl& formatted"
Node:s-ipfilegar/F, Next:6ingle Character 0E3, Previous:fscanf, Up:4iles and
8evices
ski*filegar)() =
8o programs need a function such as s6ipgar%() to deal with instances of /adl&
formatted input dataF 7 programmer can assume a /it more a/out files which are
read into a program from dis- file than it can assume a/out the user:s t&ped input"
7 dis- file will presuma/l& have /een produced /& the same program which
generated it, or will /e in a format which the program expects" 0s a function li-e
s6ipgar%() necessar& thenF The answer is: pro/a/l& not" This does not mean to
sa& that a program does not need to chec- for D/ad filesD, or files which do not
contain the data the& are alleged to contain" 3n the other hand, a programmer is at
li/ert& to assume that an& file which does not contain correctl& formatted data is
Aust nonsense: heEshe does not have to tr& to ma-e sense of it with a function li-e
s6ipgar%(), the program could simpl& return an error message li-e D.78 40ED
or whatever and recover in a sensi/le wa&" 0t would pro/a/l& not ma-e sense to use
a function li-e s6ipgar%() for files" 4or comparison alone, s6ipfilegar%() is
written /elow"
s6ipfilegar%(fp)
LEB *fp;
0
while (getc(fp) I= "2n")
0
A
A
Node:6ingle Character 0E3, Next:getc and fgetc, Previous:s-ipfilegar/F, Up:4iles
and 8evices
4ingle C&aracter #>0
There are commonl& four functionsEmacros which perform single character
inputEoutput to or from files" The& are analogous to the functionsEmacros
getchar()
putchar()
for the standard 0E3 files and the& are called:
getc()
ungetc();
putc()
fgetc()
fputc()
Node:getc and fgetc, Next:ungetc, Previous:6ingle Character 0E3, Up:4iles and
8evices
getc() an$ fgetc()
The difference /etween getc() and fgetc() will depend upon a particular
s&stem" 0t might /e that getc() is implemented as a macro, whereas fgetc() is
implemented as a function or vice versa" 3ne of these alternatives ma& not /e
present at all in a li/rar&" Chec- the manual, to /e sure; .oth getc() and fgetc()
fetch a single character from a file:
LEB *fp;
char ch;
)* open file *)
ch = getc (fp);
ch = fgetc (fp);
These functions return a character from the specified file if the& operated
successfull&, otherwise the& return BGL to indicate the end of a file or some other
error" 7part from this, these functionsEmacros are <uite unremar-a/le"
Node:ungetc, Next:putc and fputc, Previous:getc and fgetc, Up:4iles and 8evices
ungetc()
ungetc() is a function which Iun=gets: a character from a file" That is, it reverses
the effect of the last get operation" This is not li-e writing to a file, /ut it is li-e
stepping /ac- one position within the file" The purpose of this function is to leave
the input in the correct place for other functions in a program when other functions
go too far in a file" 7n example of this would /e a program which loo-s for a word
in a text file and processes that word in some wa&"
while (getc(fp) I= " ")
0
A
The program would s-ip over spaces until it found a character and then it would
-now that this was the start of a word" 9owever, having used getc() to read the
first character of that word, the position in the file would /e the second character in
the word; This means that, if another function wanted to read that word from the
/eginning, the position in the file would not /e correct, /ecause the first character
would alread& have /een read" The solution is to use ungetc() to move the file
position /ac- a character:
int returncode;
returncode = ungetc(fp);
The returncode is E34 if the operation was unsuccessful"
Node:putc and fputc, Next:fgets and fputs, Previous:ungetc, Up:4iles and 8evices
putc() an$ fputc()
These two functions write a single character to the output file, pointed to /& fp" 7s
with getc(), one of these ma& /e a macro" The form of these statements is:
LEB *fp;
char ch;
int returncode;
returncode = fputc (ch(fp);
returncode = putc (ch(fp);
The returncode is the ascii code of the character sent, if the operation was
successful, otherwise it is E34"
Node:fgets and fputs, Next:feof, Previous:putc and fputc, Up:4iles and 8evices
fgets() an$ fputs()
Yust as gets() and puts() fetched and sent strings to standard inputEoutput files
stdin and stdout, so fgets() and fputs() send strings to generaliCed files" The
form of an fgets() statement is as follows:
char *str%uff(*return4al;
int n;
LEB *fp;
return4al = fgets (str%uff(n(fp);
str%uff is a pointer to an input /uffer for the stringB fp is a pointer to an open file"
returnval is a pointer to a string: if there was an error in fgets() this pointer is set
to the value NUEE, otherwise it is set to the value of Dstr/uffD" No more than (n=()
characters are read /& fgets() so the programmer has to /e sure to set n e<ual to
the siCe of the string /uffer" (3ne /&te is reserved for the NU terminator") The
form of an fputs() statement is as follows:
char *str;
int return4al;
LEB *fp;
return4al = fputs (str(fp);
>here str is the NUEE terminated string which is to /e sent to the file pointed to
/& fp" return4al is set to BGL if there was an error in writing to the file"
Node:feof, Next:Printer 3utput, Previous:fgets and fputs, Up:4iles and 8evices
feof()
This function returns a true or false result" 0t tests whether or not the end of a file
has /een reached and if it has it returns Itrue: (which has an& value except Cero)B
otherwise the function returns Ifalse: (which has the value Cero)" The form of a
statement using this function is:
LEB *fp;
int outcome;
outcome = feof(fp);
,ost often feof() will /e used inside loops or conditional statements" 4or
example: consider a loop which reads characters from an open file, pointed to /&
fp" 7 call to feof() is re<uired in order to chec- for the end of the file"
while (Ifeof(fp))
0
ch = getc(fp);
A
Translated into pidgin English, this code reads: Iwhile N3T end of file, ch e<uals
get character from file:" 0n /etter(F) English the loop continues to fetch characters
as long as the end of the file has not /een reached" Notice the logical N3T operator
I which stands /efore feof()"
Node:Printer 3utput, Next:Example GM, Previous:feof, Up:4iles and 8evices
Printer 0ut*ut
7n& serious application program will have to /e in full control of the output of a
program" 4or instance, it ma& need to redirect output to the printer so that data can
/e made into hard copies" To do this, one of three things must /e underta-en:
Z
stdout must /e redirected so that it sends data to the printer device"
Z
7 new Dstandard fileD must /e used (not all C compilers use this method")
Z
7 new file must /e opened in order to write to the printer device
The first method is not generall& satisfactor& for applications programs, /ecause
the standard files stdin and stdout can onl& easil& /e redirected from the
operating s&stem command line interpreter (when a program is run /& t&ping its
name)" Examples of this are:
type file / ,RN
which send a text file to the printer device" The second method is reserved for onl&
a few implementations of C in which another Istandard file: is opened /& the local
operating s&stem and is availa/le for sending data to the printer stream" This file
might /e called DstdprnD or Dstandard printer fileD and data could /e written to the
printer /& switching writing to the file li-e this:
fprintf (stdprn(&string 'd...&( integer);
The final method of writing to the printer is to open a file to the printer, personall&"
To do this, a program has to give the DfilenameD of the printer device" This could
/e something li-e DP1T:D or DP1ND or DP1TD or whatever" The filename (actuall&
called a pseudo device name) is used to open a file in precisel& the same wa& as
an& other file is opened: /& using a call to fopen()" fopen() then returns a
pointer to file (which is effectivel& DstdprnD) and this is used to write data to a
computer:s printer driver" The program code to do this should loo- something li-e
the following:
LEB *stdprn;
if ((stdprn = fopen(&,R3:&(&w&)) == NUEE)
0
printf (&,rinter %usy or disconnected2n&);
errorKhandler;
A
Node:Example GM, Next:3utput GM, Previous:Printer 3utput, Up:4iles and 8evices
+/am*le
9ere is an example program which reads a source file (for a program, written in C,
Pascal or whatever""") and lists it, along with its line num/ers" This -ind of program
is useful for de/ugging programs" The program provides the user with the option of
sending the output to the printer" The printer device is assumed to have the
filename DP1T:D" 8etails of how to convert the program for other s&stems is given
at the end"
)***************************************************************)
)* *)
)* E+3 : program file utility *)
)* *)
)***************************************************************)
)* Eist a source file with line num%ers attached. Ei6e *)
)* 3\,B only with lines num%ers too. *)
-include .stdio.h/
-define DG<B @
-define +FB $88
-define GN #
-define GLL @
-define 3RUB #
-define L1E+B @
LEB *fin;
LEB *fout = stdout; )* where output goes to *)
)***************************************************************)
)* Ee4el @ *)
)***************************************************************)
main ()
0 char str%uffXsiNeY(*filename();
int ,on = false;
int line = #;
printf (&+ource ,rogram Eister S#.@2n2n&);
if ((fin = fopen(filename()(&r&)) == NUEE)
0
printf (&2nLile not found2n&);
exit (DG<B);
A
printf (&Gutput to printerV \)N&);
if (yes())
0
,on = ,rinter(GN);
A
while (Ifeof(fin))
0
if (fgets(str%uff(siNe(fin) I= str%uff)
0
if (Ifeof(fin))
0
printf (&+ource file corrupted2n&);
exit (DG<B);
A
A
fprintf (fout(&'7d 's&(linePP(str%uff);
A
DloseLiles(,on);
A
)*************************************************************)
)* Ee4el # *)
)*************************************************************)
DloseLiles(,on) )* close M tidy *)
int ,on;
0
if (,on)
0
,rinter(GLL);
A
if (fclose(fin) I= @)
0
printf (&Brror closing input file2n&);
A
A
)***********************************************************)
,rinter (status) )* switch printer file *)
int status;
0
switch (status)
0
case on: while ((fout = fopen(&,R3:&(&w&)) == NUEE)
0
printf (&,rinter %usy or disconnected2n&);
printf (&2n2nRetryV \)N2n&);
if (Iyes())
0
exit(DG<B);
A
A
%rea6;
case off: while (fclose(fout) I= @)
0
printf (&?aiting to close printer stream2r&);
A
A
A
)***********************************************************)
)* 3ool6it *)
)***********************************************************)
char *filename() )* return filename *)
0 static char *filenm = &........................&;
do
0
printf (&Bnter filename :&);
scanf (&'$7s&(filenm);
s6ipgar%();
A
while (strlen(filenm) == @);
return (filenm);
A
)*************************************************************)
yes () )* Ret a yes)no response from the user *)
0 char ch;
while (3RUB)
0
ch = getchar();
s6ipgar%();
switch (ch)
0
case "y" : case "\" : return (3RUB);
case "n" : case "N" : return (L1E+B);
A
A
A
)*************************************************************)
s6ipgar%() )* s6ip gar%age corrupting input *)
0
while (getchar() I= "2n")
0
A
A
)* end *)
Node:3utput GM, Next:Converting example, Previous:Example GM, Up:4iles and
8evices
0ut*ut
9ere is a sample portion of the output of this program as applied to one of the
example programs in section G$"
# )********************************************************)
$ )* *)
5 )* D programming utility : 4aria%le referencer *)
7 )* *)
8 )********************************************************)
:
; )* +ee section 5@ *)
=
> -include .stdio.h/
#@ -include .ctype.h/
##
#$ -define 3RUB #
#5 -define L1E+B @
#7 -define <UJJ\ @
#8 -define J1C+3R 8#$
#: -define J1C<+FB 5$
&&& and more of the same&
Node:Converting example, Next:4ile Errors, Previous:3utput GM, Up:4iles and
8evices
Converting t&e e/am*le
The example program could /e altered to wor- with a standard printer file DstdprnD
/& changing the following function"
,rinter (status) )* switch printer file *)
int status;
0
switch (status)
0
case on: fout = stdprn;
%rea6;
case off: fout = stdout;
A
A
Node:4ile Errors, Next:3ther 4acilities for 9igh evel 4iles, Previous:Converting
example, Up:4iles and 8evices
2iling +rrors
The standard li/rar& provides an error functionEmacro which returns a trueEfalse
result according to whether or not the last filing function call returned an error
condition" This is called ferror()" To chec- for an error in an open file, pointed to
/& fp:
LEB *fp;
if (ferror(fp))
0
errorKhandler();
A
This functionEmacro does not shed an& light upon the cause of errors, onl& whether
errors have occurred at all" 7 detailed diagnosis of what went wrong is onl&
generall& possi/le /& means of a deeper level call to the dis- operating s&stem
(836)"
Node:3ther 4acilities for 9igh evel 4iles, Next:fread() and fwrite(), Previous:4ile
Errors, Up:4iles and 8evices
0t&er 2acilities for %ig& 'evel 2iles
4iles which have /een opened /& fopen() can also /e handled with the following
additional functions:
fread()
fwrite()
ftell()
fsee6()
rewind()
fflush()
These functions provide facilities to read and write whole /loc-s of characters in
one operation as well as further facilities to locate and alter the current focus of
attention within a file" The& offer, essentiall&, low level filing operations for files
which have /een opened for high level use;
Node:fread() and fwrite(), Next:ftell and fsee-, Previous:3ther 4acilities for 9igh
evel 4iles, Up:4iles and 8evices
fread() an$ fwrite()
These functions read and write whole /loc-s of characters at a time" The form of
fread() is as follows:
LEB *fp;
int noread(n(siNe;
char *ptr;
noread = fread (ptr(siNe(n(fp);
The parameters in parentheses provide information a/out where the data will /e
stored once the& have /een read from a file" fp is a pointer to an open fileB ptr is a
pointer to the start of a /loc- of memor& which is to store the data when it is readB
siCe is the siCe of a /loc- of data in charactersB n is the num/er of /loc-s of data to
/e read" 4inall& noread is a return value which indicates the num/er of /loc-s
which was actuall& read during the operation" 0t is important to chec- that the
num/er of /loc-s expected is the same as the num/er received /ecause something
could have gone wrong with the reading process" (The dis- might /e corrupted or
the file might have /een altered in some wa&") fwrite() has an identical call
structure to fread():
LEB *fp;
int nowritten(n(siNe;
char *ptr;
nowritten = fread (ptr(siNe(n(fp);
This time the parameters in parentheses provide information a/out where the data,
to /e written to a file, will /e found" fp is a pointer to an open fileB ptr is a pointer
to the start of a /loc- of memor& at which the data are storedB siCe is the siCe of a
D/loc-D of data in charactersB n is the num/er of /loc-s of data to /e readB
nowritten is a return value which indicates the actual num/er of /loc-s which
was written" 7gain, this should /e chec-ed"
7 caution a/out these functions: each of these /loc- transfer routines ma-es an
important assumption a/out the wa& in which data are stored in the computer
s&stem" 0t is assumed that the data are stored contiguously in the memor&, that is,
side /& side, in se<uential memor& locations" 0n some s&stems this can /e difficult
to arrange (in multi=tas-ing s&stems in particular) and almost impossi/le to
guarantee" ,emor& which is allocated in C programs /& the function malloc()
does not guarantee to find contiguous portions of memor& on successive calls" This
should /e noted carefull& when developing programs which use these calls"
Node:ftell and fsee-, Next:rewind, Previous:fread() and fwrite(), Up:4iles and
8evices
2ile Positions9 ftell() an$ fseek()
ftell() tells a program its position within a file, opened /& fopen()" fsee6()
see-s a specified place within a file, opened /& fopen()" Normall& high level
readEwrite functions perform as much management over positions inside files as
the programmer wants, /ut in the event of their /eing insufficient, these two
routines can /e used" The form of the function calls is:
long int pos;
LEB *fp;
pos = ftell(fp);
fp is an open file, which is in some state of /eing read or written to" pos is a long
integer value which descri/es the position in terms of the num/er of characters
from the /eginning of the file" 7ligning a file portal with a particular place in a file
is more sophisticated than simpl& ta-ing note of the current position" The call to
fsee6() loo-s li-e this:
long int pos;
int mode(returncode;
LEB *fp;
returncode = fsee6 (fp(pos(mode);
The parameters have the following meanings" fp is a pointer to a file opened /&
fopen()" pos is some wa& of descri/ing the position re<uired within a file" mode
is an integer which specifies the wa& in which pos is to /e interpreted" 4inall&,
returncode is an integer whose value is $ if the operation was successful and =( if
there was an error"
@
pos is an offset measured relative to the /eginning of the file"
#
pos is an offset measured relative to the current position"
$
pos is an offset measured relative to the end of the file"
6ome examples help to show how this wor-s in practice:
long int pos = 8@;
int mode = @(returncode;
LEB *fp;
if (fsee6 (fp(pos(mode) I= @) )* find 8@th character *)
0
printf(&BrrorI2n&);
A
fsee6(fp(@E(@); )* find %eginning of file *)
fsee6(fp($E(@); )* find the end of a file *)
if (fsee6 (fp(#@E(#) I= @) )* mo4e #@ char"s forward *)
0
printf(&BrrorI2n&);
A
The E:s indicate long constants"
Node:rewind, Next:fflush, Previous:ftell and fsee-, Up:4iles and 8evices
rewind()
rewind() is a macro, /ased upon fsee6(), which resets a file position to the
/eginning of the file" e"g"
LEB *fp;
rewind(fp);
fsee6(fp(@E(@); )* = rewind() *)
Node:fflush, Next:ow evel 4iling 3perations, Previous:rewind, Up:4iles and
8evices
fflush()
This is a macroEfunction which can /e used on files which have /een opened for
writing or appending" 0t flushes the output /uffer which means that it forces the
characters in the output /uffer to /e written to the file" 0f used on files which are
open for reading, it causes the input /uffer to /e emptied (assuming that this is
allowed at all)" Example:
LEB *fp;
fflush(fp);
Node:ow evel 4iling 3perations, Next:4ile 9andles, Previous:fflush, Up:4iles
and 8evices
'o( 'evel 2iling 0*erations
Normall& a programmer can get awa& with using the high level inputEoutput
functions, /ut there ma& /e times when C:s predilection for handling all high level
inputEoutput as text files, /ecomes a nuisance" 7 program can then use a set of low
level 0E3 functions which are provided /& the standard li/rar&" These are:
open()
close()
creat()
read()
write()
rename()
unlin6())remo4e()
lsee6()
These low level routines wor- on the operating s&stem:s end of the file portals"
The& should /e regarded as /eing advanced features of the language /ecause the&
are dangerous routines for /ug ridden programs" The data which the& deal with is
untranslated: that is, no conversion from characters to floating point or integers or
an& t&pe at all ta-e place" 8ata are treated as a raw stream of /&tes" ow level
functions should not /e used on an& file at the same time as high level routines,
since high level file handling functions often ma-e calls to the low level functions"
>or-ing at the low level, programs can create, delete and rename files /ut the& are
restricted to the reading and writing of untranslated data: there are no functions
such as fprintf() or fscanf() which ma-e t&pe conversions" 7s well as the
functions listed a/ove a local operating s&stem will dou/tless provide special
function calls which ena/le a programmer to ma-e the most of the facilities offered
/& the particular operating environment" These will /e documented, either in a
compiler manual, or in an operating s&stem manual, depending upon the s&stem
concerned" (The& might concern special graphics facilities or windowing s&stems
or provide wa&s of writing special s&stem dependent data to dis- files, such as
dateEtime stamps etc")
Node:4ile 9andles, Next:open, Previous:ow evel 4iling 3perations, Up:4iles
and 8evices
2ile $escri*tors
7t the low level, files are not handled using file pointers, /ut with integers -nown
as file handles or file descriptors" 7 file handle is essentiall& the num/er of a
particular file portal in an arra&" 0n other words, for all the different terminolog&,
the& descri/e the same thing" 4or example:
int fd;
would declare a file handle or descriptor or portal or whatever it is to /e called"
Node:open, Next:close, Previous:4ile 9andles, Up:4iles and 8evices
open()
open() is the low level file open function" The form of this function call is:
int fd( mode;
char *filename;
fd = open (filename(mode);
where filename is a string which holds the name of the file concerned, mode is a
value which specifies what the file is to /e opened for and fd is either a num/er
used to distinguish the file from others, or =( if an error occurred"
7 program can give more information to this function than it can to fopen() in
order to define exactl& what open() will do" The integer mode is a message or a
pseudo register which passes the necessar& information to open(), /& using the
following flags:
GKR<GNE\ Read access only
GK?RGNE\ ?rite access only
GKR<?R Read)?rite access
and on some compilers:
GKDRB13 Dreate the file if it does not exist
GK3RUND 3runcate the file if it does exist
GK1,,BN< Lind the end of the file %efore each write
GKBCDE Bxclude. Lorce create to fail if the file
exists.
The macro definitions of these flags will /e included in a li/rar& file: find out
which one and -include it in the program" The normal procedure is to open a file
using one of the first three modes" 4or example:
-define L1EB< -#
main()
0 char *filename();
int fd;
fd = open(filename()( GKR<GNE\);
if (fd == L1EB<)
0
printf (&Lile not found2n&);
errorKhandler (failed);
A
A
This opens up a read=onl& file for low level handling, with error chec-ing" 6ome
s&stems allow a more flexi/le wa& of opening files" The four appended modes are
values which can /e /itwise 31ed with one of the first three in order to get more
mileage out of open()" The /itwise 31 operator is the vertical /ar DUD" 4or
example, to emulate the fopen() function a program could opt to create a file if it
did not alread& exist:
fd = open (filename()( GKR<GNE\ Q GKDRB13);
open() sets the file position to Cero if the file is opened successfull&"
Node:close, Next:creat, Previous:open, Up:4iles and 8evices
close()
close() releases a file portal for use /& other files and /rings a file completel& up
to date with regard to an& changes that have /een made to it" i-e all other filing
functions, it returns the value $ if it performs successfull& and the value =( if it
fails" e"g"
-define L1EB< -#
if (close(fd) == L1EB<)
0
printf (&BRRGRI&);
A
Node:creat, Next:read, Previous:close, Up:4iles and 8evices
creat()
This function creates a new file and prepares it for access using the low level file
handling functions" 0f a file which alread& exists is created, its contents are
discarded" The form of this function call is:
int fd( pmode;
char *filename;
fd = creat(filename(pmode);
filename must /e a valid filenameB pmode is a flag which contains access=
privilege mode /its (s&stem specific information a/out allowed access) and fd is a
returned file handle" 0n the a/sence of an& information a/out pmode, this parameter
can /e set to Cero" Note that, the action of creating a file opens it too" Thus after a
call to creat, &ou should close the file descriptor"
Node:read, Next:write, Previous:creat, Up:4iles and 8evices
rea$()
This function gets a /loc- of information from a file" The data are loaded directl&
into memor&, as a se<uence of /&tes" The user must provide a place for them
(either /& ma-ing an arra& or /& using malloc() to reserve space)" read() -eeps
trac- of file positions automaticall&, so it actuall& reads the next /loc- of /&tes
from the current file position" The following example reads n /&tes from a file:
int return4alue( fd( n;
char *%uffer;
if ((%uffer = malloc(siNe)) == NUEE)
0
puts (&Gut of memory2n&);
errorKhandler ();
A
return4alue = read (fd(%uffer(n);
The return value should /e chec-ed" 0ts values are defined as follows:
@
End of file
-#
Error occurred
n
the num/er of /&tes actuall& read" (0f all went well this should /e e<ual to
n")
Node:write, Next:lsee-, Previous:read, Up:4iles and 8evices
write()
This function is the opposite of read()" 0t writes a /loc- of n /&tes from a
contiguous portion of memor& to a file which was opened /& open()" The form of
this function is:
int return4alue( fd( n;
char *%uffer;
return4alue = write (fd(%uffer(n);
The return value should, again, /e chec-ed for errors:
-#
Error
n
Num/er of /&tes written
Node:lsee-, Next:unlin- remove, Previous:write, Up:4iles and 8evices
lsee%()
ow level file handing functions have their e<uivalent of fsee6() for finding a
specific position within a file" This is almost identical to fsee6() except that it
uses the file handle rather than a file pointer as a parameter and has a different
return value" The constants should /e declared long int, or simpl& long"
-define L1EB< -#E
long int pos(offset(fd;
int mode(returncode;
if ((pos = fsee6 (fd(offset(mode)) == L1EB<)
0
printf(&BrrorI2n&);
A
pos gives the new file position if successful, and =( (long) if an attempt was made
to read past the end of the file" The values which mode can ta-e are:
@
3ffset measured relative to the /eginning of the file"
#
3ffset measured relative to the current position"
$
3ffset measured relative to the end of the file"
Node:unlin- remove, Next:Example G+, Previous:lsee-, Up:4iles and 8evices
unlin%() an$ remoe()
These functions delete a file from dis- storage" 3nce deleted, files are usuall&
irretrieva/le" The& return =( if the action failed"
-define L1EB< -#
int return4alue;
char *filename;
if (unlin6 (filename) == L1EB<)
0
printf (&Dan"t delete 's2n&(filename);
A
if (remo4e (filename) == L1EB<)
0
printf (&Dan"t delete 's2n&(filename);
A
filename is a string containing the name of the file concerned" This function can
fail if a file concerned is protected or if it is not found or if it is a device" (0t is
impossi/le to delete the printer;)
rename()
This function renames a file" The programmer specifies two filenames: the old
filename and a new file name" 7s usual, it returns the value =( if the action fails"
7n example illustrates the form of the rename() call:
-define L1EB< -#
char *old(*new;
if (rename(old(new) == L1EB<)
0
printf (&Dan"t rename 's as 's2n&(old(new);
A
rename() can fail /ecause a file is protected or /ecause it is in use, or /ecause one
of the filenames given was not valid"
Node:Example G+, Next:@uestions %H, Previous:unlin- remove, Up:4iles and
8evices
+/am*le
This example strings together some low level filing actions so as to illustrate their
use in a real program" The idea is to present a -ind of file or DproAectD menu for
creating, deleting, renaming files" 7 rather fee/le text editor allows the user to
enter %HH characters of text which can /e saved"
)***************************************************************)
)* *)
)* EG? EBSBE LEB H1N<ENR *)
)* *)
)***************************************************************)
-include .stdio.h/
-include .ctype.h/
-include .fcntl.h/ )* defines GKR<GNE\ etc.. *)
-define DG<B @
-define +FB $88
-define LNJ+FB 5@ )* Jax siNe of filenames *)
-define 3RUB #
-define L1E+B @
-define L1EB< -#
-define DER+DRN() putchar("2f")
-define NB?ENB() putchar("2n")
int fd;
)***************************************************************)
)* Ee4el @ *)
)***************************************************************)
main ()
0 char *data(get6ey()(*malloc();
if ((data = malloc(+FB)) == NUEE)
0
puts (&Gut of memory2n&);
return (DG<B);
A
while (3RUB)
0
menu();
switch (get6ey())
0
case "l" : EoadLile(data);
%rea6;
case "s" : +a4eLile(data);
%rea6;
case "e" : Bdit(data);
%rea6;
case "d" : <eleteLile();
%rea6;
case "r" : RenameLile();
%rea6;
case "O" : if (sure())
0
return (DG<B);
A
%rea6;
A
A
A
)*************************************************************)
)* Ee4el # *)
)*************************************************************)
menu ()
0
DER+DRN();
printf (& ---------------------------------2n&);
printf (&Q JBNU Q2n&);
printf (&Q [[[[[[ Q2n&);
printf (&Q Q2n&);
printf (&Q E) Eoad Lile Q2n&);
printf (&Q +) +a4e Lile Q2n&);
printf (&Q B) Bdit Lile Q2n&);
printf (&Q <) <elete Lile Q2n&);
printf (&Q R) Rename Lile Q2n&);
printf (&Q ]) ]uit Q2n&);
printf (&Q Q2n&);
printf (&Q +elect Gption and RB3URN Q2n&);
printf (&Q Q2n&);
printf (& --------------------------------- 2n&);
NB?ENB();
A
)*************************************************************)
EoadLile(data) )* Eow le4el load *)
char *data;
0 char *filename()(get6ey();
int error;
fd = open(filename()( GKR<GNE\);
if (fd == L1EB<)
0
printf (&Lile not found2n&);
return (L1EB<);
A
error = read (fd(data(+FB);
if (error == L1EB<)
0
printf (&Brror loading file2n&);
wait();
A
else
0
if (error I= +FB)
0
printf (&Lile was corrupted2n&);
wait();
A
A
close (fd(data(+FB);
return (error);
A
)*************************************************************)
+a4eLile(data) )* Eow Ee4el sa4e *)
char *data;
0 char *filename()(get6ey()(*fname;
int error(fd;
fd = open ((fname = filename())( GK?RGNE\);
if (fd == L1EB<)
0
printf (&Lile cannot %e written to2n&);
printf (&3ry to create new fileV \)N2n&);
if (yes())
0
if ((fd = DreateLile(fname)) == L1EB<)
0
printf (&Dannot create file 's2n&(fname);
return (L1EB<);
A
A
else
0
return (L1EB<);
A
A
error = write (fd(data(+FB);
if (error . +FB)
0
printf (&Brror writing to file2n&);
if (error I= L1EB<)
0
printf (&Lile only partially written2n&);
A
A
close (fd(data(+FB);
wait();
return (error);
A
)*************************************************************)
Bdit(data) )* primiti4e text editor *)
char *data;
0 char *ptr;
int ctr = @;
printf (&Dontents of file:2n2n&);
for (ptr = data; ptr . (data P +FB); ptrPP)
0
if (isprint(*ptr))
0
putchar(*ptr);
if ((ctrPP ' :@) == @)
0
NB?ENB();
A
A
A
printf (&2n2nBnter '#d characters:2n&(+FB);
for (ptr = data; ptr . (data P +FB); ptrPP)
0
*ptr = getchar();
A
s6ipgar%();
A
)*************************************************************)
<eleteLile() )* <elete a file from current dir *)
0 char *filename()(get6ey()(*fname;
printf (&<elete Lile2n2n&);
fname = filename();
if (sure())
0
if (remo4e(fname) == L1EB<)
0
printf (&Dan"t delete 's2n&(fname);
A
A
else
0
printf (&Lile NG3 deletedI2n&);
A
wait();
A
)*************************************************************)
RenameLile()
0 char oldXLNJ+FBY(*new;
printf (&Rename from GE< to NB?2n2nGE<: &);
strcpy (old(filename());
printf (&2nNB?: &);
new = filename();
if (rename(old(new) == L1EB<)
0
printf (&Dan"t rename 's as 's2n&(old(new);
A
wait();
A
)*************************************************************)
)* Ee4el $ *)
)*************************************************************)
DreateLile (fname)
char *fname;
0 int fd;
if ((fd = creat(fname(@)) == L1EB<)
0
printf (&Dan"t create file 's2n&(fname);
return (L1EB<);
A
return (fd);
A
)*************************************************************)
)* 3ool6it *)
)*************************************************************)
char *filename() )* return filename *)
0 static char statfilenmXLNJ+FBY;
do
0
printf (&Bnter filename :&);
scanf (&'$7s&(statfilenm);
s6ipgar%();
A
while (strlen(statfilenm) == @);
return (statfilenm);
A
)**************************************************************)
sure () )* is the user sure V *)
0
printf (&1re you a%solutely( unOuestiona%ly certainV \)N2n&);
return(yes());
A
)**************************************************************)
yes()
0 char get6ey();
while (3RUB)
0
switch(get6ey())
0
case "y" : return (3RUB);
case "n" : return (L1E+B);
A
A
A
)**************************************************************)
wait()
0 char get6ey();
printf (&,ress a 6ey2n&);
get6ey();
A
)**************************************************************)
char get6ey() )* single 6ey P RB3URN response *)
0 char ch;
ch = getchar();
s6ipgar%();
return((char)tolower(ch));
A
)**************************************************************)
s6ipgar%() )* s6ip gar%age corrupting input *)
0
while (getchar() I= "2n")
0
A
A
)* end *)
Node:@uestions %H, Previous:Example G+, Up:4iles and 8evices
.uestions
(" >hat are the followingF
(" 4ile name
%" 4ile pointer
G" 4ile handle
%" >hat is the difference /etween high and low level filingF
G" >rite a statement which opens a high level file for reading"
#" >rite a statement which opens a low level file for writing"
H" >rite a program which chec-s for illegal characters in text files" 5alid
characters are 76C00 codes ($,(G,and G%""(%M" 7n&thing else is illegal for
programs"
M" >hat statement performs formatted writing to text filesF
+" Print out all the header files on &our s&stem so that &ou can see what is
defined where;
Node:6tructures and Unions, Next:8ata structures, Previous:4iles and 8evices,
Up:Top
4tructures an$ ,nions
&rouping data. "idying up programs.
Tid& programs are a /lessing to programmers" Tid& data are Aust as important" 7s
programs /ecome increasingl& complex, their data also grow in complexit& and
single, independent varia/les or arra&s are no longer enough" >hat one then needs
is a data structure" This is where a new t&pe of varia/le comes in: it is called a
struct t&pe, or in other languages, a record" struct t&pes or structures are
usuall& lumped together with another t&pe of varia/le called a union" 0n fact their
purposes are <uite different"
.lac- .ox 8ata:
struct:
8eclarations again:
6cope again:
Using 6tructures:
7rra&s of 6tructures:
Example G*:
6tructures of 6tructures:
Pointers to 6tructures:
Example G):
Pre=initialiCing 6tatic 6tructures:
Creating ,emor& for 8&namical struct T&pes:
Unions:
@uestions %M:
Node:.lac- .ox 8ata, Next:struct, Previous:6tructures and Unions, Up:6tructures
and Unions
0rgani7ation9 Black Bo/ -ata
>hat is the relationship /etween a program and its dataF Thin- of a program as an
operator which operates on the memor& of the computer" ocal data are operated
upon inside sealed function capsules, where the& are protected from the reach of
certain parts of a program" !lo/al data are wide open to alteration /& an& part of a
program" 0f a program were visualiCed schematicall& what would it loo- li-eF 7
traditional flow diagramF No: a computer program onl& loo-s li-e a flow diagram
at the machine code level and that is too primitive for C programmers" 3ne wa& of
visualiCing a program is illustrated /& the diagram over the page"
This shows a program as a -ind of societ& of sealed function capsules which wor-
together li-e a /eehive of activit& upon a hone&com/ of program data" This
imaginative idea is not a /ad picture of a computer program, /ut it is not complete
either" 7 program has to manipulate data: it has to loo- at them, move them around
and cop& them from place to place" 7ll of these things would /e ver& difficult if
data were scattered a/out li/erall&, with no particular structure" 4or this reason C
has the facilit&, within it, to ma-e sealed capsules = not of program code = /ut of
program data, so that all of these actions ver& simpl& /& grouping varia/les
together in convenient pac-ages for handling" These capsules are called structures"
Node:struct, Next:8eclarations again, Previous:.lac- .ox 8ata, Up:6tructures and
Unions
struct
7 structure is a pac-age of one or usuall& more varia/les which are grouped under
a single name" 6tructures are not li-e arra&s: a structure can hold an& mixture of
different t&pes of data: it can even hold arra&s of different t&pes" 7 structure can /e
as simple or as complex as the programmer desires"
The word struct is a reserved word in C and it represents a new data t&pe, called
an aggregate t&pe" 0t is not an& single t&pe: the purpose of structures is to offer a
tool for ma-ing whatever shape or form of varia/le pac-age that a programmer
wishes" 7n& particular structure t&pe is given a name, called a structure=name and
the varia/les (called mem/ers) within a structure t&pe are also given names"
4inall&, ever& varia/le which is declared to /e a particular structure t&pe has a
name of its own too" This plethora of names is not reall& as complicated as it
sounds"
Node:8eclarations again, Next:6cope again, Previous:struct, Up:6tructures and
Unions
-eclarations
7 structure is declared /& ma-ing a /lan- template for a varia/le pac-age" This is
most easil& seen with the help of an example" The following statement is actuall& a
declaration, so it /elongs with other declarations, either at the head of a program or
at the start of a /loc-"
struct ,ersonal<ata
0
char nameXnamesiNeY;
char addressXaddresssiNeY;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A;
This purpose of this statement is to create a model or template to define what a
varia/le of t&pe struct ,ersonal<ata will loo- li-e" 0t sa&s: define a t&pe of
varia/le which collectivel& holds a string called name, a string called address and
three integers called \earGf9irth, JonthGf9irth and <ayGf9irth" 7n& varia/le
which is declared to /e of t&pe struct ,ersonal<ata will /e collectivel& made
up of parts li-e these" The list of varia/le components which ma-e up the structure
are called the mem/ers of the structure: the names of the mem/ers are not the
names of varia/les, /ut are a wa& of naming the parts which ma-e up a structure
varia/le" (Note: a varia/le which has /een declared to /e of t&pe struct
something is usuall& called Aust a structure rather than a structure varia/le" The
distinction is maintained here in places where confusion might arise") The names
of mem/ers are held separate from the names of other identifiers in C, so it is <uite
possi/le to have varia/le names and struct mem/er names which are the same"
3lder compilers did not support this luxur&"
7t this stage, no storage has /een given over to a varia/le, nor has an& varia/le
/een declared: onl& a t&pe has /een defined" 9aving defined this t&pe of structure,
however, the programmer can declare varia/les to /e of this t&pe" 4or example:
struct ,ersonal<ata x;
declares a varia/le called x to /e of t&pe struct ,ersonal<ata" x is certainl& not
a ver& good name for an& varia/le which holds a person:s personal data, /ut it
contrasts well with all the other names which are a/ound and so it serves its
purpose for now"
.efore moving on to consider how structures can /e used, it is worth pausing to
show the different wa&s in which structures can /e declared" The method shown
a/ove is pro/a/l& the most common one, however there are two e<uivalent
methods of doing the same thing" 7 varia/le can /e declared immediatel& after the
template definition"
struct ,ersonal<ata
0
char nameXnamesiNeY;
char addressXaddresssiNeY;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A
x; )* 4aria%le identifier follows type *)
7lternativel&, typedef can /e used to cut down a /it on t&ping in the long term"
This t&pe definition is made once at the head of the program and then su/se<uent
declarations are made /& using the new name:
typedef struct
0
char nameXnamesiNeY;
char addressXaddresssiNeY;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A
,ersonal<ata;
then declare:
,ersonal<ata x;
7n& one of these methods will do"
Node:6cope again, Next:Using 6tructures, Previous:8eclarations again,
Up:6tructures and Unions
4co*e
.oth structure t&pes and structure varia/les o/e& the rules of scope: that is to sa&, a
structure t&pe declaration can /e local or glo/al, depending upon where the
declaration is made" 6imilarl& if a structure t&pe varia/le is declared locall& it is
onl& valid inside the /loc- parentheses in which it was defined"
main ()
0 struct GNB
0
int a;
float %;
A;
struct GNB x;
A
function ()
0 struct GNB x; )* 3his line is illegal( since GNB *)
)* is a local type definition *)
)* <efined only in main() *)
A
Node:Using 6tructures, Next:7rra&s of 6tructures, Previous:6cope again,
Up:6tructures and Unions
,sing 4tructures
9ow does a program use the varia/les which are loc-ed inside structuresF The
whole point a/out structures is that the& can /e used to group data into sensi/le
pac-ages which can then /e treated as single o/Aects" Earl& C compilers, some of
which still exist toda&, placed ver& severe restrictions upon what a program could
do with structures" Essentiall&, the mem/ers of a structure could /e assigned values
and pointers to individual structures could /e found" 7lthough this sounds highl&
restrictive, it did account for the most fre<uent uses of structures" ,odern
compilers allow more flexi/le use of structures: programs can assign one structure
varia/le to another structure varia/le (provided the structures match in t&pe)B
structure varia/les can /e passed, whole, as parameters to functions and functions
can return structure values" This ma-es structures extremel& powerful data o/Aects
to have in a program" 7 structure is assigned to another structure /& the following
statements"
struct ,ersonal x(y;
x = y;
The whole /undle of mem/ers is copied in one statement; 6tructures are passed as
parameters in the usual wa&:
function (x(y);
The function then has to /e declared:
function (x(y)
struct ,ersonal<ata x(y;
0
A
4inall&, a function which returns a structure varia/le such as:
0 struct ,ersonal<ata x(function();
x = function();
A
would /e declared in the following wa&:
struct ,ersonal<ata function ()
0
A
Notice that the return t&pe of such a function must also /e declared in the function
which calls that it, in the usual wa&" The reader will /egin to see that structure
names account for a good deal of t&ping; The t&pedef statement is a ver& good wa&
of reducing this /urden"
The mem/ers of a structure are accessed with the . dot character" This is a
structure member operator" Consider the structure varia/le x, which has the t&pe
struct ,ersonal<ata" The mem/ers of x could /e assigned /& the following
program:
main ()
0 struct ,ersonal<ata x;
Lill1rray (&+ome name&( x.name);
Lill1rray (&+ome address&( x.address);
x.\earGf9irth = #>=;;
x.JonthGf9irth = $;
x.<ayGf9irth = #>;
A
where Lill1rray() is a h&pothetical function which copies the string in the first
parameter to the arra& in the second parameter" The dot /etween the varia/le and
the names which follow implies that the statements in this /rief program are
tal-ing a/out the mem/ers in the structure varia/le x, rather than the whole
collective /undle" ,em/ers of actual structure varia/les are alwa&s accessed with
this dot operator" The general form of a mem/er reference is:
structure variable.member name
This applies to an& t&pe of structure varia/le, including those accessed /& pointers"
>henever a program needs to access the mem/ers of a structure, this dot operator
can /e used" C provides a special mem/er operator for pointers, however, /ecause
the& are used so often in connection with structures" This new operator is descri/ed
/elow"
Node:7rra&s of 6tructures, Next:Example G*, Previous:Using 6tructures,
Up:6tructures and Unions
8rra1s of 4tructures
Yust as arra&s of an& /asic t&pe of varia/le are allowed, so are arra&s of a given
t&pe of structure" 7lthough a structure contains man& different t&pes, the compiler
never gets to -now this information /ecause it is hidden awa& inside a sealed
structure capsule, so it can /elieve that all the elements in the arra& have the same
t&pe, even though that t&pe is itself made up of lots of different t&pes" 7n arra&
would /e declared in the usual wa&:
int i;
struct ,ersonal<ata x(arrayXsiNeY;
The mem/ers of the arra&s would then /e accessed /& statements li-e the
following examples:
arrayXiY = x;
arrayXiY = arrayXUY;
arrayXiY.\earGf9irth = #>=;;
i = arrayX$Y.JonthGf9irth;
Node:Example G*, Next:6tructures of 6tructures, Previous:7rra&s of 6tructures,
Up:6tructures and Unions
+/am*le
This listing uses a structure t&pe which is slightl& different to Personal8ata in that
string pointers are used instead of arra&s" This allows more convenient handling of
real=life strings"
)*********************************************************)
)* *)
)* +tructures <emo *)
)* *)
)*********************************************************)
)* +imple program to initialiNe some structures *)
)* and to print them out again. <oes no error *)
)* chec6ing( so %e wary of string siNes etc.. *)
-include .stdio.h/
-define N1JB+FB 5@
-define 1<<R+FB =@
-define NGGL,BR+GN+ $@
-define NB?ENB() putchar("2n");
)*********************************************************)
typedef struct
0
char *Name;
char *1ddress;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A
,erson<at;
)*********************************************************)
main () )* Ja6e some records *)
0 ,erson<at recordXNGGL,BR+GN+Y;
,erson<at ,ersonal<etails();
int person;
printf (&9irth Records Lor Bmployees&);
printf (&2n---------------------------&);
printf (&2n2n&);
printf (&Bnter data2n&);
for (person = @; person . NGGL,BR+GN+; personPP)
0
recordXpersonY = ,ersonal<etails();
NB?ENB();
A
<isplayRecords (record);
A
)*********************************************************)
,erson<at ,ersonal<etails() )* No error chec6ingI *)
0 ,erson<at dat;
char str%uffX1<<R+FBY( *malloc();
printf (&Name :&);
dat.Name = malloc(N1JB+FB);
strcpy (dat.Name(gets(str%uff));
printf (&1ddress :&);
dat.1ddress = malloc(1<<R+FB);
strcpy (dat.1ddress(gets(str%uff));
printf (&\ear of %irth:&);
dat.\earGf9irth = getint (#>@@(#>=;);
printf (&Jonth of %irth:&);
dat.JonthGf9irth = getint (#(#$);
printf (&<ay of %irth:&);
dat.<ayGf9irth = getint(#(5#);
return (dat);
A
)**********************************************************)
<isplayRecords (rec)
,erson<at recXNGGL,BR+GN+Y;
0 int pers;
for (pers = @; pers . NGGL,BR+GN+; persPP)
0
printf (&Name : 's2n&( recXpersY.Name);
printf (&1ddress : 's2n&( recXpersY.1ddress);
printf(&<ate of 9irth: '#d)'#d)'#d2n&(recXpersY.<ayGf9irth(
recXpersY.JonthGf9irth(recXpersY.\earGf9irth);
NB?ENB();
A
A
)**********************************************************)
)* 3ool6it *)
)**********************************************************)
getint (a(%) )* return int %etween a and % *)
int a(%;
0 int p( i = a - #;
for (p=@; ((a / i) QQ (i / %)); pPP)
0
printf (&V : &);
scanf (&'d&(Mi);
if (p / $)
0
s6ipgar%();
p = @;
A
A
s6ipgar%();
return (i);
A
)**********************************************************)
s6ipgar%() )* +6ip input gar%age corrupting scanf *)
0
while (getchar() I= "2n")
0
A
A
)* end *)
Node:6tructures of 6tructures, Next:Pointers to 6tructures, Previous:Example G*,
Up:6tructures and Unions
4tructures of 4tructures
6tructures are said to nest" This means that structure templates can contain other
structures as mem/ers" Consider two structure t&pes:
struct firstKstructure
0
int 4alue;
float num%er;
A;
and
struct secondKstructure
0
int tag;
struct firstKstructure fs;
A
x;
These two structures are of different t&pes, &et the first of the two is included in the
second; 7n instance of the second structure would /e initialiCed /& the following
assignments" The structure varia/le name is x:
x.tag = #@;
x.fs.4alue = $@;
x.fs.num%er = 5@.@;
Notice the wa& in which the mem/er operator . can /e used over and over again"
Notice also that no parentheses are necessar&, /ecause the reference which is
calculated /& this operator is wor-ed out from left to right" This nesting can, in
principle, go on man& times, though some compilers might place restrictions upon
this nesting level" 6tatements such as:
4aria%le.tag#.tag$.tag5.tag7 = something;
are pro/a/l& o-a& (though the& do not reflect good programming)" 6tructures
should nest safel& a few times"
7 word of caution is in order here" There is a pro/lem with the a/ove scheme that
has not &et /een addressed" 0t is this: what happens if a structure contains an
instance of itselfF 4or example:
struct Regression
0
int i;
struct Regression tag;
A
There is simpl& no wa& that this -ind of statement can ma-e sense, unless the
compiler:s target computer has an infinite suppl& of memor&; 1eferences to
varia/les of this t&pe would go on for ever and an infinite amount of memor&
would /e needed for ever& varia/le" 4or this one reason, it is for/idden for a
structure to contain an instance of itself" >hat is not for/idden, however, is for a
structure to contain an instance of a pointer to its own t&pe (/ecause a pointer is
not the same t&pe as a structure: it is merel& a varia/le which holds the address of a
structure)" Pointers to structures are <uite invalua/le, in fact, for /uilding data
structures such as lin-ed lists and trees" These extremel& valua/le devices are
descri/ed /elow"
Node:Pointers to 6tructures, Next:Example G), Previous:6tructures of 6tructures,
Up:6tructures and Unions
Pointers to 4tructures
7 pointer to a structure t&pe varia/le is declared /& a statement li-e:
struct Name *ptr;
ptr is then, formall&, a pointer to a structure of t&pe Name onl&" ptr can /e
assigned to an& other pointer of similar t&pe and it can /e used to access the
mem/ers of a structure" 0t is in the second of these actions that a new structure
operator is revealed" 7ccording to the rules which have descri/ed so far, a structure
mem/er could /e accessed /& pointers with the following statements:
struct ,ersonal<ata *ptr;
(*ptr).\earGf9irth = $@;
This sa&s let the mem/er \earGf9irth of the structure pointed to /& ptr, have the
value %$" Notice that *ptr, /& itself, means the contents of the address which is
held in ptr and notice that the parentheses around this statement avoid an&
confusion a/out the precedence of these operators" There is a /etter wa& to write
the a/ove statement, however, using a new operator: -/" This is an arrow made out
of a minus sign and a greater than s&m/ol and it is used simpl& as follows:
struct ,ersonal<ata *ptr;
ptr-/\earGf9irth = $@;
This statement is identical in ever& wa& to the first version, /ut since this -ind of
access is re<uired so fre<uentl&, when dealing with structures, C provides this
special operator to ma-e the operation clearer" 0n the statements a/ove, it is
assumed that ptr has /een assigned to the address of some pre=assigned structure:
for example, /& means of a statement such as:
ptr = Mx;
where x is a pre=assigned structure"
Node:Example G), Next:Pre=initialiCing 6tatic 6tructures, Previous:Pointers to
6tructures, Up:6tructures and Unions
+/am*le
)*********************************************************)
)* *)
)* +tructures <emo -$ *)
)* *)
)*********************************************************)
)* 3his is the same program( using pointer references *)
)* instead of straight 4aria%le references. i.e. this *)
)* uses 4aria%le parameters instead of 4alue params *)
-include .stdio.h/
-define N1JB+FB 5@
-define 1<<R+FB =@
-define NGGL,BR+GN+ $@
-define NB?ENB() putchar("2n");
)*********************************************************)
typedef struct
0
char *Name;
char *1ddress;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A
,erson<at;
)*********************************************************)
main () )* Ja6e some records *)
0 ,erson<at recordXNGGL,BR+GN+Y;
int person;
printf (&9irth Records Lor Bmployees&);
printf (&2n---------------------------&);
printf (&2n2n&);
printf (&Bnter data2n&);
for (person = @; person . NGGL,BR+GN+; personPP)
0
,ersonal<etails(M(recordXpersonY));
NB?ENB();
A
<isplayRecords (record);
A
)*********************************************************)
,ersonal<etails(dat) )* No error chec6ingI *)
,erson<at *dat;
0 char str%uffX1<<R+FBY( *malloc();
printf (&Name :&);
dat-/Name = malloc(N1JB+FB);
strcpy (dat-/Name(gets(str%uff));
printf (&1ddress :&);
dat-/1ddress = malloc(1<<R+FB);
strcpy (dat-/1ddress(gets(str%uff));
printf (&\ear of %irth:&);
dat-/\earGf9irth = getint (#>@@(#>=;);
printf (&Jonth of %irth:&);
dat-/JonthGf9irth = getint (#(#$);
printf (&<ay of %irth:&);
dat-/<ayGf9irth = getint(#(5#);
A
)**********************************************************)
<isplayRecords (rec)
,erson<at recXNGGL,BR+GN+Y;
0 int pers;
for (pers = @; pers . NGGL,BR+GN+; persPP)
0
printf (&Name : 's2n&( recXpersY.Name);
printf (&1ddress : 's2n&( recXpersY.1ddress);
printf(&<ate of 9irth: '#d)'#d)'#d2n&(recXpersY.<ayGf9irth(
recXpersY.JonthGf9irth(recXpersY.\earGf9irth);
NB?ENB();
A
A
)**********************************************************)
)* 3ool6it *)
)**********************************************************)
)* 1s %efore *)
Node:Pre=initialiCing 6tatic 6tructures, Next:Creating ,emor& for 8&namical
struct T&pes, Previous:Example G), Up:6tructures and Unions
Pre@initiali7ing 4tatic 4tructures
0n the chapter on arra&s it was shown how static and external t&pe arra&s could /e
initialiCed with values at compile time" 6tatic and external structures can also /e
pre=assigned /& the compiler so that programs can set up options and starting
conditions in a convenient wa&" 7 static varia/le of t&pe ,erson<at (as in the
example programs) could /e declared and initialiCed in the same statement:
-define N1JB+FB $@
-define 1<<RB+++FB $$
struct ,erson<at
0
char *name;
char *address;
int \earGf9irth;
int JonthGf9irth;
int <ayGf9irth;
A;
main ()
0 static struct ,ersonal<ata 4aria%le =
0
&1lice ?onderment&(
&+omewhere in ,aradise&(
#>:8(
8(
#$
A;
)* rest of program *)
A
The items in the curl& /races are matched to the mem/ers of the structure varia/le
and an& items which are not initialiCed /& items in the list are filled out with Ceros"
Node:Creating ,emor& for 8&namical struct T&pes, Next:Unions, Previous:Pre=
initialiCing 6tatic 6tructures, Up:6tructures and Unions
Creating Memor1 for -1namical struct T1*es
Pro/a/l& the single most fre<uent use of struct t&pe varia/les is in the /uilding of
d&namical data structures" 8&namical data are data which are created explicitl& /&
a program using a scheme of memor& allocation and pointers" Normal program
data, which are reserved space /& the compiler, are, in fact, static data structures
/ecause the& do not change during the course of a program: an integer is alwa&s an
integer and an arra& is alwa&s an arra&: their siCes cannot change while the
program is running" 7 d&namical structure is /uilt using the memor& allocation
function:
malloc()
and pointers" The idea is to create the memor& space for a new structure as and
when it is needed and to use a pointer to access the mem/ers of that structure,
using the -/ operator" malloc() was descri/ed in connection with strings: it
allocates a fixed num/er of /&tes of memor& and returns a pointer to that data" 4or
instance, to allocate ten /&tes, one would write something li-e this:
char *malloc()( *ptr;
ptr = malloc(#@);
ptr is then a pointer to the start of that /loc- of ($ /&tes" >hen a program wants
to create the space for a structure, it has a template for that structure, which was
used to define it, /ut it does not generall& -now, in advance, how man& /&tes long
a structure is" 0n fact, it is seldom possi/le to -now this information, since a
structure ma& occup& more memor& than the sum of its parts" 9ow then does a
program -now how must space to allocateF The C compiler comes to the rescue
here, /& providing a compile time operator called
siNeof ()
which calculates the siCe of an o/Aect while a program is compiling" 4or example:
siNeof(int)
>or-s out the num/er of /&tes occupied /& the t&pe int"
siNeof(char)
>or-s out the num/er of /&tes occupied /& a single character" This e<uals (,
in fact"
siNeof(struct ,ersonal<ata) wor-s out the num/er of /&tes needed to store a
single structure varia/le" 3/viousl& this tool is ver& useful for wor-ing with
malloc()" The memor& allocation statement /ecomes something li-e:
ptr = malloc(siNeof(type name));
There is a pro/lem with this statement though: malloc() is declared as a function
which returns a t&pe Ipointer to character: whereas, here, the programmer is
interested in pointers of t&pe Dpointer to struct 6omethingD" malloc() has to /e
forced to produce a pointer of the correct t&pe then and this is done /& using the
cast operator to mould it into shape" The cast operator casts pointers with a general
form:
(type *) 4alue
Consider the following example of C source code which allocates space for a
structure t&pe called +ome+truct and creates a correctl& aligned pointer to it,
called ptr"
struct +ome+truct *ptr;
char *malloc();
ptr = (struct +ome+truct *) malloc(siNeof(struct +omestruct));
This rather la/oured statement provides /oth the memor& and the location of that
memor& in a legal and t&pe=sensical wa&" The next section of this /oo- discusses
what we can do with d&namicall& allocated structures"
Node:Unions, Next:@uestions %M, Previous:Creating ,emor& for 8&namical struct
T&pes, Up:6tructures and Unions
,nions
7 union is li-e a structure in which all the Imem/ers: are stored at the same
address" Clearl& the& cannot all /e there at the same time" 3nl& one mem/er can /e
stored in such an o/Aect at an& one time, or it would /e overwritten /& another"
Unions /ehave li-e speciall& siCed storage containers which can hold man&
different t&pes of data" 7 union can hold an& one of its mem/ers /ut onl& at
different times" The compiler arranges that a union t&pe varia/le is /ig enough to
handle the Ao/"
The real purpose of unions is to prevent memor& fragmentation /& arranging for a
standard siCe for data in the memor&" .& having a standard data siCe we can
guarantee that an& hole left when d&namicall& allocated memor& is freed will
alwa&s /e reusa/le /& another instance of the same t&pe of union" This is a natural
strateg& in s&stem programming where man& instances of different -inds of
varia/les with a related purpose and stored d&namicall&"
8eclaration of union:
Using unions:
Node:8eclaration of union, Next:Using unions, Previous:Unions, Up:Unions
-eclaration
7 union is declared in the same wa& as a structure" 0t has a list of mem/ers, which
are used to mould the t&pe of o/Aect concerned"
union ntGrLloat
0
int ordinal;
float continuous;
A;
This declares a t&pe template" 5aria/les are then declared as:
union ntGrLloat x(y(N;
7t different times the program is to treat x,y and N as /eing either integers or float
t&pes" >hen the varia/les are referred to as
x.ordinal = #;
the program sees x as /eing an integer t&pe" 7t other times (when x is referred to as
x.continuous) it ta-es on another aspect: its alter ego, the float t&pe" Notice that
x /& itself does not have a value: onl& its mem/ers have values, x is Aust a /ox for
the different mem/ers to share"
Node:Using unions, Previous:8eclaration of union, Up:Unions
,sing unions
Unions are coded with the same constructions as structures" The dot . operator
selects the different mem/ers for varia/le and the arrow -/ selects different values
for pointers" The form of such statements is:
unionK4aria%le.mem%er;
unionKpointer-/mem%er;
Unions are seldom ver& useful o/Aects to have in programs, since a program has no
automatic wa& of -nowing what t&pe of mem/er is currentl& stored in the union
t&pe" 3ne wa& to overcome this is to -eep a varia/le which signals the t&pe
currentl& held in the varia/le" This is done ver& easil& with the aid of enumerated
data" Consider the following -ind of union:
union ?hich3ype
0
int ordinal;
float continuous;
char letter;
A;
This could /e accompanied /& an enumerate declaration such as:
enum 3ypes
0
N3(
LEG13(
DH1R
A;
5aria/les could then go in pairs:
union ?hich3ype x;
enum 3ypes xKstatus;
which would ma-e union t&pe=handling straightforward:
switch (xKstatus)
0
case N3 : x.ordinal = #$;
%rea6;
case LEG13 : x.continuous = #$.$5;
%rea6;
case DH1R : x.letter = "*";
A
These varia/les could even /e grouped into a structure:
struct UnionKHandler
0
union ?hich3ype x;
enum 3ypes xKstatus;
A
4ar;
which would then re<uire statements such as:
4ar.x.ordinal = $;
ptr-/x.ordinal = $;
4ar.xKstatus = DH1R;
and so on"""
Node:@uestions %M, Previous:Unions, Up:6tructures and Unions
.uestions
(" >hat is the difference /etween a structure and a unionF
%" >hat is a mem/erF
G" 0f x is a varia/le, how would &ou find out the value of a mem/er called mem"
#" 0f ptr is a pointer to a structure, how would &ou find out the value of a
mem/er called mem"
H" 7 union is a group of varia/les in a single pac-age" True or falseF
Node:8ata structures, Next:1ecursion, Previous:6tructures and Unions, Up:Top
-ata 4tructures
8ses for struct variables. Structure diagrams.
8ata structures are organiCed patterns of data" The purpose of /uilding a data
structure is to create a pattern of information which models a particular situation
clearl& and efficientl&" Ta-e the simplest -ind of data structure: the arra&" 7rra&s
are good for storing patterns of information which loo- li-e ta/les, or share a
ta/ular structure" 4or example, a chess /oard loo-s li-e a two dimensional arra&, so
a chess game would naturall& use a two dimensional arra& to store the positions of
pieces on the chess /oard" The aim of a data structure is to model real life patterns
with program data"
,ost real application programs re<uire a more complex data structure than C
varia/les can offerB often arra&s are not suita/le structures for a given application"
To see this, consider an application example in which a program stores a map of
the local countr&side" This program has to store information a/out individual towns
and it has to /e a/le to give directions to the user a/out how to get to particular
towns from some reference point" 0n real life, all of this information is most easil&
conve&ed /& means of a map, with towns: vital statistics written on it" (6ee figure
(") The diagram shows such a simplified map of the surrounding land" This sort of
map is, ideall&, Aust what a computer ought to /e a/le to store" The handicap is that
the map does not loo- ver& computerish" 0f the map is ever going to /e stored in a
computer it will need to loo- more mechanical" 7 transformation is needed" 0n
order to ma-e the map into a more computer=li-e picture, it must /e drawn as a
structure diagram"
7 structure diagram is a picture which shows how something is connected up"
,ost often a structure diagram shows how a pro/lem is connected up /& relating
all the parts which go together to ma-e it up" 0n this case, the structure diagram Aust
shows how program data are related to each other"
8ata 6tructure 8iagrams:
Tools:
Programme 4or .uilding 8ata 6tructures:
6etting Up 7 8ata 6tructure:
Example 6tructures:
@uestions %+:
Node:8ata 6tructure 8iagrams, Next:Tools, Previous:8ata structures, Up:8ata
structures
-ata 4tructure -iagrams
Now examine figure %" This diagram is a data structure diagram: it is a diagram
which shows how /oxes of data must relate to one another in order to solve the
pro/lem of the towns map" 0t has /een drawn, <uite deli/eratel&, in a wa& which is
intended to conAure up some particular thoughts" The arrows tend to suggest that
pointers will pla& a role in the data structure" The /loc-s tend to suggest that sealed
capsules or struct t&pe data will also pla& a role" Putting these two together
creates the idea of a Itown structure: containing pointers to neighouring villages
which lie on roads to the North, 6outh, East and >est of the town, as well as the
information a/out the town itself" This town structure might loo- something li-e
this:
struct 3own
0
struct 3own *north;
struct 3own *south;
struct 3own *east;
struct 3own *west;
struct Eocalnfo help;
A;
7ssume for now that Eocalnfo is a structure which contains all the information
a/out a town re<uired /& the program" This part of the information is actuall&
irrelevant to the structure of the data /ecause it is hidden inside the sealed capsule"
0t is the pointers which are the main items of concern /ecause it is pointers which
contain information that ena/les a program to find its wa& around the map ver&
<uic-l&" 0f the user of this imaginar& application program wished to -now a/out
the town to the north of one particular place, the program would onl& have to
refocus its attention on the new structure which was pointed to /& the struct
mem/er north and similarl& for other directions"
7 data structure is /uilt up, li-e a model, /& connecting struct t&pe varia/les
together with pointers: these are the /uilding /loc-s"
.& thin-ing of struct t&pes and pointers in terms of pictures, one /egins to see how
structures can /e fashioned, in computer memor&, to loo- exactl& li-e the pro/lems
which the& represent"
>hat is interesting a/out data structure diagrams is the wa& in which the&
resem/le the structure diagrams of C programs, which were drawn in chapter +"
There is a simple reason for this similarit&: computer programs are themselves Aust
data structures in which the data are program instructions and the pointers and
sealed /oxes are function calls" The structure of a computer program is called a
hierach&" 6ometimes the shape of data structures and programs are identicalB when
this happens, a -ind of optimum efficienc& has /een reached in conceptual terms"
Programs which /ehave exactl& li-e their data operate ver& simpl&" This is the
reason wh& structure diagrams are so useful in programming: a structure diagram
is a diagram which solves a pro/lem and does so in a pictorial wa&, which models
the wa& we thin-"
Node:Tools, Next:Programme 4or .uilding 8ata 6tructures, Previous:8ata
6tructure 8iagrams, Up:8ata structures
T&e Tools9 4tructures" Pointers an$ -1namic Memor1
The tools of the data structure trade are struct t&pes and pointers" 8ata structures
are /uilt out of d&namicall& allocated memor&, so storage places do not need
names: all a program needs to do is to -eep a record of a pointer, to a particular
storage space, and the computer will /e a/le to find it at an& time after that"
Pointers are the -e&s which unloc- a program:s data" The reader might o/Aect to
this /& sa&ing that a pointer has to /e stored in some C varia/le somewhere, so
does a program reall& gain an&thing from wor-ing with pointersF The answer is
&es, /ecause pointers in data structures are invaria/l& chained together to ma-e up
the structure" To understand this, ma-e a note of the following terms:
7oot
This is a place where a data structure starts" Ever& chain has to start
somewhere" The address of the root of a data structure has to /e stored
explicitl& in a C varia/le"
3in#s
7 lin- is a pointer to a new struct t&pe" in-s are used to chain structures
together" The address of the next element in a chain structure is stored inside
the previous structure"
8ata structures do not have to /e linear chains and the& are often not" 6tructures,
after all, can hold an& num/er of pointers to other structures, so there is the
potential to /ranch out into an& num/er of new structures" 0n the map example
a/ove, there were four pointers in each structure, so the chaining was not linear,
/ut more li-e a latticewor-"
>e need to thin- a/out where and how data structures are going to /e stored"
1emem/er that pointers alone do not create an& storage space: the& are onl& a wa&
of finding out the contents of storage space which alread& exists" 0n fact, a program
must create its own space for data structures" The -e& phrase is d&namic storage: a
program ma-es space for structures as new ones are re<uired and deletes space
which is does not re<uire" The functions which perform this memor& allocation and
release are:
malloc() and free()
There are some advantages which go with the use of d&namic storage for data
structures and the& are summariCed /& the following points:
6ince memor& is allocated as it is needed, the onl& restriction on data siCe is
the memor& capacit& of the computer" >e don:t need to declare how much
we shall use in advance"
Using pointers to connect structures means that the& can /e re=connected in
different wa&s as the need arises" (8ata structures can /e sorted, for
example")
8ata structures can /e made up of lots of DlesserD data structures, each held
inside struct t&pe storage" The limitations are few"
The remaining parts of this section aim to provide a /asic plan or formula for
putting data structures together in C" This is done with recourse to two example
structures, which /ecome two example programs in the next chapter"
Node:Programme 4or .uilding 8ata 6tructures, Next:6etting Up 7 8ata 6tructure,
Previous:Tools, Up:8ata structures
Programme 2or Buil$ing -ata 4tructures
0n writing programs which centre around their data, such as word processors,
accounts programs or data/ase managers, it is extremel& important to plan data
structures /efore an& program code is written: changes in program code do not
affect a data structure, /ut alterations to a data structure impl& drastic changes to
program code" 3nl& in some numerical applications does a data structure actuall&
assist an algorithm rather than vice versa" The steps which a programmer would
underta-e in designing a data structure follow a /asic pattern:
!roup all the data, which must /e stored, together and define a struct t&pe to
hold them"
Thin- of a pattern which reflects the wa& in which the data are connected
and add structure pointers to the struct definition, to connect them"
8esign the programming algorithms to handle the memor& allocation, lin-
pointers and data storage"
Node:6etting Up 7 8ata 6tructure, Next:Example 6tructures, Previous:Programme
4or .uilding 8ata 6tructures, Up:8ata structures
4etting ,* 8 -ata 4tructure
3nce the /asic mould has /een cast for the /uilding /loc-s, a program actuall& has
to go through the motions of putting all the pieces together, /& connecting
structures together with pointers and filling them up with information" The data
structure is set up /& repeating the following actions as man& times as is necessar&"
8efine a struct t&pe" 4or example:
struct 3own
0
struct 3own *north;
struct 3own *south;
struct 3own *east;
struct 3own *west;
struct Eocalnfo help;
A;

8eclare two pointers to this t&pe:


struct 3own *ptr(*root;

3ne of these is used to hold the root of the data structure and the other is
used as a current pointer"
7llocate memor& for one structure t&pe:
root = (struct 3own *) malloc(siNeof(struct 3own));

You might also like