You are on page 1of 152

1

C Programming
An Introduction
About C
As a programming language, C is rather like Pascal or Fortran.. Values are stored in variables.
Programs are structured by defining and calling functions. Program flow is controlled using loops, if
statements and function calls. nput and output can be directed to the terminal or to files. !elated data
can be stored together in arrays or structures.
"f the three languages, C allows the most precise control of input and output. C is also rather more
terse than Fortran or Pascal. #his can result in short efficient programs, where the programmer has
made wise use of C$s range of powerful operators. t also allows the programmer to produce programs
which are impossible to understand.
Programmers who are familiar with the use of pointers %or indirect addressing, to use the correct term&
will welcome the ease of use compared with some other languages. 'ndisciplined use of pointers can
lead to errors which are very hard to trace. #his course only deals with the simplest applications of
pointers.
t is hoped that newcomers will find C a useful and friendly language. Care must be taken in using C.
(any of the e)tra facilities which it offers can lead to e)tra types of programming error. *ou will have
to learn to deal with these to successfully make the transition to being a C programmer.
Common C
'ntil recently there was one dominant form of the C language. #his was the native '+, form, which
for historical reasons is known as either -ell .abs C, after the most popular compiler, or /. 0!. C,
after the authors of the most popular te)tbook on the language. t is now often called 1Classic C1
ANSI C
#he American +ational 2tandards nstitute defined a standard for C, eliminating much uncertainty
about the e)act synta) of the language. #his newcomer, called A+2 C, proclaims itself the standard
version of the language. As such it will inevitably overtake, and eventually replace common C.
A+2 C does incorporate a few improvements over the old common C. #he main difference is in the
grammar of the language. #he form of function declarations has been changed making them rather
more like Pascal procedures.
3
#his course introduces A+2 C since it is supported by the 2'+ workstation compilers. (ost C
programming te)ts are now available in A+2 editions.
A Simple Program
#he following program is written in the C programming language.
#include <stdio.h>
main()
{
printf("Programming in C is easy.\n");

A NOTE ABOUT C PROGRAMS


n C, lowercase and uppercase characters are very important4 All commands in C must be lowercase.
#he C programs starting point is identified by the word
main()
#his informs the computer as to where the program actually starts. #he brackets that follow the
keyword main indicate that there are no arguments supplied to this program %this will be e)amined
later on&.
#he two braces, 5 and 6, signify the begin and end segments of the program. #he purpose of the
statment
include <stdio.h>
is to allow the use of the printf statement to provide program output. #e)t to be displayed by printf()
must be enclosed in double 7uotes. #he program has only one statement
printf("Programming in C is easy.\n");
printf() is actually a function %procedure& in C that is used for printing variables and te)t. 8here te)t
appears in double 7uotes 11, it is printed without modification. #here are some e)ceptions however.
#his has to do with the 9 and : characters. #hese characters are modifier$s, and for the present the 9
followed by the n character represents a newline character. #hus the program prints
Programming in C is easy.
and the cursor is set to the beginning of the ne)t line. As we shall see later on, what follows the 9
character will determine what is printed, ie, a tab, clear screen, clear line etc. Another important thing
to remember is that all C statements are terminated by a semi;colon <
Summary of major points
program e)ecution begins at main()
=
keywords are written in lower;case
statements are terminated with a semi;colon
te)t strings are enclosed in double 7uotes
C is case sensitive, use lower;case and try not to capitalise variable names
9n means position the cursor on the beginning of the ne)t line
printf() can be used to display te)t to the screen
#he curly braces 56 define the beginning and end of a program block.
! E"ERC#SE C$
8hat will the following program output>
#include <stdio.h>
main()
{
printf("Programming in C is easy.\n");
printf("!nd so is Pascal.\n");

" Programming in C is easy.


!nd so is Pascal.
And this program>
#include <stdio.h>
main()
{
printf("#he $lac% dog &as $ig. ");
printf("#he co& 'umped o(er the moon.\n");

" #he $lac% dog &as $ig. #he co& 'umped o(er the moon.
)
Another thing about programming in C is that it is not necessary to repeatedly call the printf routine,
so try and work out what the following program displays,
#include <stdio.h>
main()
{
printf("*ello...\n..oh my\n...&hen do i stop+\n");

" *ello...
..oh my
...&hen do i stop+
)
?
%AR#AB&ES
C provides the programmer with F"'! basic data types. 'ser defined variables must be declared
before they can be used in a program.
@et into the habit of declaring variables using lowercase characters. !emember that C is case
sensitive, so even though the two variables listed below have the same name, they are considered
different variables in C.
sum
,um
#he declaration of variables is done after the opening brace of main(),
#include <stdio.h>
main()
{
int sum;
sum - .// 0 1.;
printf("#he sum of .// and 1. is 2d\n"3 sum);

t is possible to declare variables elsewhere in a program, but lets start simply and then get into
variations later on.
#he basic format for declaring variables is
data)type (ar3 (ar3 ... ;
where data_type is one of the four basic types, an integer, character, float, or double type.
#he program declares the variable sum to be of type +#A@A! %int&. #he variable sum is then assigned
the value of BCC D 1B by using the assignment operator, the E sign.
sum - .// 0 1.;
+ow lets look more closely at the printf() statement. t has two arguments, separated by a comma. .ets
look at the first argument,
"#he sum of .// and 1. is 2d\n"
#he % sign is a special character in C. t is used to display the value of variables. 8hen the program is
e)ecuted, C starts printing the te)t until it finds a % character. f it finds one, it looks up for the ne)t
argument %in this case sum&, displays its value, then continues on.
#he d character that follows the % indicates that a decimal integer is e)pected. 2o, when the %d sign
is reached, the ne)t argument to the printf() routine is looked up %in this case the variable sum, which
is B1B&, and displayed. #he \n is then e)ecuted which prints the newline character.
#he output of the program is thus,
B
The sum of 500 and 15 is 515
_
Some of t'e formatters for printf are(
Cursor Control Formatters
\n newline
\t tab
\r carriage return
\f form feed
\v vertical tab
Variable Formatters
%d decimal integer
%c character
%s string or character array
%f float
%e double
The following program prints out two integer values separated by a TAB
t does this by using the \t cursor control formatter
#include <stdio.h>
main()
{
int sum3 (alue;
sum - 1/;
(alue - 1.;
printf("2d\t2d\n"3 sum3 (alue);

Program output looks like


10 15
_
! E"ERC#SE C)
8hat is the output of the following program>
#include <stdio.h>
main()
{
int (alue13 (alue43 sum;
(alue1 - 5.;
(alue4 - 16;
sum - (alue1 0 (alue4;
printf("#he sum of 2d and 2d is 2d\n"3 (alue13 (alue43 sum);

F
" #he sum of 5. and 16 is .5
)
+ote that the program declares three variables, all integers, on the same declaration line. #his could$ve
been done by three separate declarations,
int (alue1;
int (alue4;
int sum;
COMMENTS
#he addition of comments inside programs is desirable. #hese may be added to C programs by
enclosing them as follows,
78 $la $la $la $la $la $la 87
+ote that the *+ opens the comment field and +* closes the comment field. Comments may span
multiple lines. Comments may not be nested one inside another.
78 this is a comment. 78 this comment is inside 87 &rong 87
n the above e)ample, the first occurrence of +* closes the comment statement for the entire line,
meaning that the te)t wrong is interpreted as a C statement or variable, and in this e)ample, generates
an error.
,'at Comments Are Use- .or
documentation of variables and their usage
e)plaining difficult sections of code
describes the program, author, date, modification changes, revisions etc
copyrighting
Basi/ Stru/ture of C Programs
C programs are essentially constructed in the following manner, as a number of well defined sections.
!" #$%&$' ($CT)* "!
!" Contains name+ author+ revision number"!
!" *C,-&$ ($CT)* "!
!" contains .include statements "!
!" C)*(T%*T( %*& T/P$( ($CT)* "!
!" contains ty0es and .defines "!
!" 1,)2%, 3%'%2,$( ($CT)* "!
!" any global variables declared here "!
!" 4-*CT)*( ($CT)* "!
!" user defined functions "!
G
!" main56 ($CT)* "!
int main56
7
8
Adhering to a well defined structured layout will make your programs
easy to read
easy to modify
consistent in format
self documenting
MORE ABOUT %AR#AB&ES
Variables must begin with a character or underscore, and may be followed by any combination of
characters, underscores, or the digits C ; H. #he following is a list of valid variable names,
summary
e9it)flag
i
:erry;
<um$er)of)mo(es
)(alid)flag
*ou should ensure that you use meaningful names for your variables. #he reasons for this are,
meaningful names for variables are self documenting %see what they do at a glance&
they are easier to understand
there is no correlation with the amount of space used in the .A,A file
makes programs easier to read
! E"ERC#SE C0
8hy are the variables in the following list invalid,
(alue=sum
e9it flag
5lotsofmoney
char

" (alue=sum contains a =
e9it flag contains a space
5lotsofmoney $egins &ith a digit
char is a reser(ed %ey&ord
%AR#AB&E NAMES AN1 PRE.#"ES ,2EN ,R#T#NG ,#N1O,S OR OS*) PROGRAMS
Iuring the development of "2J3, it became common to add prefi) letters to variable names to indicate
the data type of variables.
K
#his enabled programmers to identify the data type of the variable without looking at its declaration,
thus they could easily check to see if they were performing the correct operations on the data type and
hopefully, reduce the number of errors.
Prefix Purpose or Type
b a byte value
c count or si9e
clr a variable that holds a color
f bitfields or flags
h a handle
hwnd a window handle
id an identity
l a long integer
msg a message
P a Pointer
rc return value
s short integer
ul unsigned long integer
us unsigned short integer
s9 a null terminated string variable
0s9 a 0ointer to a null terminated string variable
1ATA T3PES AN1 CONSTANTS
#he four basic data types are
#NTEGER
#hese are whole numbers, both positive and negative. 'nsigned integers %positive values only&
are supported. n addition, there are short and long integers.
#he keyword used to define integers is,
int
An e)ample of an integer value is =3. An e)ample of declaring an integer variable called sum
is,
int sum;
sum : ;0<
.&OAT#NG PO#NT
#hese are numbers which contain fractional parts, both positive and negative. #he keyword
used to define float variables is,
float
An e)ample of a float value is =?.13. An e)ample of declaring a float variable called money is,
H
float money;
money - /.14;
1OUB&E
#hese are e)ponetional numbers, both positive and negative. #he keyword used to define
double variables is,
dou$le
An e)ample of a double value is =.CA3. An e)ample of declaring a double variable called big
is,
dou$le $ig;
$ig - 514>0;;
C2ARACTER
#hese are single characters. #he keyword used to define character variables is,

char
An e)ample of a character value is the letter A. An e)ample of declaring a character variable
called letter is,
char letter;
letter - ?!?;
+ote the assignment of the character A to the variable letter is done by enclosing the value in
single 4uotes. !emember the golden ruleL 2ingle character ; 'se single 7uotes.
Sample program illustrating ea/' -ata type
#include < stdio.h >
main()
{
int sum;
float money;
char letter;
dou$le pi;
1C
sum - 1/; 78 assign integer (alue 87
money - 4.41; 78 assign float (alue 87
letter - ?!?; 78 assign character (alue 87
pi - 4./1>@; 78 assign a dou$le (alue 87
printf("(alue of sum - 2d\n"3 sum );
printf("(alue of money - 2f\n"3 money );
printf("(alue of letter - 2c\n"3 letter );
printf("(alue of pi - 2e\n"3 pi );

Sample program output


(alue of sum - 1/
(alue of money - 4.41////
(alue of letter - !
(alue of pi - 4./1////e0/@
#N#T#A&#S#NG 1ATA %AR#AB&ES AT 1EC&ARAT#ON T#ME
'nlike PA2CA., in C variables may be initialised with a value when they are declared. Consider the
following declaration, which declares an integer variable count which is initialised to 1C.
int count - 1/;
S#MP&E ASS#GNMENT O. %A&UES TO %AR#AB&ES
#he 5 operator is used to assign values to data variables. Consider the following statement, which
assigns the value =3 an integer variable count, and the letter A to the character variable letter
count - 54;
letter - ?!?;
T2E %A&UE O. %AR#AB&ES AT 1EC&ARAT#ON T#ME
.ets e)amine what the default value a variable is assigned when its declared. #o do this, lets consider
the following program, which declares two variables, count which is an integer, and letter which is a
character.
+either variable is pre;initialised. #he value of each variable is printed out using a printf() statement.
#include <stdio.h>
main()
{
int count;
char letter;
printf("Count - 2d\n"3 count);
printf("Aetter - 2c\n"3 letter);

11
Sample program output
Count : ;=>?>
,etter : f
t can be seen from the sample output that the values which each of the variables take on at declaration
time are no67ero. n C, this is common, and programmers must ensure that variables are assigned
values before using them.
f the program was run again, the output could well have different values for each of the variables. 8e
can never assume that variables declare in the manner above will take on a specific value.
2ome compilers may issue warnings related to the use of variables, and #urbo C from -orland issues
the following warning,
possi$le use of ?count? $efore definition in function main
RA1#" C2ANG#NG
Iata numbers may be e)pressed in any base by simply altering the modifier, eg, decimal, octal, or
he)adecimal. #his is achieved by the letter which follows the : sign related to the printf argument.
#include <stdio.h>
main() 78 Prints the same (alue in Becimal3 *e9 and Cctal 87
{
int num$er - 1//;
printf("Dn decimal the num$er is 2d\n"3 num$er);
printf("Dn he9 the num$er is 29\n"3 num$er);
printf("Dn octal the num$er is 2o\n"3 num$er);
78 &hat a$out 2E\n as an argument+ 87

Sample program output


n decimal the number is 100
n he@ the number is =>
n octal the number is 1>>
+ote how the variable number is initialised to Mero at the time of its declaration.
1E.#N#NG %AR#AB&ES #N OCTA& AN1 2E"A1EC#MA&
"ften, when writing systems programs, the programmer needs to use a different number base rather
than the default decimal.
nteger constants can be defined in octal or he) by using the associated prefi), eg, to define an integer
as an octal constant use %o
int sum - 2o.@;;
#o define an integer as a he) constant use %0x
13
int sum - 2/9;a$F;
int flag - 2/9;!GF; 78 <ote upper or lo&ercase he9 o% 87
MORE ABOUT .&OAT AN1 1OUB&E %AR#AB&ES
C displays both float and double variables to si) decimal places. #his does +"# refer to the precision
%accuracy& of which the number is actually stored, only how many decimal places printf() uses to
display these variable types.
#he following program illustrates how the different data types are declared and displayed,
#include <stdio.h>
main()
{
int sum - 1//;
char letter - ?H?;
float set1 - 45..@;;
dou$le num4 - 11e045;
printf("Dnteger (aria$le is 2d\n"3 sum);
printf("Character is 2c\n"3 letter);
printf("Iloat (aria$le is 2f\n"3 set1);
printf("Bou$le (aria$le is 2e\n"3 num4);

Sample program output


nteger variable is 100
Character variable is A
4loat variable is ;B.5=C000
&ouble variable is 11.000000e;B
#o change the number of decimal places printed out for float or double variables, modify the :f or :e
to include a precision value, eg,
printf("Iloat (aria$le is 2.4f\n"3 set1 );
n this case, the use of :.3f limits the output to two decimal places, and the output now looks like
Sample program output
nteger variable is 100
Character variable is A
4loat variable is ;B.5=
&ouble variable is 11.000000e;B
SPEC#A& NOTE ABOUT 1ATA T3PE CON%ERS#ON
Consider the following program,
#include <stdio.h>
main()
{
int (alue1 - 143 (alue4 - .;
float ans&er - /;
1=
ans&er - (alue1 7 (alue4;
printf("#he (alue of 2d di(ided $y 2d is 2f\n"3(alue13(alue43ans&er
);

Sample program output


The value of 1; divided by 5 is ;.000000
Aven though the above declaration seems to work, it is not always 1CC: reliable. Note how answer
does not contain a proper fractional part %ie, all Mero$s&.
#o ensure that the correct result always occurs, the data type of value1 and value should be converted
to a float type before assigning to the float variable answer. #he following change illustrates how this
can be done,
ans&er - (float)(alue1 7 (float)(alue4;
1#..ERENT T3PES O. #NTEGERS
A normal integer is limited in range to D;=3GFG. #his value differs from computer to computer. t is
possible in C to specify that an integer be stored in four memory locations instead of the normal two.
#his increases the effective range and allows very large integers to be stored. #he way in which this is
done is as follows,
long int $ig)num$er - 4F./54A;
#o display a long integer, use :l, ie,
printf("! larger num$er is 2l\n"3 $ig)num$er );
2hort integers are also available, eg,
short int small)(alue - 11Fh;
printf("#he (alue is 2h\n"3 small)(alue);
'nsigned integers %positive values only& can also be defined.
#he siMe occupied by integers varies upon the machine hardware. A+2 C %American +ational
2tandards nstitute& has tried to standardise upon the siMe of data types, and hence the number range of
each type.
#he following information is from the on;line help of the #urbo C compiler,
Ty0eD int
nteger data ty0e
3ariables of ty0e int are one word in length.
They can be signed 5default6 or unsigned+
which means they have a range of EB;C=F to
B;C=C and 0 to =55B5+ res0ectively.
Ty0e modifiersD signed+ unsigned+ short+ long
% ty0e modifier alters the meaning of the base
ty0e to yield a new ty0e. $ach of the above
1?
can be a00lied to the base ty0e int. The
modifiers signed and unsigned can be a00lied
to the base ty0e char. n addition+ long can
be a00lied to double. Ghen the base ty0e is
ommitted from a declaration+ int is assumed.
$@am0lesD
long @< !" int is im0lied "!
unsigned char ch<
signed int i< !" signed is default "!
unsigned long int l< !" int oH+ not needed "!
PREPROCESSOR STATEMENTS
#he -efine statement is used to make programs more readable. Consider the following e)amples,
#define #JK> 1 78 Bon?t use a semiLcolon 3 # must $e first character
on line 87
#define I!A,> /
#define <KAA /
#define !<B M
#define CJ N
#define >OK!A, --
game)o(er - #JK>;
&hile( list)pointer P- <KAA )
................
+ote that preprocessor statements begin with a N symbol, and are +"# terminated by a semi;colon.
#raditionally, preprocessor statements are listed at the beginning of the source file.
Preprocessor statements are handled by the compiler %or preprocessor& before the program is actually
compiled. All N statements are processed first, and the symbols %like #!'A& which occur in the C
program are replaced by their value %like 1&. "nce this substitution has taken place by the
preprocessor, the program is then compiled.
n general, preprocessor constants are written in UPPERCASE.
Click here for more information of preprocessor statements, including macros.
! E8er/ise C9
'se pre;processor statements to replace the following constants
/.514
Q
5;
! 'se pre;processor statements to replace the following constants
/.514
1B
Q
5;
#define small(alue /.514
#define letter ?Q?
#define smallint 5;
&#TERA& SUBST#TUT#ON O. S3MBO&#C CONSTANTS US#NG !-efine
.ets now e)amine a few e)amples of using these symbolic constants in our programs. Consider the
following program which defines a constant called #A,O!A#A.
#include <stdio.h>
#define #!E)J!#> /.1/
main()
{
float $alance;
float ta9;
$alance - ;4.1/;
ta9 - $alance 8 #!E)J!#>;
printf("#he ta9 on 2.4f is 2.4f\n"3 $alance3 ta9 );

#he pre;processor first replaces all symbolic constants before the program is compiled, so after
preprocessing the file %and before its compiled&, it now looks like,
#include <stdio.h>
#define #!E)J!#> /.1/
main()
{
float $alance;
float ta9;
$alance - ;4.1/;
ta9 - $alance 8 /.1/;
printf("#he ta9 on 2.4f is 2.4f\n"3 $alance3 ta9 );

3OU CANNOT ASS#GN %A&UES TO T2E S3MBO&#C CONSTANTS


Considering the above program as an e)ample, look at the changes we have made below. 8e have
added a statement which tries to change the #A,O!A#A to a new value.
#include <stdio.h>
#define #!E)J!#> /.1/
main ()
{
float $alance;
float ta9;
1F
$alance - ;4.1/;
#!E)J!#> - /.1.;
ta9 - $alance 8 #!E)J!#>;
printf("#he ta9 on 2.4f is 2.4f\n"3 $alance3 ta9 );

#his is illegal. *ou cannot re;assign a new value to a symbolic constant.


#TS &#TERA& SUBST#TUT#ON( SO BE,ARE O. ERRORS
As shown above, the preprocessor performs literal substitution of symbolic constants. .ets modify the
previous program slightly, and introduce an error to highlight a problem.
#include <stdio.h>
#define #!E)J!#> /.1/;
main()
{
float $alance;
float ta9;
$alance - ;4.1/;
ta9 - ($alance 8 #!E)J!#> )0 1/./4;
printf("#he ta9 on 2.4f is 2.4f\n"3 $alance3 ta9 );

n this case, the error that has been introduced is that the "define is terminated with a semi;colon. #he
preprocessor performs the substitution and the offending line %which is flagged as an error by the
compiler& looks like
ta9 - ($alance 8 /.1/; )0 1/./4;
Powever, you do not see the output of the preprocessor. f you are using #'!-" C, you will only see
ta9 - ($alance 8 #!E)J!#> )0 1/./4;
flagged as an error, and this actually looks okay %but its not4 after substitution takes place&.
MA:#NG PROGRAMS EAS3 TO MA#NTA#N B3 US#NG !-efine
#he whole point of using "define in your programs is to make them easier to read and modify.
Considering the above programs as e)amples, what changes would you need to make if the
#A,O!A#A was changed to 3C:.
"bviously, the answer is once, where the "define statement which declares the symbolic constant and
its value occurs. *ou would change it to read
#define #!E)J!#> - /.4/
8ithout the use of symbolic constants, you would hard code the value C.3C in your program, and this
might occur several times %or tens of times&.
#his would make changes difficult, because you would need to search and replace every occurrence in
the program. Powever, as the programs get larger, ;'at ;oul- 'appen if you a/tually use- t'e
<alue =>)= in a /al/ulation t'at 'a- not'ing to -o ;it' t'e TA"?RATE@
SUMMAR3 O. !-efine
1G
allow the use of symbolic constants in programs
in general, symbols are written in uppercase
are not terminated with a semi;colon
generally occur at the beginning of the file
each occurrence of the symbol is replaced by its value
makes programs readable and easy to maintain
2EA1ER .#&ES
Peader files contain definitions of functions and variables which can be incorporated into any C
program by using the pre;processor "include statement. 2tandard header files are provided with each
compiler, and cover a range of areas, string handling, mathematical, data conversion, printing and
reading of variables.
#o use any of the standard functions, the appropriate header file should be included. #his is done at the
beginning of the C source file. For e)ample, to use the function printf() in a program, the line
#include <stdio.h>
should be at the beginning of the source file, because the definition for printf() is found in the file
stdio#h All header files have the e)tension .h and generally reside in the Jinclude subdirectory.
#include <stdio.h>
#include "mydecls.h"
The use of angle bracHets IJ informs the com0iler to search the com0ilers include
directory for the s0ecified file. The use of the double Kuotes LL around the
filename inform the com0iler to search in the current directory for the s0ecified
file.
Pra/tise E8er/ise $ 1efining %ariables
1. Ieclare an integer called sum
3. Ieclare a character called letter
=. Iefine a constant called #!'A which has a value of 1
?. Ieclare a variable called money which can be used to hold currency
B. Ieclare a variable called arctan which will hold scientific notation values %De&
F. Ieclare an integer variable called total and initialise it to Mero.
G. Ieclare a variable called loop, which can hold an integer value.
K. Iefine a constant called @2# with a value of .13B
1K
Ans;ers to Pra/tise E8er/ise $ 1efining %ariables
1. Ieclare an integer called sum
int sum;
3. Ieclare a character called letter
char letter;
=. Iefine a constant called #!'A which has a value of 1
#define #JK> 1
?. Ieclare a variable called money which can be used to hold currency
float money$
B. Ieclare a variable called arctan which will hold scientific notation values %De&
dou$le arctan;
F. Ieclare an integer variable called total and initialise it to Mero.
int total;
total - /;
G. Ieclare a variable called loop, which can hold an integer value.
int loop;
K. Iefine a constant called @2# with a value of .13B
#define R,# /.14.
1H
AR#T2MET#C OPERATORS
#he symbols of the arithmetic operators areL;
Operation Operator Comment %alue of Sum before %alue of sum after
(ultiply Q sum E sum Q 3< ? K
Iivide J sum E sum J 3< ? 3
Addition D sum E sum D 3< ? F
2ubtraction ; sum E sum ;3< ? 3
ncrement DD DDsum< ? B
Iecrement ;; ;;sum< ? =
(odulus : sum E sum : =< ? 1
#he following code fragment adds the variables loop and count together, leaving the result in the
variable sum
sum : loo0 M count<
+oteL f the modulus A sign is needed to be displayed as part of a te)t string, use two, ie ::
#include <stdio.h>
main()
{
int sum - ./;
float modulus;

modulus - sum 2 1/;
printf("#he 22 of 2d $y 1/ is 2f\n"3 sum3 modulus);

! E"ERC#SE CB
8hat does the following change do to the printed output of the previous program>
printf("#he 22 of 2d $y 1/ is 2.4f\n"3 sum3 modulus);
" #include <stdio.h>
main()
{
int sum - ./;
float modulus;

modulus - sum 2 1/;
printf("#he 22 of 2d $y 1/ is 2.4f\n"3 sum3 modulus);

3C
#he 2 of ./ $y 1/ is /.//
)
Pra/tise E8er/ise ) Assignments
1. Assign the value of the variable number1 to the variable total
3. Assign the sum of the two variables loopOcount and petrolOcost to the variable sum
=. Iivide the variable total by the value 1C and leave the result in the variable discount
?. Assign the character 8 to the char variable letter
B. Assign the decimal result of dividing the integer variable sum by = into the float variable costing.
'se type casting to ensure that the remainder is also held by the float variable.
Ans;ers Pra/tise E8er/ise ) Assignments
1. Assign the value of the variable number1 to the variable total
total - num$er1;
3. Assign the sum of the two variables loopOcount and petrolOcost to the variable sum
sum - loop)count 0 petrol)cost;
=. Iivide the variable total by the value 1C and leave the result in the variable discount
discount - total 7 1/;
?. Assign the character 8 to the char variable letter
letter - ?Q?;
B. Assign the decimal result of dividing the integer variable sum by = into the float variable costing.
'se type casting to ensure that the remainder is also held by the float variable.
costing - (float) sum 7 5;
31
PRE*POST #NCREMENT*1ECREMENT OPERATORS
P!A means do the operation first followed by any assignment operation. P"2# means do the
operation after any assignment operation. Consider the following statements
00count; 78 PJ> Dncrement3 means add one to count 87
count00; 78 PC,# Dncrement3 means add one to count 87
n the above e)ample, because the value of count is not assigned to any variable, the effects of the
P!AJP"2# operation are not clearly visible.
.ets e)amine what happens when we use the operator along with an assignment operation. Consider
the following program,
#include <stdio.h>
main()
{
int count - /3 loop;
loop - 00count; 78 same as count - count 0 1; loop - count; 87
printf("loop - 2d3 count - 2d\n"3 loop3 count);
loop - count00; 78 same as loop - count; count - count 0 1; 87
printf("loop - 2d3 count - 2d\n"3 loop3 count);

f the operator precedes %is on the left hand side& of the variable, the operation is performed first, so the
statement
loop - 00count;
really means increment count first, then assign the new value of count to loop.
,'i/' ;ay -o you ;rite itC
8here the incrementJdecrement operation is used to adRust the value of a variable, and is not involved
in an assignment operation, which should you use,
MMloo0_count<
or
loo0_countMM<
#he answer is, it really does not matter. t does seem that there is a preference amongst C programmers
to use the post form.
Somet'ing to ;at/' out for
8hilst we are on the subRect, do not get into the habit of using a space%s& between the variable name
and the preJpost operator.
loo0_count MM<
#ry to be e)plicit in binding the operator tightly by leaving no gap.
33
GOO1 .ORM
Perhaps we should say programming style or readability. #he most common complaints we would
have about beginning C programmers can be summarised as,
they have poor layout
their programs are hard to read
*our programs will be 7uicker to write and easier to debug if you get into the habit of actually
formatting the layout correctly as you write it.
For instance, look at the program below
#include<stdio.h>
main()
{
int sum3loop3%ettle3'o$;
char Qho%no&s;
sum-S;
loop-;;
&hoTno&s-?!?;
printf("Qho%no&s-2c3Tettle-2d\n"3&ho%no&s3%ettle);

t is our contention that the program is hard to read, and because of this, will be difficult to debug for
errors by an ine)perienced programmer. t also contains a few deliberate mistakes4
"kay then, lets rewrite the program using good form.
#include <stdio.h>
main()
{
int sum3 loop3 %ettle3 'o$;
char &ho%no&s;
sum - S;
loop - ;;
&ho%no&s - ?!?;
printf( "Qho%no&s - 2c3 Tettle - 2d\n"3 &ho%no&s3 %ettle );

8e have also corrected the mistakes. #he maRor differences are


the 5 and 6 braces directly line up underneath each other
#his allows us to check ident levels and ensure that statements belong to the correct block of
code. #his becomes vital as programs become more comple)
3=
spaces are inserted for readability
8e as humans write sentences using spaces between words. #his helps our comprehension of
what we read %if you dont believe me, try reading the following sentence.
wishihadadollarforeverytimeimadeamistake. #he insertion of spaces will also help us identify
mistakes 7uicker.
good indentation
ndent levels %tab stops& are clearly used to block statements, here we clearly see and identify
functions, and the statements which belong to each 5 6 program body.
Programs to 'elp you
#here are a number of shareware programs available in the public domain which will assist you in the
areas of available to Sregistered users onlyT
checking for code correctness
converting between tabs and spaces
formatting the layout with indentation etc
building a tree representation of program flow
generating cross references
checking synta)
Please note that the above are all (2I"2 based programs. Perhaps the most famous of all C program
utilities is lint.
:E3BOAR1 #NPUT
#here is a function in C which allows the programmer to accept input from a keyboard. #he following
program illustrates the use of this function,
#include <stdio.h>
main() 78 program &hich introduces %ey$oard input 87
{
int num$er;
printf("#ype in a num$er \n");
scanf("2d"3 Mnum$er);
printf("#he num$er you typed &as 2d\n"3 num$er);

An integer called number is defined. A prompt to enter in a number is then printed using the statement
printf("#ype in a num$er \nU");
#he scanf routine, which accepts the response, has two arguments. #he first %1:d1& specifies what type
of data type is e)pected %ie char, int, or float&.
#he second argument %0number& specifies the variable into which the typed response will be placed.
n this case the response will be placed into the memory location associated with the variable number.
3?
#his e)plains the special significance of the 0 character %which means the address of&.
Sample program illustrating use of s/anfDE to rea- integers( /'ara/ters an- floats
#include < stdio.h >
main()
{
int sum;
char letter;
float money;
printf("Please enter an integer (alue ");
scanf("2d"3 Msum );
printf("Please enter a character ");
78 the leading space $efore the 2c ignores space characters in the
input 87
scanf(" 2c"3 Mletter );
printf("Please enter a float (aria$le ");
scanf("2f"3 Mmoney );
printf("\n#he (aria$les you entered &ere\n");
printf("(alue of sum - 2d\n"3 sum );
printf("(alue of letter - 2c\n"3 letter );
printf("(alue of money - 2f\n"3 money );


T'is program illustrates se<eral important points>
the c language provides no error checking for user input. #he user is e)pected to enter the
correct data type. For instance, if a user entered a character when an integer value was
e)pected, the program may enter an infinite loop or abort abnormally.
its up to the programmer to <ali-ate data for correct type and range of values.
Pra/tise E8er/ise 0 printfDE an- s/anfDE
1. 'se a printf statement to print out the value of the integer variable sum
3. 'se a printf statement to print out the te)t string 18elcome1, followed by a newline.
=. 'se a printf statement to print out the character variable letter
?. 'se a printf statement to print out the float variable discount
B. 'se a printf statement to print out the float variable dump using two decimal places
3B
F. 'se a scanf statement to read a decimal value from the keyboard, into the integer variable sum
G. 'se a scanf statement to read a float variable into the variable discountOrate
K. 'se a scanf statement to read a single character from the keyboard into the variable operator. 2kip
leading blanks, tabs and newline characters.
Ans;ers Pra/tise E8er/ise 0 printfDE an- s/anfDE
1. 'se a printf statement to print out the value of the integer variable sum
printf("2d"3 sum);
3. 'se a printf statement to print out the te)t string 18elcome1, followed by a newline.
printf("Qelcome\n");
=. 'se a printf statement to print out the character variable letter
printf("2c"3 letter);
?. 'se a printf statement to print out the float variable discount
printf("2f"3 discount);
B. 'se a printf statement to print out the float variable dump using two decimal places
printf("2.4f"3 dump);
F. 'se a scanf statement to read a decimal value from the keyboard, into the integer variable sum
scanf("2d"3 Msum);
G. 'se a scanf statement to read a float variable into the variable discountOrate
scanf("2f"3 Mdiscount)rate);
3F
K. 'se a scanf statement to read a single character from the keyboard into the variable operator. 2kip
leading blanks, tabs and newline characters.
scanf(" 2c"3 Moperator);
T2E RE&AT#ONA& OPERATORS
#hese allow the comparision of two or more variables.
-- eVual to
P- not eVual
< less than
<- less than or eVual to
> greater than
>- greater than or eVual to
n the ne)t few screens, these will be used in for loops and if statements.
#he operator
<>
may be legal in Pascal, but is illegal in C>
#TERAT#ON( .OR &OOPS
#he basic format of the for statement is,
for( start condition; continue condition; reLe(aulation )
program statement;
78 sample program using a for statement 87
#include <stdio.h>
main() 78 Program introduces the for statement3 counts to ten 87
{
int count;
for( count - 1; count <- 1/; count - count 0 1 )
printf("2d "3 count );
printf("\n");

#he program declares an integer variable count. #he first part of the for statement
for( count - 1;
initialises the value of count to 1. #he for loop continues whilst the condition
3G
count <- 1/;
evaluates as #!'A. As the variable count has Rust been initialised to 1, this condition is #!'A and so
the program statement
printf("2d "3 count );
is e)ecuted, which prints the value of count to the screen, followed by a space character.
+e)t, the remaining statement of the for is e)ecuted
count - count 0 1 );
which adds one to the current value of count. Control now passes back to the conditional test,
count <- 1/;
which evaluates as true, so the program statement
printf("2d "3 count );
is e)ecuted. %ount is incremented again, the condition re;evaluated etc, until count reaches a value of
11.
8hen this occurs, the conditional test
count <- 1/;
evaluates as FA.2A, and the for loop terminates, and program control passes to the statement
printf("\n");
which prints a newline, and then the program terminates, as there are no more statements left to
e)ecute.
78 sample program using a for statement 87
#include <stdio.h>
main()
{
int n3 t)num$er;
t)num$er - /;
for( n - 1; n <- 4//; n - n 0 1 )
t)num$er - t)num$er 0 n;
printf("#he 4//th triangular)num$er is 2d\n"3 t)num$er);

#he above program uses a for loop to calculate the sum of the numbers from 1 to 3CC inclusive %said to
be the triangular number&.
#he following diagram shows the order of processing each part of a for
3K
An e8ample of using a for loop to print out /'ara/ters
#include <stdio.h>
main()
{
char letter;
for( letter - ?!?; letter <- ?>?; letter - letter 0 1 ) {
printf("2c "3 letter);

,ample Program Cutput


! G C B >
An e8ample of using a for loop to /ount numbers( using t;o initialisations
#include <stdio.h>
main()
{
int total3 loop;
for( total - /3 loop - 1; loop <- 1/; loop - loop 0 1 ){
total - total 0 loop;

printf("#otal - 2d\n"3 total );

n the above e)ample, the variable total is initialised to C as the first part of the for loop. #he two
statements,
for( total - /3 loop - 1;
are part of the initialisation. #his illustrates that more than one statement is allowed, as long as they are
separated by /ommas.
Grap'i/al Animation of for loop
#o demonstrate the operation of the for statement, lets consider a series of animations.
#he code we will be using is
.include Istdio.hJ
3H
main56 7
int @+ y+ 9<
@ : ;<
y : ;<
9 : B<
for5 @ : 1< @ I: =< @ : @ M 1 6 7
0rintf5L%dL+ y 6<
y : y M 1<
8
0rintf5L%dL+ 9 6<
8
#he following diagram shows the initial state of the program, after the initialisation of the variables x&
y& and '.
"n entry to the for statement, the first e)pression is e)ecuted, which in our e)ample assigns the value
1 to x. #his can be seen in the graphic shown below %+oteL see the Variable ValuesL section&
#he ne)t part of the for is e)ecuted, which tests the value of the loop variable x against the constant F.
=C
t can be seen from the variable window that x has a current value of 1, so the test is successful, and
program flow branches to e)ecute the statements of the for body, which prints out the value of y, then
adds 1 to y. *ou can see the program output and the state of the variables shown in the graphic below.
After e)ecuting the statements of the for body, e)ecution returns to the last part of the for statement.
Pere, the value of x is incremented by 1. #his is seen by the value of x changing to 3.
=1
+e)t, the condition of the for variable is tested again. t continues because the value of it %3& is less
than F, so the body of the loop is e)ecuted again.
A)ecution continues till the value of x reaches G. .ets now Rump ahead in the animation to see this.
Pere, the condition test will fail, and the for statement finishes, passing control to the statement which
follows.
! E"ERC#SE CF
!ewrite the previous program by calculating the 3CCth triangular number, and make the program
shorter %if possible&.
N #include <stdio.h>
main()
{
int n - 13 t)num$er - /;
for( ; n <- 4//; n00 )
t)num$er - t)num$er 0 n;
=3
printf("#he 4//th triangular)num$er is 2d\n"3 t)num$er);


C&ASS E"ERC#SE CG
8hat is the difference between the two statements,
a -- 4
a - 4
" a -- 4 eVuality test
a - 4 assignment
C&ASS E"ERC#SE CH
Change the printf line of the above program to the following,
printf(" 24d 24d\n"3n3t)num$er);
8hat does the inclusion of the 3 in the :d statements achieve>
U #he inclusion of the 3 in the :d statements achieves a field width of two places, and prints a
leading C where the value is less than 1C.
E"ERC#SE CI
Create a C program which calculates the triangular number of the users re7uest, read from the
keyboard using s/anfDE. A triangular number is the sum of the preceding numbers, so the triangular
number G has a value of
G D F D B D ? D = D 3 D 1
N #include <stdio.h>
main()
{
int n - 13 t)num$er - /3 input;
printf(">nter a num$er\n");
scanf("2d"3 Minput);
for( ; n <- input; n00 )
t)num$er - t)num$er 0 n;
printf("#he triangular)num$er of 2d is 2d\n"3 input3 t)num$er);

Pra/tise E8er/ise 9 for loops


==
1. 8rite a for loop to print out the values 1 to 1C on separate lines.
for( loop - 1; loop <- 1/; loop - loop 0 1 )
printf("2d\n"3 loop) ;
3. 8rite a for loop which will produce the following output %hintL use two nested for loops&
1
;;
BBB
>>>>
55555
for( loop - 1; loop <- .; loop - loop 0 1 )
{
for( count - 1; count <- loop; count - count 0 1 )
printf("2d"3 count );
printf("\n");

=. 8rite a for loop which sums all values between 1C and 1CC into a variable called total. Assume that
total has +"# been initialised to Mero.
for( loop - 1/3 total - /; loop <- 1//; loop - loop 0 1 )
total - total 0 loop;
?. 8rite a for loop to print out the character set from A;V.
for( ch - ?!?; ch <- ?H?; ch - ch 0 1 )
printf("2c"3 ch );
printf("\n");
T2E ,2#&E STATEMENT
#he while provides a mechanism for repeating C statements whilst a condition is true. ts format is,
&hile( condition )
program statement;
2omewhere within the body of the while loop a statement must alter the value of the condition to allow
the loop to finish.
78 ,ample program including &hile 87
#include <stdio.h>
=?
main()
{
int loop - /;
&hile( loop <- 1/ ) {
printf("2d\n"3 loop);
00loop;


#he above program uses a while loop to repeat the statements
printf("2d\n"3 loop);
00loop;
whilst the value of the variable loop is less than or e7ual to 1C.
+ote how the variable upon which the while is dependant is initialised prior to the while statement %in
this case the previous line&, and also that the value of the variable is altered within the loop, so that
eventually the conditional test will succeed and the while loop will terminate.
#his program is functionally e7uivalent to the earlier for program which counted to ten.
T2E 1O ,2#&E STATEMENT
#he do ( ) while statement allows a loop to continue whilst a condition evaluates as #!'A %non;Mero&.
#he loop is e)ecuted as least once.
78 Bemonstration of BC...Q*DA> 87
#include <stdio.h>
main()
{
int (alue3 r)digit;
printf(">nter the num$er to $e re(ersed.\n");
scanf("2d"3 M(alue);
do {
r)digit - (alue 2 1/;
printf("2d"3 r)digit);
(alue - (alue 7 1/;
&hile( (alue P- / );
printf("\n");

#he above program reverses a number that is entered by the user. t does this by using the modulus %
operator to e)tract the right most digit into the variable r_digit. #he original number is then divided by
1C, and the operation repeated whilst the number is not e7ual to C.
t is our contention that this programming construct is improper and should be avoided. t has potential
problems, and you should be aware of these.
=B
"ne such problem is deemed to be lac* of control. Considering the above program code portion,
do {
r)digit - (alue 2 1/;
printf("2d"3 r)digit);
(alue - (alue 7 1/;
&hile( (alue P- / );
there is NO choice whether to e)ecute the loop. Antry to the loop is automatic, as you only get a
choice to continue.
Another problem is that the loop is always e)ecuted at least once. #his is a by;product of the lack of
control. #his means its possible to enter a do ( ) while loop with invalid data.
-eginner programmers can easily get into a whole heap of trouble, so our advice is to avoid its use.
#his is the only time that you will encounter it in this course. ts easy to avoid the use of this construct
by replacing it with the following algorithms,
initialise loo0 control variable
while5 loo0 control variable is valid 6 7
0rocess data
adOust control variable if necessary
8
"kay, lets now rewrite the above e)ample to remove the do ( ) while construct.
78 re&ritten code to remo(e construct 87
#include <stdio.h>
main()
{
int (alue3 r)digit;
(alue - /;
&hile( (alue <- / ) {
printf(">nter the num$er to $e re(ersed.\n");
scanf("2d"3 M(alue);
if( num$er <- / )
printf("#he num$er must $e positi(e\n");

&hile( (alue P- / )
{
r)digit - (alue 2 1/;
printf("2d"3 r)digit);
(alue - (alue 7 1/;

printf("\n");

MA:#NG 1EC#S#ONS
=F
SE&ECT#ON D#. STATEMENTSE
#he if statements allows branching %decision making& depending upon the value or state of variables.
#his allows statements to be e)ecuted or skipped, depending upon decisions. #he basic format is,
if( e9pression )
program statement;
A)ample<
if( students < @. )
00student)count;
n the above e)ample, the variable student_count is incremented by one only if the value of the integer
variable students is less than FB.
#he following program uses an if statement to validate the users input to be in the range 1;1C.
#include <stdio.h>
main()
{
int num$er;
int (alid - /;
&hile( (alid -- / ) {
printf(">nter a num$er $et&een 1 and 1/ LL>");
scanf("2d"3 Mnum$er);
78 assume num$er is (alid 87
(alid - 1;
if( num$er < 1 ) {
printf("<um$er is $elo& 1. Please reLenter\n");
(alid - /;

if( num$er > 1/ ) {


printf("<um$er is a$o(e 1/. Please reLenter\n");
(alid - /;

printf("#he num$er is 2d\n"3 num$er );

! E"ERC#SE C$=
8rite a C program that allows the user to enter in B grades, ie, marks between C ; 1CC. #he program
must calculate the average mark, and state the number of marks less than FB.
N #include <stdio.h>
main()
{
int grade; 78 to hold the entered grade 87
float a(erage; 78 the a(erage mar% 87
int loop; 78 loop count 87
int sum; 78 running total of all entered grades 87
int (alid)entry; 78 for (alidation of entered grade 87
=G
int failures; 78 num$er of people &ith less than @. 87
sum - /; 78 initialise running total to / 87
failures - /;
for( loop - /; loop < .; loop - loop 0 1 )
{
(alid)entry - /;
&hile( (alid)entry -- / )
{
printf(">nter mar% (1L1//)U");
scanf(" 2d"3 Mgrade );
if ((grade > 1 ) NN (grade < 1// ))
{
(alid)entry - 1;


if( grade < @. )
failures00;
sum - sum 0 grade;

a(erage - (float) sum 7 loop;
printf("#he a(erage mar% &as 2.4f\n"3 a(erage );
printf("#he num$er less than @. &as 2d\n"3 failures );

Consider the following program which determines whether a character entered from the keyboard is
within the range A to V.
#include <stdio.h>
main()
{
char letter;
printf(">nter a character LL>");
scanf(" 2c"3 Mletter );
if( letter >- ?!? ) {
if( letter <- ?H? )
printf("#he character is &ithin ! to H\n");

#he program does not print any output if the character entered is not within the range A to V. #his can
be addressed on the following pages with the if else construct.
Please note use of the leading space in the statement %before :c&
scanf(" 2c"3 Mletter );
#his enables the skipping of leading #A-2, 2paces, %collectively called whitespaces& and the A+#A!
/A*. f the leading space was not used, then the first entered character would be used, and scanf
would not ignore the whitespace characters.
=K
COMPAR#NG float types .OR EJUA&#T3
-ecause of the way in which float types are stored, it makes it very difficult to compare float types for
e7uality. Avoid trying to compare float variables for e7uality, or you may encounter unpredictable
results.
if else
#he general format for these are,
if( condition 1 )
statement1;
else if( condition 4 )
statement4;
else if( condition 5 )
statement5;
else
statementF;
#he else clause allows action to be taken where the condition evaluates as false %Mero&.
#he following program uses an if else statement to validate the users input to be in the range 1;1C.
#include <stdio.h>
main()
{
int num$er;
int (alid - /;
&hile( (alid -- / ) {
printf(">nter a num$er $et&een 1 and 1/ LL>");
scanf("2d"3 Mnum$er);
if( num$er < 1 ) {
printf("<um$er is $elo& 1. Please reLenter\n");
(alid - /;

else if( num$er > 1/ ) {


printf("<um$er is a$o(e 1/. Please reLenter\n");
(alid - /;

else
(alid - 1;

printf("#he num$er is 2d\n"3 num$er );

#his program is slightly different from the previous e)ample in that an else clause is used to set the
variable valid to 1. n this program, the logic should be easier to follow.
78 Dllustates nested if else and multiple arguments to the scanf function.
87
#include <stdio.h>
=H
main()
{
int in(alid)operator - /;
char operator;
float num$er13 num$er43 result;
printf(">nter t&o num$ers and an operator in the format\n");
printf(" num$er1 operator num$er4\n");
scanf("2f 2c 2f"3 Mnum$er13 Moperator3 Mnum$er4);
if(operator -- ?8?)
result - num$er1 8 num$er4;
else if(operator -- ?7?)
result - num$er1 7 num$er4;
else if(operator -- ?0?)
result - num$er1 0 num$er4;
else if(operator -- ?L?)
result - num$er1 L num$er4;
else
in(alid)operator - 1;
if( in(alid)operator P- 1 )
printf("2f 2c 2f is 2f\n"3 num$er13 operator3 num$er43
result );
else
printf("Dn(alid operator.\n");

#he above program acts as a simple calculator.


Pra/tise E8er/ise B ;'ile loops an- if else
1. 'se a while loop to print the integer values 1 to 1C on the screen
1;B>5=CF?10
#include <stdio.h>
main()
{
int loop;
loop - 1;
&hile( loop <- 1/ ) {
printf("2d"3 loop);
loop00;

printf("\n");
?C

3. 'se a nested while loop to reproduce the following output


1
;;
BBB
>>>>
55555
#include <stdio.h>
main()
{
int loop;
int count;
loop - 1;
&hile( loop <- . ) {
count - 1;
&hile( count <- loop ) {
printf("2d"3 count);
count00;

loop00;

printf("\n");

=. 'se an if statement to compare the value of an integer called sum against the value FB, and if it is
less, print the te)t string 12orry, try again1.
if( sum < @. )
printf(",orry3 try again.\n");
?. f total is e7ual to the variable goodOguess, print the value of total, else print the value of
goodOguess.
if( total -- good)guess )
printf("2d\n"3 total );
else
printf("2d\n"3 good)guess );
COMPOUN1 RE&AT#ONA&S D AN1( NOT( OR( EOR E
Combining more t'an one /on-ition
#hese allow the testing of more than one condition as part of selection statements. #he symbols are
?1
,)1C%, %*& PP
.ogical and re7uires all conditions to evaluate as #!'A %non;Mero&.
,)1C%, )' QQ
.ogical or will be e)ecuted if any "+A of the conditions is #!'A %non;Mero&.
,)1C%, *)T R
logical not negates %changes from #!'A to FA.2A, vsvs& a condition.
,)1C%, $)' S
.ogical eor will be e)cuted if either condition is #!'A, but +"# if they are all true.
#he following program uses an if statement with logical A+I to validate the users input to be in the
range 1;1C.
#include <stdio.h>
main()
{
int num$er;
int (alid - /;
&hile( (alid -- / ) {
printf(">nter a num$er $et&een 1 and 1/ LL>");
scanf("2d"3 Mnum$er);
if( (num$er < 1 ) NN (num$er > 1/) ){
printf("<um$er is outside range 1L1/. Please reL
enter\n");
(alid - /;

else
(alid - 1;

printf("#he num$er is 2d\n"3 num$er );

#his program is slightly different from the previous e)ample in that a ."@CA. A+I eliminates one
of the else clauses.
COMPOUN1 RE&AT#ONA&S D AN1( NOT( OR( EOR E
NEGAT#ON
#include <stdio.h>
main()
{
int flag - /;
if( P flag ) {
printf("#he flag is not set.\n");
flag - P flag;

printf("#he (alue of flag is 2d\n"3 flag);

?3
#he program tests to see if flag is not %4& set< e7ual to Mero. t then prints the appropriate message,
changes the state of flag< flag becomes e7ual to not flag< e7ual to 1. Finally the value of flag is printed.
COMPOUN1 RE&AT#ONA&S D AN1( NOT( OR( EOR E
Range /'e/King using Compoun- Relationals
Consider where a value is to be inputted from the user, and checked for validity to be within a certain
range, lets say between the integer values 1 and 1CC.
#include <stdio.h>
main()
{
int num$er;
int (alid - /;
&hile( (alid -- / ) {
printf(">nter a num$er $et&een 1 and 1//");
scanf("2d"3 Mnum$er );
if( (num$er < 1) NN (num$er > 1//) )
printf("<um$er is outside legal range\n");
else
(alid - 1;

printf("<um$er is 2d\n"3 num$er );

#he program uses valid, as a flag to indicate whether the inputted data is within the re7uired range of
allowable values. #he while loop continues whilst valid is C.
#he statement
if( (num$er < 1) NN (num$er > 1//) )
checks to see if the number entered by the user is within the valid range, and if so, will set the value of
valid to 1, allowing the while loop to e)it.
+ow consider writing a program which validates a character to be within the range A;V, in other
words alphabetic.
#include <stdio.h>
main()
{
char ch;
int (alid - /;
?=
&hile( (alid -- / ) {
printf(">nter a character !LH");
scanf(" 2c"3 Mch );
if( (ch >- ?!?) NN (ch <- ?H?) )
(alid - 1;
else
printf("Character is outside legal range\n");

printf("Character is 2c\n"3 ch );

s;it/'DE /ase
#he switch case statement is a better way of writing a program when a series of if elses occurs. #he
general format for this is,
s&itch ( e9pression ) {
case (alue1U
program statement;
program statement;
......
$rea%;
case (aluenU
program statement;
.......
$rea%;
defaultU
.......
.......
$rea%;

#he keyword brea* must be included at the end of each case statement. #he default clause is optional,
and is e)ecuted if the cases are not met. #he right brace at the end signifies the end of the case
selections.
Rules for s;it/' statements
values for TcaseT must be integer or character constants
the order of the TcaseT statements is unim0ortant
the default clause may occur first 5convention 0laces it last6
you cannot use e@0ressions or ranges
#include <stdio.h>
main()
{
int menu3 num$13 num$43 total;
printf("enter in t&o num$ers LL>");
scanf("2d 2d"3 Mnum$13 Mnum$4 );
printf("enter in choice\n");
??
printf("1-addition\n");
printf("4-su$traction\n");
scanf("2d"3 Mmenu );
s&itch( menu ) {
case 1U total - num$1 0 num$4; $rea%;
case 4U total - num$1 L num$4; $rea%;
defaultU printf("Dn(alid option selected\n");

if( menu -- 1 )
printf("2d plus 2d is 2d\n"3 num$13 num$43 total );
else if( menu -- 4 )
printf("2d minus 2d is 2d\n"3 num$13 num$43 total );

#he above program uses a switch statement to validate and select upon the users input choice,
simulating a simple menu of choices.
! E"ERC#SE C$$
!ewrite the previous program, which accepted two numbers and an operator, using the switch case
statement.
U !ewrite the previous program, which accepted two numbers and an operator, using the switch
case statement.
78 Dllustates nested if else and multiple arguments to the scanf function.
87
#include <stdio.h>
main()
{
int in(alid)operator - /;
char operator;
float num$er13 num$er43 result;
printf(">nter t&o num$ers and an operator in the format\n");
printf(" num$er1 operator num$er4\n");
scanf("2f 2c 2f"3 Mnum$er13 Moperator3 Mnum$er4);
if(operator -- ?8?)
result - num$er1 8 num$er4;
else if(operator -- ?7?)
result - num$er1 7 num$er4;
else if(operator -- ?0?)
result - num$er1 0 num$er4;
else if(operator -- ?L?)
result - num$er1 L num$er4;
else
in(alid)operator - 1;
if( in(alid)operator P- 1 )
printf("2f 2c 2f is 2f\n"3 num$er13 operator3 num$er43
result );
else
printf("Dn(alid operator.\n");
?B

Solution
78 Dllustates s&itch 87
#include <stdio.h>
main()
{
int in(alid)operator - /;
char operator;
float num$er13 num$er43 result;
printf(">nter t&o num$ers and an operator in the format\n");
printf(" num$er1 operator num$er4\n");
scanf("2f 2c 2f"3 Mnum$er13 Moperator3 Mnum$er4);
s&itch( operator ) {
case ?8? U result - num$er1 8 num$er4; $rea%;
case ?7? U result - num$er1 7 num$er4; $rea%;
case ?0? U result - num$er1 0 num$er4; $rea%;
case ?L? U result - num$er1 L num$er4; $rea%;
default U in(alid)operator - 1;

s&itch( in(alid)operator ) {
case 1 U printf("Dn(alid operator.\n"); $rea%;
default U printf("2f 2c 2f is 2f\n"3 num$er13 operator3
num$er43 result );

Pra/tise E8er/ise F
Compound Relationals and switch
1. if sum is e7ual to 1C and total is less than 3C, print the te)t string 1incorrect.1.
if( (sum -- 1/) MM (total < 4/) )
printf("incorrect.\n");
3. if flag is 1 or letter is not an $,$, then assign the value C to e)itOflag, else set e)itOflag to 1.
if( (flag -- 1) NN (letter P- ?E?) )
e9it)flag - /;
else
e9it)flag - 1;
=. rewrite the following statements using a switch statement
?F
if( letter -- ?E? )
sum - /;
else if ( letter -- ?H? )
(alid)flag - 1;
else if( letter -- ?!? )
sum - 1;
else
printf("Kn%no&n letter LL>2c\n"3 letter );
s&itch( letter ) {
case ?E? U sum - /; $rea%;
case ?H? U (alid)flag - 1; $rea%;
case ?!? U sum - 1; $rea%;
default U printf("Kn%no&n letter LL>2c\n"3 letter );

ACCEPT#NG S#NG&E C2ARACTERS .ROM T2E :E3BOAR1


get/'ar
#he following program illustrates this,
#include <stdio.h>
main()
{
int i;
int ch;
for( i - 1; i<- .; 00i ) {
ch - getchar();
putchar(ch);

#he program reads five characters %one for each iteration of the for loop& from the keyboard. +ote that
getchar() gets a single character from the keyboard, and putchar() writes a single character %in this
case, ch& to the console screen.
#he file ctype.h provides routines for manipulating characters.
BU#&T #N .UNCT#ONS .OR STR#NG 2AN1&#NG
string>'
*ou may want to look at the section on arrays first4. #he following macros are built into the file
string.h
strcat !ppends a string
strchr Iinds first occurrence of a gi(en character
?G
strcmp Compares t&o strings
strcmpi Compares t&o strings3 nonLcase sensiti(e
strcpy Copies one string to another
strlen Iinds length of a string
strl&r Con(erts a string to lo&ercase
strncat !ppends n characters of string
strncmp Compares n characters of t&o strings
strncpy Copies n characters of one string to another
strnset ,ets n characters of string to a gi(en character
strrchr Iinds last occurrence of gi(en character in string
strre( Je(erses string
strset ,ets all characters of string to a gi(en character
strspn Iinds first su$string from gi(en character set in string
strupr Con(erts string to uppercase
To convert a string to uppercase
#include <stdio.h>
#include <string.h>
main()
{
char nameW6/X; 78 declare an array of characters /L;S 87
printf(">nter in a name in lo&ercase\n");
scanf( "2s"3 name );
strupr( name );
printf("#he name is uppercase is 2s"3 name );

BU#&T #N .UNCT#ONS .OR C2ARACTER 2AN1&#NG


#he following character handling functions are defined in ctype.h
isalnum #ests for alphanumeric character
isalpha #ests for alpha$etic character
isascii #ests for !,CDD character
iscntrl #ests for control character
isdigit #ests for / to S
isgraph #ests for printa$le character
islo&er #ests for lo&ercase
isprint #ests for printa$le character
ispunct #ests for punctuation character
isspace #ests for space character
isupper #ests for uppercase character
is9digit #ests for he9adecimal
toascii Con(erts character to ascii code
tolo&er Con(erts character to lo&ercase
toupper Con(erts character to uppercase
To /on<ert a string array to upper/ase a /'ara/ter at a time using toupper()
#include <stdio.h>
#include <ctype.h>
main()
{
char nameW6/X;
?K
int loop;
printf(">nter in a name in lo&ercase\n");
scanf( "2s"3 name );
for( loop - /; nameWloopX P- /; loop00 )
nameWloopX - toupper( nameWloopX );
printf("#he name is uppercase is 2s"3 name );

%ali-ation Of User #nput #n C


Basic Rules
Ion$t pass invalid data onwards.
Validate data at input time.
Always give the user meaningful feedback
#ell the user what you e)pect to read as input
78 e9ample one3 a simple continue statement 87
#include <stdio.h>
#include <ctype.h>
main()
{
int (alid)input; 78 &hen 13 data is (alid and loop is e9ited 87
char user)input; 78 handles user input3 single character menu
choice 87
(alid)input - /;
&hile( (alid)input -- / ) {
printf("Continue (Y7<)+\n");
scanf(" 2c"3 Muser)input );
user)input - toupper( user)input );
if((user)input -- ?Y?) NN (user)input -- ?<?) ) (alid)input - 1;
else printf("\//;>rrorU Dn(alid choice\n");

78 e9ample t&o3 getting and (alidating choices 87


#include <stdio.h>
#include <ctype.h>
main()
{
int e9it)flag - /3 (alid)choice;
char menu)choice;
&hile( e9it)flag -- / ) {
(alid)choice - /;
&hile( (alid)choice -- / ) {
?H
printf("\nC - Copy Iile\n> - >9it\nZ - Zo(e Iile\n");
printf(">nter choiceU\n");
scanf(" 2c"3 Mmenu)choice );
if((menu)choice--?C?) NN (menu)choice--?>?) NN
(menu)choice--?Z?))
(alid)choice - 1;
else
printf("\//;>rror. Dn(alid menu choice
selected.\n");

s&itch( menu)choice ) {
case ?C? U ....................(); $rea%;
case ?>? U e9it)flag - 1; $rea%;
case ?Z? U ....................(); $rea%;
default U printf(">rrorLLL ,hould not occur.\n"); $rea%;

Ot'er <ali-ation e8amples


2an-ling User #nput #n C
scanf%& has problems, in that if a user is e)pected to type an integer, and types a string instead, often
the program bombs. #his can be overcome by reading all input as a string %use getchar()&, and then
converting the string to the correct data type.
78 e9ample one3 to read a &ord at a time 87
#include <stdio.h>
#include <ctype.h>
#define Z!EGKII>J,DH> 6/
(oid cleartoendofline( (oid ); 78 !<,D function prototype 87
(oid cleartoendofline( (oid )
{
char ch;
ch - getchar();
&hile( ch P- ?\n? )
ch - getchar();

main()
{
char ch; 78 handles user input 87
char $ufferWZ!EGKII>J,DH>X; 78 sufficient to handle one line 87
int char)count; 78 num$er of characters read for this line
87
int e9it)flag - /;
int (alid)choice;
&hile( e9it)flag -- / ) {
printf(">nter a line of te9t (<6/ chars)\n");
ch - getchar();
BC
char)count - /;
&hile( (ch P- ?\n?) MM (char)count < Z!EGKII>J,DH>)) {
$ufferWchar)count00X - ch;
ch - getchar();

$ufferWchar)countX - /9//; 78 null terminate $uffer 87


printf("\n#he line you entered &asU\n");
printf("2s\n"3 $uffer);
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf("Continue (Y7<)+\n");
scanf(" 2c"3 Mch );
ch - toupper( ch );
if((ch -- ?Y?) NN (ch -- ?<?) )
(alid)choice - 1;
else
printf("\//;>rrorU Dn(alid choice\n");
cleartoendofline();

if( ch -- ?<? ) e9it)flag - 1;

Anot'er E8ample( rea- a number as a string


78 e9ample t&o3 reading a num$er as a string 87
#include <stdio.h>
#include <ctype.h>
#include <stdli$.h>
#define Z!EGKII>J,DH> 6/
(oid cleartoendofline( (oid ); 78 !<,D function prototype 87
(oid cleartoendofline( (oid )
{
char ch;
ch - getchar();
&hile( ch P- ?\n? )
ch - getchar();

main()
{
char ch; 78 handles user input 87
char $ufferWZ!EGKII>J,DH>X; 78 sufficient to handle one line 87
int char)count; 78 num$er of characters read for this line
87
int e9it)flag - /3 num$er3 (alid)choice;
&hile( e9it)flag -- / ) {
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf(">nter a num$er $et&een 1 and 1///\n");
ch - getchar();
char)count - /;
&hile( (ch P- ?\n?) MM (char)count < Z!EGKII>J,DH>)) {
B1
$ufferWchar)count00X - ch;
ch - getchar();

$ufferWchar)countX - /9//; 78 null terminate $uffer 87


num$er - atoi( $uffer );
if( (num$er < 1) NN (num$er > 1///) )
printf("\//;>rror. <um$er outside range 1L1///\n");
else
(alid)choice - 1;

printf("\n#he num$er you entered &asU\n");


printf("2d\n"3 num$er);
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf("Continue (Y7<)+\n");
scanf(" 2c"3 Mch );
ch - toupper( ch );
if((ch -- ?Y?) NN (ch -- ?<?) )
(alid)choice - 1;
else
printf("\//;>rrorU Dn(alid choice\n");
cleartoendofline();

if( ch -- ?<? ) e9it)flag - 1;

T2E CON1#T#ONA& E"PRESS#ON OPERATOR


#his conditional e)pression operator takes #P!AA operators. #he two symbols used to denote this
operator are the > and the L. #he first operand is placed before the >, the second operand between the >
and the L, and the third after the L. #he general format is,
condition + e9pression1 U e9pression4
f the result of condition is #!'A % non;Mero &, e)pression1 is evaluated and the result of the
evaluation becomes the result of the operation. f the condition is FA.2A %Mero&, then e)pression3 is
evaluated and its result becomes the result of the operation. An e)ample will help,
s - ( 9 < / ) + L1 U 9 8 9;
Df 9 is less than [ero then s - L1
Df 9 is greater than [ero then s - 9 8 9
E8ample program illustrating /on-itional e8pression operator
#include <stdio.h>
B3
main()
{
int input;
printf("D &ill tell you if the num$er is positi(e3 negati(e or
[eroP"\n");
printf("please enter your num$er no&LLL>");
scanf("2d"3 Minput );
(input < /) + printf("negati(e\n") U ((input > /) +
printf("positi(e\n") U printf("[ero\n"));

! E"ERC#SE C$)
Avaluate the following e)pression, where aE?, bEB
least)(alue - ( a < $ ) + a U $;
! Avaluate the following e)pression, where aE?, bEB
least)(alue - ( a < $ ) + a U $;
ma)Ovalue E B
ARRA3S
&ittle Bo8es on t'e 'illsi-e
Arrays are a data structure which hold multiple variables of the same data type. Consider the case
where a programmer needs to keep track of a number of people within an organisation. 2o far, our
initial attempt will be to create a specific variable for each user. #his might look like,
int name1 - 1/1;
int name4 - 454;
int name5 - 451;
t becomes increasingly more difficult to keep track of this as the number of variables increase. Arrays
offer a solution to this problem.
An array is a multi;element bo), a bit like a filing cabinet, and uses an inde)ing system to find each
variable stored within it. n C, inde)ing starts at 7ero.
Arrays, like other variables in C, must be declared before they can be used.
#he replacement of the above e)ample using arrays looks like,
B=
int namesWFX;
namesW/X - 1/1;
namesW1X - 454;
namesW4X - 451;
namesW5X - /;
8e created an array called names, which has space for four integer variables. *ou may also see that we
stored C in the last space of the array. #his is a common techni7ue used by C programmers to signify
the end of an array.
Arrays have the following synta), using s7uare brackets to access each inde)ed value %called an
element&.
9WiX
so that x+,- refers to the si)th element in an array called x. n C, array elements start with C. Assigning
values to array elements is done by,
9W1/X - g;
and assigning array elements to a variable is done by,
g - 9W1/X;
n the following e)ample, a character based array named word is declared, and each element is
assigned a character. #he last element is filled with a Mero value, to signify the end of the character
string %in C, there is no string type, so character based arrays are used to hold strings&. A printf
statement is then used to print out all elements of the array.
!" ntroducing arrayTs+ ; "!
.include Istdio.hJ
main56
7
char wordU;0V<
wordU0V : T#T<
wordU1V : TeT<
wordU;V : TlT<
wordUBV : TlT<
wordU>V : ToT<
wordU5V : 0<
0rintf5LThe contents of wordUV is EEJ%s\nL+ word 6<
8
B?
1EC&AR#NG ARRA3S
Arrays may consist of any of the valid data types. Arrays are declared along with all other variables in
the declaration section of the program.
78 Dntroducing array?s 87
#include <stdio.h>
main()
{
int num$ersW1//X;
float a(eragesW4/X;
num$ersW4X - 1/;
LLnum$ersW4X;
printf("#he 5rd element of array num$ers is 2d\n"3 num$ersW4X);

#he above program declares two arrays, assigns 1C to the value of the =rd element of array numbers,
decrements this value % ..numbers+- &, and finally prints the value. #he number of elements that each
array is to have is included inside the s7uare brackets.
ASS#GN#NG #N#T#A& %A&UES TO ARRA3S
#he declaration is preceded by the word static. #he initial values are enclosed in braces, eg,
#include <stdio.h>
main()
{
int 9;
static int (aluesWX - { 134353F3.3@3;363S ;
static char &ordWX - { ?*?3?e?3?l?3?l?3?o? ;
for( 9 - /; 9 < S; 009 )
printf("\alues W2dX is 2d\n"3 93 (aluesW9X);

#he previous program declares two arrays, values and word. +ote that inside the s7uarebrackets there
is no variable to indicate how big the array is to be. n this case, C initialiMes the array to the number of
elements that appear within the initialiMe braces. 2o values consist of H elements %numbered C to K& and
the char array word has B elements.
T'e follo;ing program s'o;s 'o; to initialise all t'e elements of an integer base- array to t'e
<alue $=( using a for loop to /y/le t'roug' ea/' element in turn>
#include <stdio.h>
main()
{
int count;
int (aluesW1//X;
for( count - /; count < 1//; count00 )
BB
(aluesWcountX - 1/;

MU&T# 1#MENS#ONE1 ARRA3S


(ulti;dimensioned arrays have two or more inde) values which specify the element in the array.
multiWiXW'X
n the above e)ample, the first inde) value i specifies a row inde), whilst / specifies a column inde).
WPB1e/laration an- /al/ulations
int m1W1/XW1/X;
static int m4W4XW4X - { {/313 {435 ;
sum - m1WiXW'X 0 m4W%XWlX;
+"#A the strange way that the initial values have been assigned to the two;dimensional array m3.
nside the braces are,
{ /3 1 3
{ 43 5
!emember that arrays are split up into row and columns. #he first is the row, the second is the column.
.ooking at the initial values assigned to m, they are,
m4W/XW/X - /
m4W/XW1X - 1
m4W1XW/X - 4
m4W1XW1X - 5
! E"ERC#SE C$0
@iven a two dimensional array, write a program that totals all elements, printing the total.
U @iven a two dimensional array write a program that totals all elements printing the total.
#include <stdio.h>
main()
{
static int mWXWX - { {1/3.3L53 {S3 /3 /3 {5434/313 {/3/36 ;
int ro&3 column3 sum;
BF
sum - /;
for( ro& - /; ro& < F; ro&00 )
for( column - /; column < 5; column00 )
sum - sum 0 mWro&XWcolumnX;
printf("#he total is 2d\n"3 sum );

! E"ERC#SE C$9
8hat value is assigned to the elements which are not assigned initialised.
U #hey get initialised to LERO
C2ARACTER ARRA3S MSTR#NGSN
Consider the following program,
#include <stdio.h>
main()
{
static char name1WX - {?*?3?e?3?l?3?l?3?o?;
static char name4WX - "*ello";
printf("2s\n"3 name1);
printf("2s\n"3 name4);

#he difference between the two arrays is that name has a null placed at the end of the string, ie, in
name3SBT, whilst name1 has not. #o insert a null at the end of the name1 array, the initialiMation can be
changed to,
static char name1WX - {?*?3?e?3?l?3?l?3?o?3?\/?;
Consider the following program, which initialises the contents of the character based array word
during the program, using the function strcpy, which necessitates using the include file string#h
#include <stdio.h>
#include <string.h>
main()
{
char &ordW4/X;
strcpy( &ord3 "hi there." );
printf("2s\n"3 &ord );

BG
SOME %AR#AT#ONS #N 1EC&AR#NG ARRA3S
int num$ersW1/X;
static int num$ersW1/X - { 5F3 4;3 1@ ;
static int num$ersWX - { 43 L53 F.3 ;S3 L1F3 .3 S3 463 L13 / ;
static char te9tWX - "Qelcome to <e& Healand.";
static float radi9W14X - { 15F.5@43 1S15.4F6 ;
dou$le radiansW1///X;
REA1#NG C2ARACTER STR#NGS .ROM T2E :E3BOAR1
Character based arrays are often referred to in C as strings. C does not support a string type, so scanf()
is used to handle character based arrays. #his assumes that a C or +'.. value is stored in the last
element of the array. Consider the following, which reads a string of characters %e)cluding spaces&
from the keyboard.
char stringW16X;
scanf("2s"3 string);
+"#A that the 0 character does not need to precede the variable name when the formatter :s is used4
f the users response was
*ello
then
stringW/X - ?*?
stringW1X - ?e?
....
stringWFX - ?o?
stringW.X - ?\/?
Pra/tise E8er/ise G Arrays
1. Ieclare a character based array called letters of ten elements
char lettersW1/X;
3. Assign the character value $V$ to the fourth element of the letters array
BK
lettersW5X - ?H?;
=. 'se a for loop to total the contents of an integer array called numbers which has five elements. 2tore
the result in an integer called total.
for( loop - /3 total - /; loop < .; loop00 )
total - total 0 num$ersWloopX;
?. Ieclare a multidimensioned array of floats called balances having three rows and five columns.
float $alancesW5XW.X;
B. 8rite a for loop to total the contents of the multidimensioned float array balances.
for( ro& - /3 total - /; ro& < 5; ro&00 )
for( column - /; column < .; column00 )
total - total 0 $alancesWro&XWcolumnX;
F. Assign the te)t string 1Pello1 to the character based array words at declaration time.
static char &ordsWX - "*ello";
G. Assign the te)t string 18elcome1 to the character based array stuff %not at declaration time&
char stuffW./X;
strcpy( stuff3 "Qelcome" );
K. 'se a printf statement to print out the third element of an integer array called totals
printf("2d\n"3 totalsW4X );
H. 'se a printf statement to print out the contents of the character array called words
printf("2s\n"3 &ords);
BH
1C. 'se a scanf statement to read a string of characters into the array words.
scanf("2s"3 &ords);
11. 8rite a for loop which will read five characters %use scanf& and deposit them into the character
based array words, beginning at element C.
for( loop - /; loop < .; loop00 )
scanf("2c"3 M&ordsWloopX );
.UNCT#ONS
A function in C can perform a particular task, and supports the concept of modular programming
design techni7ues.
8e have already been e)posed to functions. #he main body of a C program, identified by the keyword
main, and enclosed by the left and right braces is a function. t is called by the operating system when
the program is loaded, and when terminated, returns to the operating system.
Functions have a basic structure. #heir format is
return)data)type function)name ( arguments3 arguments )
data)type)declarations)of)arguments;
{
function)$ody

t is worth noting that a returnOdataOtype is assumed to be type int unless otherwise specified, thus the
programs we have seen so far imply that main() returns an integer to the operating system.
A+2 C varies slightly in the way that functions are declared. ts format is
return)data)type function)name (data)type (aria$le)name3 data)type
(aria$le)name3 .. )
{
function)$ody

#his permits type checking by utiliMing function prototypes to inform the compiler of the type and
number of parameters a function accepts. 8hen calling a function, this information is used to perform
type and parameter checking.
A+2 C also re7uires that the returnOdataOtype for a function which does not return data must be type
void. #he default returnOdataOtype is assumed to be integer unless otherwise specified, but must match
that which the function declaration specifies.
FC
A simple function is,
(oid print)message( (oid )
{
printf("#his is a module called print)message.\n");

+ote the function name is print_message. +o arguments are accepted by the function, this is indicated
by the keyword void in the accepted parameter section of the function declaration. #he
returnOdataOtype is void, thus data is not returned by the function.
An A+2 C function prototype for print_message() is,
(oid print)message( (oid );
Function prototypes are listed at the beginning of the source file. "ften, they might be placed in a
users .h %header& file.
.UNCT#ONS
+ow lets incorporate this function into a program.
78 Program illustrating a simple function call 87
#include <stdio.h>
(oid print)message( (oid ); 78 !<,D C function prototype 87
(oid print)message( (oid ) 78 the function code 87
{
printf("#his is a module called print)message.\n");

main()
{
print)message();

#o call a function, it is only necessary to write its name. #he code associated with the function name is
e)ecuted at that point in the program. 8hen the function terminates, e)ecution begins with the
statement which follows the function name.
n the above program, e)ecution begins at main(). #he only statement inside the main body of the
program is a call to the code of function print_message(). #his code is e)ecuted, and when finished
returns back to main().
As there is no further statements inside the main body, the program terminates by returning to the
operating system.
F1
.UNCT#ONS
n the following e)ample, the function accepts a single data variable, but does not return any
information.
78 Program to calculate a specific factorial num$er 87
#include <stdio.h>
(oid calc)factorial( int ); 78 !<,D function prototype 87
(oid calc)factorial( int n )
{
int i3 factorial)num$er - /;
for( i - 1; i <- n; 00i )
factorial)num$er 8- i;
printf("#he factorial of 2d is 2d\n"3 n3 factorial)num$er );

main()
{
int num$er - /;
printf(">nter a num$er\n");
scanf("2d"3 Mnum$er );
calc)factorial( num$er );

.ets look at the function calc_factorial(). #he declaration of the function


(oid calc)factorial( int n )
indicates there is no return data type and a single integer is accepted, known inside the body of the
function as n. +e)t comes the declaration of the local variables,
int i3 factorial)num$er - /;
t is more correct in C to use,
auto int i3 factorial)num$er - /;
as the keyword auto designates to the compiler that the variables are local. #he program works by
accepting a variable from the keyboard which is then passed to the function. n other words, the
variable number inside the main body is then copied to the variable n in the function, which then
calculates the correct answer.
F3
RETURN#NG .UNCT#ON RESU&TS
#his is done by the use of the keyword return, followed by a data variable or constant value, the data
type of which must match that of the declared returnOdataOtype for the function.
float add)num$ers( float n13 float n4 )
{
return n1 0 n4; 78 legal 87
return @; 78 illegal3 not the same data type 87
return @./; 78 legal 87

t is possible for a function to have multiple return statements.


int (alidate)input( char command )
{
s&itch( command ) {
case ?0? U
case ?L? U return 1;
case ?8? U
case ?7? U return 4;
default U return /;

Pere is another e)ample


78 ,imple multiply program using argument passing 87
#include <stdio.h>
int calc)result( int3 int ); 78 !<,D function prototype 87
int calc)result( int num$13 int num$4 )
{
auto int result;
result - num$1 8 num$4;
return result;

main()
{
int digit1 - 1/3 digit4 - 5/3 ans&er - /;
ans&er - calc)result( digit13 digit4 );
printf("2d multiplied $y 2d is 2d\n"3 digit13 digit43 ans&er );

+"#A that the value which is returned from the function %ie result& must be declared in the function.
+"#AL #he formal declaration of the function name is preceded by the data type which is returned,
F=
int calc)result ( num$13 num$4 )
! E"ERC#SE C$B
8rite a program in C which incorporates a function using parameter passing and performs the addition
of three numbers. #he main section of the program is to print the result.
U 8rite a program in C which incorporates a function using parameter passing and performs the
addition of three numbers. #he main section of the program is to print the result.
#include <stdio.h>
int calc)result( int3 int3 int );
int calc)result( int (ar13 int (ar43 int (ar5 )
{
int sum;
sum - (ar1 0 (ar4 0 (ar5;
return( sum ); 78 return( (ar1 0 (ar4 0 (ar5 ); 87

main()
{
int num$1 - 43 num$4 - 53 num$5-F3 ans&er-/;
ans&er - calc)result( num$13 num$43 num$5 );
printf("2d 0 2d 0 2d - 2d\n"3 num$13 num$43 num$53 ans&er);

RETURN#NG .UNCT#ON RESU&TS


#his is done by the use of the keyword return, followed by a data variable or constant value, the data
type of which must match that of the declared returnOdataOtype for the function.
float add)num$ers( float n13 float n4 )
{
return n1 0 n4; 78 legal 87
return @; 78 illegal3 not the same data type 87
return @./; 78 legal 87

t is possible for a function to have multiple return statements.


int (alidate)input( char command )
{
s&itch( command ) {
case ?0? U
case ?L? U return 1;
F?
case ?8? U
case ?7? U return 4;
default U return /;

Pere is another e)ample


78 ,imple multiply program using argument passing 87
#include <stdio.h>
int calc)result( int3 int ); 78 !<,D function prototype 87
int calc)result( int num$13 int num$4 )
{
auto int result;
result - num$1 8 num$4;
return result;

main()
{
int digit1 - 1/3 digit4 - 5/3 ans&er - /;
ans&er - calc)result( digit13 digit4 );
printf("2d multiplied $y 2d is 2d\n"3 digit13 digit43 ans&er );

+"#A that the value which is returned from the function %ie result& must be declared in the function.
+"#AL #he formal declaration of the function name is preceded by the data type which is returned,
int calc)result ( num$13 num$4 )
! E"ERC#SE C$B
8rite a program in C which incorporates a function using parameter passing and performs the addition
of three numbers. #he main section of the program is to print the result.
" #include <stdio.h>
int calc)result( int3 int3 int );
int calc)result( int (ar13 int (ar43 int (ar5 )
{
int sum;
sum - (ar1 0 (ar4 0 (ar5;
return( sum ); 78 return( (ar1 0 (ar4 0 (ar5 ); 87

main()
{
int num$1 - 43 num$4 - 53 num$5-F3 ans&er-/;
FB
ans&er - calc)result( num$13 num$43 num$5 );
printf("2d 0 2d 0 2d - 2d\n"3 num$13 num$43 num$53 ans&er);

&OCA& AN1 G&OBA& %AR#AB&ES


&o/al
#hese variables only e)ist inside the specific function that creates them. #hey are unknown to other
functions and to the main program. As such, they are normally implemented using a stack. .ocal
variables cease to e)ist once the function that created them is completed. #hey are recreated each time
a function is e)ecuted or called.
Global
#hese variables can be accessed %ie known& by any function comprising the program. #hey are
implemented by associating memory locations with variable names. #hey do not get recreated if the
function is recalled.
1E.#N#NG G&OBA& %AR#AB&ES
78 Bemonstrating Rlo$al (aria$les 87
#include <stdio.h>
int add)num$ers( (oid ); 78 !<,D function prototype 87
78 #hese are glo$al (aria$les and can $e accessed $y functions from this
point on 87
int (alue13 (alue43 (alue5;
int add)num$ers( (oid )
{
auto int result;
result - (alue1 0 (alue4 0 (alue5;
return result;

main()
{
auto int result;
result - add)num$ers();
printf("#he sum of 2d 0 2d 0 2d is 2d\n"3
(alue13 (alue43 (alue53 final)result);

#he scope of global variables can be restricted by carefully placing the declaration. #hey are visible
from the declaration until the end of the current source file.
#include <stdio.h>
(oid no)access( (oid ); 78 !<,D function prototype 87
(oid all)access( (oid );
FF
static int n4; 78 n4 is %no&n from this point on&ards 87
(oid no)access( (oid )
{
n1 - 1/; 78 illegal3 n1 not yet %no&n 87
n4 - .; 78 (alid 87

static int n1; 78 n1 is %no&n from this point on&ards 87


(oid all)access( (oid )
{
n1 - 1/; 78 (alid 87
n4 - 5; 78 (alid 87

AUTOMAT#C AN1 STAT#C %AR#AB&ES


C programs have a number of segments %or areas& where data is located. #hese segments are typically,
_&%T% (tatic data
_2(( -ninitiali9ed static data+ 9eroed out before call to main56
_(T%CW %utomatic data+ resides on stacH frame+ thus local to functions
_C)*(T Constant data+ using the %*( C Heyword const
#he use of the appropriate keyword allows correct placement of the variable onto the desired data
segment.
78 e9ample program illustrates difference $et&een static and automatic
(aria$les 87
#include <stdio.h>
(oid demo( (oid ); 78 !<,D function prototypes 87
(oid demo( (oid )
{
auto int a(ar - /;
static int s(ar - /;
printf("auto - 2d3 static - 2d\n"3 a(ar3 s(ar);
00a(ar;
00s(ar;

main()
{
int i;
&hile( i < 5 ) {
demo();
i00;

AUTOMAT#C AN1 STAT#C %AR#AB&ES


FG
78 e9ample program illustrates difference $et&een static and automatic
(aria$les 87
#include <stdio.h>
(oid demo( (oid ); 78 !<,D function prototypes 87
(oid demo( (oid )
{
auto int a(ar - /;
static int s(ar - /;
printf("auto - 2d3 static - 2d\n"3 a(ar3 s(ar);
00a(ar;
00s(ar;

main()
{
int i;
&hile( i < 5 ) {
demo();
i00;

Program output
auto - /3 static - /
auto - /3 static - 1
auto - /3 static - 4
2tatic variables are created and initialiMed once, on the first call to the function. 2ubse7uent calls to the
function do not recreate or re;initialiMe the static variable. 8hen the function terminates, the variable
still e)ists on the OIA#A segment, but cannot be accessed by outside functions.
Automatic variables are the opposite. #hey are created and re;initialiMed on each entry to the function.
#hey disappear %are de;allocated& when the function terminates. #hey are created on the O2#AC/
segment.
PASS#NG ARRA3S TO .UNCT#ONS
#he following program demonstrates how to pass an array to a function.
78 e9ample program to demonstrate the passing of an array 87
#include <stdio.h>
int ma9imum( int WX ); 78 !<,D function prototype 87
int ma9imum( int (aluesW.X )
{
FK
int ma9)(alue3 i;
ma9)(alue - (aluesW/X;
for( i - /; i < .; 00i )
if( (aluesWiX > ma9)(alue )
ma9)(alue - (aluesWiX;
return ma9)(alue;

main()
{
int (aluesW.X3 i3 ma9;
printf(">nter . num$ers\n");
for( i - /; i < .; 00i )
scanf("2d"3 M(aluesWiX );
ma9 - ma9imum( (alues );
printf("\nZa9imum (alue is 2d\n"3 ma9 );

+oteL #he program defines an array of five elements %values& and initialiMes each element to the users
inputted values. #he array values is then passed to the function. #he declaration
int ma9imum( int (aluesW.X )
defines the function name as maximum, and declares that an integer is passed back as the result, and
that it accepts a data type called values, which is declared as an array of five integers. #he values array
in the main body is now known as the array values inside function ma)imum. #T #S NOT A COP3(
BUT T2E OR#G#NA&.
#his means any changes will update the original array.
A local variable max_value is set to the first element of values, and a for loop is e)ecuted which
cycles through each element in values and assigns the lowest item to max_value. #his number is then
passed back by the return statement, and assigned to max in the main section.
.un/tions an- Arrays
C allows the user to build up a library of modules such as the ma)imum value found in the previous
e)ample.
Powever, in its present form this module or function is limited as it only accepts ten elements. t is
thus desirable to modify the function so that it also accepts the number of elements as an argument
also. A modified version follows,
FH
78 e9ample program to demonstrate the passing of an array 87
#include <stdio.h>
int findma9imum( int WX3 int ); 78 !<,D function prototype 87
int findma9imum( int num$ersWX3 int elements )
{
int largest)(alue3 i;
largest)(alue - num$ersW/X;
for( i - /; i < elements; 00i )
if( num$ersWiX < largest)(alue )
largest)(alue - num$ersWiX;
return largest)(alue;

main()
{
static int num$1WX - { .3 5F3 .@3 L143 53 1S ;
static int num$4WX - { 13 L43 5F3 4/;3 S53 L14 ;
printf("ma9imum of num$1WX is 2d\n"3 findma9imum(num$13 @));
printf("ma9imum is num$4WX is 2d\n"3 findma9imum(num$43 @));

PASS#NG O. ARRA3S TO .UNCT#ONS


f an entire array is passed to a function, any changes made also occur to the original array.
PASS#NG O. MU&T#1#MENS#ONA& ARRA3S TO .UNCT#ONS
f passing a multidimensional array, the number of columns must be specified in the formal parameter
declaration section of the function.
N A,A!C2A C1FL
,rite a C program in/orporating a fun/tion to a-- all elements of a t;o -imensional array> T'e
number of ro;s are to be passe- to t'e fun/tion( an- it passes ba/K t'e total sum of all elements
DUse at least a 9 8 9 arrayE>
" #include <stdio.h>
int add4darray( int WXW.X3 int ); 78 function prototype 87
int add4darray( int arrayWXW.X3 int ro&s )
{
int total - /3 columns3 ro&;
for( ro& - /; ro& < ro&s; ro&00 )
for( columns - /; columns < .; columns00 )
total - total 0 arrayWro&XWcolumnsX;
return total;

GC
main()
{
int num$ersWXWX - { {13 43 5.3 ;3 1/3 {@3 ;3 F3 13 / ;
int sum;
sum - add4darray( num$ers3 4 );
printf("the sum of num$ers is 2d\n"3 sum );

.UNCT#ON PROTOT3PES
#hese have been introduced into the C language as a means of provided type checking and parameter
checking for function calls. -ecause C programs are generally split up over a number of different
source files which are independently compiled, then linked together to generate a run;time program, it
is possible for errors to occur.
Consider the following e)ample.
78 source file add.c 87
(oid add)up( int num$ersW4/X )
{
....

78 source file mainline.c 87


static float (aluesWX - { 1/.43 54.13 /.//@3 51./6 ;
main()
{
float result;
...
result - add)up( (alues );

As the two source files are compiled separately, the compiler generates correct code based upon what
the programmer has written. 8hen compiling mainline.c, the compiler assumes that the function
addOup accepts an array of float variables and returns a float. 8hen the two portions are combined and
ran as a unit, the program will definitely not work as intended.
#o provide a means of combating these conflicts, A+2 C has function prototyping. Xust as data types
need to be declared, functions are declared also. #he function prototype for the above is,
78 source file mainline.c 87
(oid add)up( int num$ersW4/X );
+"#A that the function prototype ends with a semi;colon< in this way we can tell its a declaration of a
function type, not the function code. f mainline.c was re;compiled, errors would be generated by the
call in the main section which references add_up().
G1
@enerally, when developing a large program, a separate file would be used to contain all the function
prototypes. #his file can then be included by the compiler to enforce type and parameter checking.
A11#T#ONA& ASS#GNMENT OPERATOR
Consider the following statement,
num$ersWloopX 0- ;;
#his assignment DE is e7uivalent to multiply e7uals. t takes the value of numbers+loop-, adds it by G,
then assigns the value to numbers+loop-. n other words it is the same as,
num$ersWloopX - num$ersWloopX 0 ;;
! E"ERC#SE C$G
8hat is the outcome of the following, assuming timeE3, aE=, bE?, cEB
time L- .;
a 8- $ 0 c;
"
time L- .;
a 8- $ 0 c;
time - L5
a - 4;
S#MP&E E"C2ANGE SORT A&GOR#T2M
#he following steps define an algorithm for sorting an array,
1. (et i to 0
;. (et O to i M 1
B. f aUiV J aUOV+ e@change their values
>. (et O to O M 1. f O I n goto ste0 B
5. (et i to i M 1. f i I n E 1 goto ste0 ;
=. a is now sorted in ascending order.
*oteD n is the number of elements in the array.
N A,A!C2A C1KL
mplement the above algorithm as a function in C, accepting the array and its siMe, returning the sorted array in ascending
order so it can be printed out by the calling module. #he array should consist of ten elements>
U A S#MP&E E"C2ANGE SORT A&GOR#T2M
#he following steps define an algorithm for sorting an array,
G3
1. (et i to 0
;. (et O to i M 1
B. f aUiV J aUOV+ e@change their values
>. (et O to O M 1. f O I n goto ste0 B
5. (et i to i M 1. f i I n E 1 goto ste0 ;
=. a is now sorted in ascending order.
*oteD n is the number of elements in the array.
E"ERC#SE C$H
mplement the above algorithm as a function in C, accepting the array and its siMe, returning the sorted
array in ascending order so it can be printed out by the calling module. #he array should consist of ten
elements.
#include <stdio.h>
(oid sort( WX3 int );
(oid sort( arrayWX3 int elements )
{
int i3 '3 temp;
i - /;
&hile( i < (elements L 1) ) {
' - i 0 1;
&hile( ' < elements ) {
if( aWiX > aW'X ) {
temp - aWiX;
aWiX - aW'X;
aW'X - temp;

'00;

i00;

main()
{
int num$ersWX - { 1/3 S3 63 453 1S3 113 43 ;3 13 153 14 ;
int loop;
printf("Gefore the sort the array &as \n");
for( loop - /; loop < 11; loop00 )
printf(" 2d "3 num$ersWloopX );
sort( num$ers3 11 );
printf("!fter the sort the array &as \n");
for( loop - /; loop < 11; loop00 )
printf(" 2d "3 num$ersWloopX );

RECURS#ON
#his is where a function repeatedly calls itself to perform calculations. #ypical applications are games
and 2orting trees and lists.
G=
Consider the calculation of F4 % F factorial &
ie =R : = " 5 " > " B " ; " 1
=R : = " 5R
=R : = " 5 = E 1 6R
nR : n " 5 n E 1 6R
!" bad e@am0le for demonstrating recursion "!
.include Istdio.hJ
long int factorial5 long int 6< !" %*( function 0rototy0e "!
long int factorial5 long int n 6
7
long int result<
if5 n :: 0, 6
result : 1,<
else
result : n " factorial5 n E 1, 6<
return 5 result 6<
8
main56
7
int O<
for5 O : 0< O I 11< MMO 6
0rintf5L%;dR : %ld\nL+ factorial5 5long6 O6 6<
8
RECURS#%E PROGRAMM#NG E"ERC#SE C$I
!ewrite e)ample cH using a recursive function.
#include <stdio.h>
long int triang)rec( long int );
long int triang)rec( long int num$er )
{
long int result;
if( num$er -- /l )
result - /l;
else
result - num$er 0 triang)rec( num$er L 1 );
return( result );

main ()
{
int reVuest;
long int triang)rec()3 ans&er;
G?
printf(">nter num$er to $e calculated.\n");
scanf( "2d"3 MreVuest);
ans&er - triang)rec( (long int) reVuest );
printf("#he triangular ans&er is 2l\n"3 ans&er);

<ote this (ersion of function triang)rec


#include <stdio.h>
long int triang)rec( long int );
long int triang)rec( long int num$er )
{
return((num$er -- /l) + /l U num$er8triang)rec( num$erL1));
Pra/tise E8er/ise H .un/tions
1. 8rite a function called menu which prints the te)t string 1(enu choices1. #he function does not
pass any data back, and does not accept any data as parameters.
(oid menu( (oid )
{
printf("Zenu choices");

3. 8rite a function prototype for the above function.


(oid menu( (oid );
=. 8rite a function called print which prints a te)t string passed to it as a parameter %ie, a character
based array&.
(oid print( char messageWX )
{
printf("2s3 message );

?. 8rite a function prototype for the above function print.


(oid print( char WX );
GB
B. 8rite a function called total, which totals the sum of an integer array passed to it %as the first
parameter& and returns the total of all the elements as an integer. .et the second parameter to the
function be an integer which contains the number of elements of the array.
int total( int arrayWX3 int elements )
{
int loop3 sum;
for( loop - /3 sum - /; loop < elements; loop00 )
sum 0- arrayWloopX;
return sum;

F. 8rite a function prototype for the above function.


int total( int WX3 int );
2an-ling User #nput #n C
scanf%& has problems, in that if a user is e)pected to type an integer, and types a string instead, often
the program bombs. #his can be overcome by reading all input as a string %use getchar()&, and then
converting the string to the correct data type.
78 e9ample one3 to read a &ord at a time 87
#include <stdio.h>
#include <ctype.h>
#define Z!EGKII>J,DH> 6/
(oid cleartoendofline( (oid ); 78 !<,D function prototype 87
(oid cleartoendofline( (oid )
{
char ch;
ch - getchar();
&hile( ch P- ?\n? )
ch - getchar();

main()
{
char ch; 78 handles user input 87
char $ufferWZ!EGKII>J,DH>X; 78 sufficient to handle one line 87
int char)count; 78 num$er of characters read for this line
87
int e9it)flag - /;
int (alid)choice;
&hile( e9it)flag -- / ) {
GF
printf(">nter a line of te9t (<6/ chars)\n");
ch - getchar();
char)count - /;
&hile( (ch P- ?\n?) MM (char)count < Z!EGKII>J,DH>)) {
$ufferWchar)count00X - ch;
ch - getchar();

$ufferWchar)countX - /9//; 78 null terminate $uffer 87


printf("\n#he line you entered &asU\n");
printf("2s\n"3 $uffer);
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf("Continue (Y7<)+\n");
scanf(" 2c"3 Mch );
ch - toupper( ch );
if((ch -- ?Y?) NN (ch -- ?<?) )
(alid)choice - 1;
else
printf("\//;>rrorU Dn(alid choice\n");
cleartoendofline();

if( ch -- ?<? ) e9it)flag - 1;

Anot'er E8ample( rea- a number as a string


78 e9ample t&o3 reading a num$er as a string 87
#include <stdio.h>
#include <ctype.h>
#include <stdli$.h>
#define Z!EGKII>J,DH> 6/
(oid cleartoendofline( (oid ); 78 !<,D function prototype 87
(oid cleartoendofline( (oid )
{
char ch;
ch - getchar();
&hile( ch P- ?\n? )
ch - getchar();

main()
{
char ch; 78 handles user input 87
char $ufferWZ!EGKII>J,DH>X; 78 sufficient to handle one line 87
int char)count; 78 num$er of characters read for this line
87
int e9it)flag - /3 num$er3 (alid)choice;
&hile( e9it)flag -- / ) {
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf(">nter a num$er $et&een 1 and 1///\n");
ch - getchar();
GG
char)count - /;
&hile( (ch P- ?\n?) MM (char)count < Z!EGKII>J,DH>)) {
$ufferWchar)count00X - ch;
ch - getchar();

$ufferWchar)countX - /9//; 78 null terminate $uffer 87


num$er - atoi( $uffer );
if( (num$er < 1) NN (num$er > 1///) )
printf("\//;>rror. <um$er outside range 1L1///\n");
else
(alid)choice - 1;

printf("\n#he num$er you entered &asU\n");


printf("2d\n"3 num$er);
(alid)choice - /;
&hile( (alid)choice -- / ) {
printf("Continue (Y7<)+\n");
scanf(" 2c"3 Mch );
ch - toupper( ch );
if((ch -- ?Y?) NN (ch -- ?<?) )
(alid)choice - 1;
else
printf("\//;>rrorU Dn(alid choice\n");
cleartoendofline();

if( ch -- ?<? ) e9it)flag - 1;

More 1ata %ali-ation


Consider the following program
#include <stdio.h>
main() {
int num$er;
printf("Please enter a num$er\n");
scanf("2d"3 Mnum$er );
printf("#he num$er you entered &as 2d\n"3 num$er );

#he above program has several problems


the input is not validated to see if its the correct data type
it is not clear if there are e)plicit number ranges e)pected
the program might crash if an incorrect data type was entered
Perhaps the best way of handling input in C programs is to treat all input as a se7uence of characters,
and then perform the necessary data conversion.
GK
At this point we shall want to e)plore some other aspects also, like the concepts of
trapping data at the source
the dominoJripple effect
Trapping 1ata At T'e Sour/e
#his means that the validation of data as to its correct rangeJlimit and data type is best done at the
point of entry. #he benefits of doing this at the time of data entry are
less cost later in the program maintenance phase %because data is already validated&
programs are easier to maintain and modify
reduces the chances of incorrect data crashing the program later on
T'e Ripple T'roug' Effe/t
#his refers to the problem of incorrect data which is allowed to propagate through the program. An
e)ample of this is sending invalid data to a function to process.
-y trapping data at the source, and ensuring that it is correct as to its data type and range, we ensure
that bad data cannot be passed onwards. #his makes the code which works on processing the data
simpler to write and thus reduces errors.
An e8ample
.ets look at the case of wanting to handle user input. +ow, we know that users of programs out there
in user;land are a bunch of annoying people who spend most of their time inventing new and more
wonderful ways of making our programs crash.
.ets try to implement a sort of general purpose way of handling data input, as a replacement to scanf().
#o do this, we will implement a function which reads the input as a se7uence of characters.
#he function is readinput(), which, in order to make it more versatile, accepts several parameters,
a character array to store the inputted data
an integer which specifies the data type to read, 2#!+@, +#A@A!, A.PPA
an integer which specifies the amount of digitsJcharacters to read
8e have used the some of the functions covered in ctype.h to check the data type of the inputted data.
78 (ersion 1./ 87
#include <stdio.h>
#include <ctype.h>
#define Z!E 6/ 78 ma9imum length of $uffer 87
#define BDRD# 1 78 data &ill $e read as digits /LS 87
#define !AP*! 4 78 data &ill $e read as alpha$et !LH 87
#define ,#JD<R 5 78 data is read as !,CDD 87
(oid readinput( char $uffWX3 int mode3 int limit ) {
int ch3 inde9 - /;
GH
ch - getchar();
&hile( (ch P- ?\n?) MM (inde9 < limit) ) {
s&itch( mode ) {
case BDRD#U
if( isdigit( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
case !AP*!U
if( isalpha( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
case ,#JD<RU
if( isascii( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
defaultU
78 this should not occur 87
$rea%;

ch - getchar();

$uffWinde9X - /9//; 78 null terminate input 87

main() {
char $ufferWZ!EX;
int num$er;
printf("Please enter an integer\n");
readinput( $uffer3 BDRD#3 Z!E );
num$er - atoi( $uffer );
printf("#he num$er you entered &as 2d\n"3 num$er );

"f course, there are improvements to be made. 8e can change readinput to return an integer value
which represents the number of characters read. #his would help in determining if data was actually
entered. n the above program, it is not clear if the user actually entered any data %we could have
checked to see if buffer was an empty array&.
2o lets now make the changes and see what the modified program looks like
78 (ersion 1.1 87
#include <stdio.h>
#include <ctype.h>
#define Z!E 6/ 78 ma9imum length of $uffer 87
#define BDRD# 1 78 data &ill $e read as digits /LS 87
KC
#define !AP*! 4 78 data &ill $e read as alpha$et !LH 87
#define ,#JD<R 5 78 data is read as !,CDD 87
int readinput( char $uffWX3 int mode3 int limit ) {
int ch3 inde9 - /;
ch - getchar();
&hile( (ch P- ?\n?) MM (inde9 < limit) ) {
s&itch( mode ) {
case BDRD#U
if( isdigit( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
case !AP*!U
if( isalpha( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
case ,#JD<RU
if( isascii( ch ) ) {
$uffWinde9X - ch;
inde900;

$rea%;
defaultU
78 this should not occur 87
$rea%;

ch - getchar();

$uffWinde9X - /9//; 78 null terminate input 87


return inde9;

main() {
char $ufferWZ!EX;
int num$er3 digits - /;
&hile( digits -- / ) {
printf("Please enter an integer\n");
digits - readinput( $uffer3 BDRD#3 Z!E );
if( digits P- / ) {
num$er - atoi( $uffer );
printf("#he num$er you entered &as 2d\n"3 num$er );

#he second version is a much better implementation.


K1
Controlling t'e /ursor position
#he following characters, placed after the 9 character in a printf() statement, have the following effect.
\$ $ac%space
\f form feed
\n ne& line
\r carriage return
\t hori[ontal ta$
\( (ertical ta$
\\ $ac%slash
\" dou$le Vuote
\? single Vuote
\ line continuation
\nnn nnn - octal character (alue
\/9nn nn - he9adecimal (alue (some compilers only)
printf("\//;!ttention3 that &as a $eepP\n");
.ORMATTERS .OR s/anfDE
#he following characters, after the : character, in a scanf argument, have the following effect.
d read a decimal integer
o read an octal value
@ read a he@adecimal value
h read a short integer
l read a long integer
f read a float value
e read a double value
c read a single character
s read a seKuence of characters
U...V 'ead a character string. The characters inside the bracHets
indicate
the allowEable characters that are to be contained in the
string. f any
other character is ty0ed+ the string is terminated. f the
first character
is a S+ the remaining characters inside the bracHets
indicate that
ty0ing them will terminate the string.
" this is used to sHi0 in0ut fields
Example of scanf() modifiers
int num$er;
char te9t1W5/X3 te9t4W5/X;
scanf("2s 2d 28f 2s"3 te9t13 Mnum$er3 te9t4);
f the user response is,
#ello 1> CB=.55 uncle sam
K3
then
te@t1 : hello+ number : 1>+ te@t; : uncle
and the ne)t call to the scanf function will continue from where the last one left off, so if
scanf5L%s L+ te@t;6<
was the ne)t call, then
te@t; : sam
PR#NT#NG OUT T2E ASC## %A&UES O. C2ARACTERS
Anclosing the character to be printed within single 7uotes will instruct the compiler to print out the
Ascii value of the enclosed character.
printf("#he character ! has a (alue of 2d\n"3 ?!?);
#he program will print out the integer value of the character A.
! E"ERC#SE C)=
8hat would the result of the following operation be>
" int c;
c - ?a? 0 1;
printf("2c\n"3 c);
int c;
c - ?a? 0 1;
printf("2c\n"3 c);
#he program adds one to the (alue ?a?3 resulting in the (alue ?$? as the
(alue &hich is assigned to the (aria$le c.
B#T OPERAT#ONS
C has the advantage of direct bit manipulation and the operations available are,
Operation Operator Comment %alue of Sum before %alue of sum after
A+I 0 sum E sum 0 3< ? C
"! Y sum E sum Y 3< ? F
A)clusive "! Z sum E sum Z 3< ? F
1$s Complement [ sum E [sum< ? ;B
.eft 2hift WW sum E sum WW 3< ? 1F
!ight 2hift \\ sum E sum \\ 3< ? C
78 >9ample program illustrating << and >> 87
#include <stdio.h>
K=
main()
{
int n1 - 1/3 n4 - 4/3 i - /;
i - n4 << F; 78 n4 shifted left four times 87
printf("2d\n"3 i);
i - n1 >> .; 78 n1 shifted right fi(e times 87
printf("2d\n"3 i);

78 >9ample program using >CJ operator 87


#include <stdio.h>
main()
{
int (alue1 - 43 (alue4 - F;
(alue1 ]- (alue4;
(alue4 ]- (alue1;
(alue1 ]- (alue4;
printf("\alue1 - 2d3 \alue4 - 2d\n"3 (alue13 (alue4);

78 >9ample program using !<B operator 87


#include <stdio.h>
main()
{
int loop;
for( loop - ?!?; loop <- ?H?; loop00 )
printf("Aoop - 2c3 !<B /9df - 2c\n"3 loop3 loop M /9df);

STRUCTURES
A 2tructure is a data type suitable for grouping data elements together. .ets create a new data structure
suitable for storing the date. #he elements or fields which make up the structure use the four basic data
types. As the storage re7uirements for a structure cannot be known by the compiler, a definition for the
structure is first re7uired. #his allows the compiler to determine the storage allocation needed, and also
identifies the various sub;fields of the structure.
struct date {
int month;
int day;
int year;
;
#his declares a +A8 data type called date. #his date structure consists of three basic data elements, all
of type integer. T'is is a -efinition to t'e /ompiler> t does not create any storage space and cannot
be used as a variable. n essence, its a new data type keyword, like int and char, and can now be used
K?
to create variables. "ther data structures may be defined as consisting of the same composition as the
date structure,
struct date todays)date;
defines a variable called todays_date to be of the same data type as that of the newly defined data type
struct date.
ASS#GN#NG %A&UES TO STRUCTURE E&EMENTS
#o assign todays date to the individual elements of the structure todays_date, the statement
todays)date.day - 41;
todays)date.month - /;;
todays)date.year - 1S6.;
is used. +"#A the use of the .element to reference the individual elements within todays_date.
78 Program to illustrate a structure 87
#include <stdio.h>
struct date { 78 glo$al definition of type date 87
int month;
int day;
int year;
;
main()
{
struct date today;
today.month - 1/;
today.day - 1F;
today.year - 1SS.;
printf("#odays date is 2d72d72d.\n"3 \
today.month3 today.day3 today.year );

! E"ERC#SE C)$
8rite a program in C that prompts the user for todays date, calculates tomorrows date, and displays
the result. 'se structures for todays date, tomorrows date, and an array to hold the days for each month
of the year. !emember to change the month or year as necessary.
N #include <stdio.h>
struct date {
int day3 month3 year;
;
int daysWX - { 513 463 513 5/3 513 5/3 513 513 5/3 513 5/3 51 ;
struct date today3 tommorro&;
KB
(oid gettodaysdate( (oid );
(oid gettodaysdate( (oid )
{
int (alid - /;
&hile( (alid -- / ) {
printf(">nter in the current year (1SS/L1SSS)LL>");
scanf("Md"3 Mtoday.year);
if( (today.year < 1SS/) NN (today.year > 1SSS) )
printf("\//;Dn(alid year\n");
else
(alid - 1;

(alid - /;
&hile( (alid -- / ) {
printf(">nter in the current month (1L14)LL>");
scanf("Md"3 Mtoday.month);
if( (today.month < 1) NN (today.month > 14) )
printf("\//;Dn(alid month\n");
else
(alid - 1;

(alid - /;
&hile( (alid -- / ) {
printf(">nter in the current day (1L2d)LL>"3
daysWtoday.monthL1X);
scanf("Md"3 Mtoday.day);
if( (today.day < 1) NN (today.day > daysWtoday.monthL1X) )
printf("\//;Dn(alid day\n");
else
(alid - 1;

main()
{
gettodaysdate();
tommorro& - today;
tommorro&.day00;
if( tommorro&.day > daysWtommorro&.monthL1X ) {
tommorro&.day - 1;
tommorro&.month00;
if( tommorro&.month > 14 )
tommorro&.year00;

printf("#ommorro&s date is 2/4dU2/4dU2/4d\n"3 \


tommorro&.day3 tommorro&.month3 tommorro&.year );

78 #DZ>.C Program updates time $y 1 second using functions 87


#include <stdio.h>
struct time {
int hour3 minutes3 seconds;
KF
;
(oid time time)update( struct time ); 78 !<,D function prototype 87
78 function to update time $y one second 87
(oid time)update( struct ne&)time )
{
00ne&)time.seconds;
if( ne&)time.seconds -- @/) {
ne&)time.seconds - /;
00ne&)time.minutes;
if(ne&)time.minutes -- @/) {
ne&)time.minutes - /;
00ne&)time.hour;
if(ne&)time.hour -- 4F)
ne&)time.hour - /;

main()
{
(oid time time)update();
struct time current)time;
printf(">nter the time (hhUmmUss)U\n");
scanf("2dU2dU2d"3 \
Mcurrent)time.hour3Mcurrent)time.minutes3Mcurrent)time.seconds);
time)update ( current)time);
printf("#he ne& time is 2/4dU2/4dU2/4d\n"3current)time.hour3 \
current)time.minutes3 current)time.seconds);

#N#T#A&#L#NG STRUCTURES
#his is similar to the initialiMation of arrays< the elements are simply listed inside a pair of braces, with
each element separated by a comma. #he structure declaration is preceded by the keyword static
static struct date today - { F34531SS6 ;
ARRA3S O. STRUCTURES
Consider the following,
struct date {
int month3 day3 year;
;
.ets now create an array called birthdays of the same data type as the structure date
struct date $irthdaysW.X;
#his creates an array of B elements which have the structure of date.
$irthdaysW1X.month - 14;
KG
$irthdaysW1X.day - /F;
$irthdaysW1X.year - 1SS6;
LL$irthdaysW1X.year;
STRUCTURES AN1 ARRA3S
2tructures can also contain arrays.
struct month {
int num$er)of)days;
char nameWFX;
;
static struct month this)month - { 513 ":an" ;
this)month.num$er)of)days - 51;
strcpy( this)month.name3 ":an" );
printf("#he month is 2s\n"3 this)month.name );
+ote that the array name has an e)tra element to hold the end of string nul character.
%AR#AT#ONS #N 1EC&AR#NG STRUCTURES
Consider the following,
struct date {
int month3 day3 year;
todays)date3 purchase)date;
or another way is,
struct date {
int month3 day3 year;
todays)date - { S34.31S6. ;
or, how about an array of structures similar to date,
struct date {
int month3 day3 year;
datesW1//X;
Ieclaring structures in this way, however, prevents you from using the structure definition later in the
program. #he structure definition is thus bound to the variable name which follows the right brace of
the structures definition.
! E"ERC#SE C))
" #include <stdio.h>
struct date { 78 Rlo$al definition of date 87
int day3 month3 year;
;
main()
{
struct date datesW.X;
KK
int i;
for( i - /; i < .; 00i ) {
printf("Please enter the date (ddUmmUyy)" );
scanf("2dU2dU2d"3 MdatesWiX.day3 MdatesWiX.month3
MdatesWiX.year );

STRUCTURES ,2#C2 CONTA#N STRUCTURES


2tructures can also contain structures. Consider where both a date and time structure are combined
into a single structure called date_time, eg,
struct date {
int month3 day3 year;
;
struct time {
int hours3 mins3 secs;
;
struct date)time {
struct date sdate;
struct time stime;
;
#his declares a structure whose elements consist of two other previously declared structures.
nitialiMation could be done as follows,
static struct date)time today - { { 43 113 1S6. 3 { 53 5355 ;
which sets the sdate element of the structure today to the eleventh of February, 1HKB. #he stime
element of the structure is initialiMed to three hours, three minutes, thirty;three seconds. Aach item
within the structure can be referenced if desired, eg,
00today.stime.secs;
if5 today.stime.secs :: =0 6 MMtoday.stime.mins<
B#T .#E&1S
Consider the following data elements defined for a PA-, telephone system.
flag - 1 $it
off)hoo% - 1 $it
status - 4 $its
n C, these can be defined as a structure, and the number of bits each occupy can be specified.
struct pac%ed)struct {
unsigned int flagU1;
unsigned int off)hoo%U1;
unsigned int statusU4;
KH
pac%ed)struct1;
#he L1 following the variable flag indicates that flag occupies a single bit. #he C compiler will assign
all the above fields into a single word.
Assignment is as follows,
pac%ed)struct1.flag - /;
pac%ed)struct1.status - F;
if( pac%ed)struct1.flag )
.............
Pra/tise E8er/ise I Stru/tures
1. Iefine a structure called record which holds an integer called loop, a character array of B elements
called word, and a float called sum.
struct record {
int loop;
char &ordW.X;
float sum;
;
3. Ieclare a structure variable called sample, defined from a structure of type struct record.
struct record sample;
=. Assign the value 1C to the field loop of the sample structure of type struct record.
sample.loop - 1/;
?. Print out %using printf& the value of the word array of the sample structure.
printf("2s"3 sample.&ord );
B. Iefine a new structure called birthdays, whose fields are a structure of type struct time called btime,
and a structure of type struct date, called bdate.
struct $irthdays {
struct time $time;
struct date $date;
;
1ATA CON%ERS#ON
#he following functions convert between data types.
atof() con(erts an ascii character array to a float
atoi() con(erts an ascii character array to an integer
itoa() con(erts an integer to a character array
HC
A)ample
78 con(ert a string to an integer 87
#include <stdio.h>
#include <stdli$.h>
char stringWX - "145F";
main()
{
int sum;
sum - atoi( string );
printf(",um - 2d\n"3 sum );

78 con(ert an integer to a string 87


#include <stdio.h>
#include <stdli$.h>
main()
{
int sum;
char $uffW4/X;
printf(">nter in an integer ");
scanf(" 2d"3 Msum );
printf( "!s a string it is 2s\n"3 itoa( sum3 $uff3 1/ ) );

<ote that itoa() ta%es three parameters3


the integer to $ con(erted

a character $uffer into &hich the resultant string is stored

a radi9 (alue (1/-decimal3 1@-he9adecimal)

Dn addition3 itoa() returns a pointer to the resultant string.


.#&E #NPUT*OUTPUT
#o work with files, the library routines must be included into your programs. #his is done by the
statement,
#include <stdio.h>
H1
as the first statement of your program.
US#NG .#&ES
1e/lare a <ariable of type .#&E
#o use files in C programs, you must declare a file variable to use. #his variable must be of
type .#&E, and be declared as a pointer type.
.#&E is a predefined type. *ou declare a variable of this type as
IDA> 8in)file;
#his declares infile to be a pointer to a file.
Asso/iate t'e <ariable ;it' a file using fopenDE
-efore using the variable, it is associated with a specific file by using the fopen() function,
which accepts the pathname for the file and the access mode %like reading or writing&.

in)file - fopen( "myfile.dat"3 "r" );


n this e)ample, the file myfile>-at in the current directory is opened for rea- access.
Pro/ess t'e -ata in t'e file
'se the appropriate file routines to process the data
,'en finis'e- pro/essing t'e file( /lose it
'se the fclose() function to close the file.

fclose( in)file );
#he following illustrates the fopen function, and adds testing to see if the file was opened successfully.
#include <stdio.h>
78 declares pointers to an input file3 and the fopen function 87
IDA> 8input)file3 8fopen ();
78 the pointer of the input file is assigned the (alue returned from the
fopen call. 87
78 fopen tries to open a file called datain for read only. <ote that 87
78 "&" - &rite3 and "a" - append. 87
input)file - fopen("datain"3 "r");
78 #he pointer is no& chec%ed. Df the file &as opened3 it &ill point to
the first 87
78 character of the file. Df not3 it &ill contain a <KAA or /. 87
if( input)file -- <KAA ) {
printf("888 datain could not $e opened.\n");
printf("returning to dos.\n");
e9it(1);

H3
+"#AL Consider the following statement, which combines the opening of the file and its test to see if
it was successfully opened into a single statement.
if(( input)file - fopen ("datain"3 "r" )) -- <KAA ) {
printf("888 datain could not $e opened.\n");
printf("returning to dos.\n");
e9it(1);

#NPUTT#NG*OUTPUTT#NG S#NG&E C2ARACTERS


2ingle characters may be readJwritten with files by use of the two functions, getc(), and putc().
int ch;
ch - getc( input)file ); 78 assigns character to ch 87
#he getc() also returns the value A"F %end of file&, so
&hile( (ch - getc( input)file )) P- >CI )
......................
+"#A that the putc0getc are similar to getchar0putchar e)cept that arguments are supplied specifying
the J" device.
putc(?\n?3 output)file ); 78 &rites a ne&line to output file 87
C&OS#NG .#&ES
8hen the operations on a file are completed, it is closed before the program terminates. #his allows
the operating system to cleanup any resources or buffers associated with the file. #he fclose() function
is used to close the file and flush any buffers associated with the file.
fclose( input)file );
fclose( output)file );
COP3#NG A .#&E
#he following demonstrates copying one file to another using the functions we have Rust covered.
#include <stdio.h>
main() 78 ICCPY.C 87
{
char in)nameW4.X3 out)nameW4.X;
IDA> 8in)file3 8out)file3 8fopen ();
int c;
H=
printf("Iile to $e copiedU\n");
scanf("24Fs"3 in)name);
printf("Cutput filenameU\n");
scanf("24Fs"3 out)name);
in)file - fopen ( in)name3 "r");
if( in)file -- <KAA )
printf("Cannot open 2s for reading.\n"3 in)name);
else {
out)file - fopen (out)name3 "&");
if( out)file -- <KAA )
printf("Can?t open 2s for &riting.\n"3out)name);
else {
&hile( (c - getc( in)file)) P- >CI )
putc (c3 out)file);
putc (c3 out)file); 78 copy >CI 87
printf("Iile has $een copied.\n");
fclose (out)file);

fclose (in)file);

TEST#NG .OR T2E En- Of .ile TERM#NATOR DfeofE


#his is a built in function incorporated with the stdio#h routines. t returns 1 if the file pointer is at the
end of the file.
if( feof ( input)file ))
printf("Jan out of data.\n");
T2E fprintf AN1 fs/anf STATEMENTS
#hese perform the same function as printf and scanf, but work on files. Consider,
fprintf(output)file3 "<o& is the time for all..\n");
fscanf(input)file3 "2f"3 Mfloat)(alue);
T2E fgets AN1 fputs STATEMENTS
#hese are useful for reading and writing entire lines of data toJfrom a file. f buffer is a pointer to a
character array and n is the ma)imum number of characters to be stored, then
fgets ($uffer3 n3 input)file);
will read an entire line of te)t %ma) chars E n& into buffer until the newline character or nEma),
whichever occurs first. #he function places a +'.. character after the last character in the buffer. #he
function will be e7ual to a +'.. if no more data e)ists.
fputs ($uffer3 output)file);
H?
writes the characters in buffer until a +'.. is found. #he +'.. character is not written to the
output_file.
+"#AL fgets does not store the newline into the buffer, fputs will append a newline to the line written
to the output file.
Pra/tise E8er/ise IA .ile 2an-ling
1. Iefine an input file handle called input_file, which is a pointer to a type F.A.
IDA> 8input)file;
3. 'sing input_file, open the file results#dat for read mode.
input)file - fopen( "results.dat"3 "r" );
=. 8rite C statements which tests to see if input_file has opened the data file successfully. f not, print
an error message and e)it the program.
if( input)file -- <KAA ) {
printf("Kna$le to open file.\n");\
e9it(1);

?. 8rite C code which will read a line of characters %terminated by a 9n& from input_file into a
character array called buffer. +'.. terminate the buffer upon reading a 9n.
int ch3 loop - /;
ch - fgetc( input)file );
&hile( (ch P- ?\n?) MM (ch P- >CI) ) {
$ufferWloopX - ch;
loop00;
ch - fgetc( input)file );

$ufferWloopX - <KAA;
B. Close the file associated with input_file.
fclose( input)file );
HB
.ile 'an-ling using openDE( rea-DE( ;riteDE an- /loseDE
#he previous e)amples of file handling deal with File Control -locks %FC-&. 'nder (2I"2 v=.) %or
greater& and '+, systems, file handling is often done using handles, rather than file control blocks.
8riting programs using handles ensures portability of source code between different operating
systems. 'sing handles allows the programmer to treat the file as a stream of characters.
openDE
#include <fcntl.h>
int open( char 8filename3 int access3 int permission );
#he available access modes are
C)JBC<AY C)QJC<AY C)JBQJ
C)!PP><B C)GD<!JY C)#>E#
#he permissions are
,)DQJD#> ,)DJ>!B ,)DQJD#> N ,)DJ>!B
#he open() function returns an integer value, which is used to refer to the file. f un; successful, it
returns ;1, and sets the global variable errno to indicate the error type.
rea-DE
#include <fcntl.h>
int read( int handle3 (oid 8$uffer3 int n$yte );
#he read() function attempts to read nbytes from the file associated with handle, and places the
characters read into buffer. f the file is opened using "O#A,#, it removes carriage returns and detects
the end of the file.
#he function returns the number of bytes read. "n end;of;file, C is returned, on error it returns ;1,
setting errno to indicate the type of error that occurred.
;riteDE
#include <fcntl.h>
int &rite( int handle3 (oid 8$uffer3 int n$yte );
#he write() function attempts to write nbytes from buffer to the file associated with handle. "n te)t
files, it e)pands each .F to a C!J.F.
#he function returns the number of bytes written to the file. A return value of ;1 indicates an error,
with errno set appropriately.
HF
/loseDE
#include <fcntl.h>
int close( int handle );
#he close() function closes the file associated with handle. #he function returns C if successful, ;1 to
indicate an error, with errno set appropriately.
PO#NTERS
Pointers enable us to effectively represent comple) data structures, to change values as arguments to
functions, to work with memory which has been dynamically allocated, and to more concisely and
efficiently deal with arrays. A pointer provides an indirect means of accessing the value of a particular
data item. .ets see how pointers actually work with a simple e)ample,
int count - 1/3 8int)pointer;
declares an integer count with a value of 1C, and also an integer pointer called int_pointer. +ote that
the prefi) Q defines the variable to be of type pointer. #o set up an indirect reference between
int_pointer and count, the 0 prefi) is used, ie,
int)pointer - Mcount;
#his assigns the memory address of count to intOpointer, not the actual value of count stored at that
address.
PO#NTERS CONTA#N MEMOR3 A11RESSES( NOT %A&UES@
#o reference the value of count using int_pointer, the Q is used in an assignment, eg,
9 - 8int)pointer;
2ince int_pointer is set to the memory address of count, this operation has the effect of assigning the
contents of the memory address pointed to by int_pointer to the variable x, so that after the operation
variable x has a value of 1C.
#include <stdio.h>
main()
{
int count - 1/3 93 8int)pointer;
78 this assigns the memory address of count to int)pointer 87
int)pointer - Mcount;
78 assigns the (alue stored at the address specified $y int)pointer
to 9 87
9 - 8int)pointer;
HG
printf("count - 2d3 9 - 2d\n"3 count3 9);

#his however, does not illustrate a good use for pointers.


#he following program illustrates another way to use pointers, this time with characters,
#include <stdio.h>
main()
{
char c - ?O?;
char 8char)pointer - Mc;
printf("2c 2c\n"3 c3 8char)pointer);
c - ?H?;
printf("2c 2c\n"3 c3 8char)pointer);
8char)pointer - ?Y?;
78 assigns Y as the contents of the memory address specified $y
char)pointer 87
printf("2c 2c\n"3 c3 8char)pointer);

N E"ERC#SE C)0
Ietermine the output of the pointer programs P1, P3, and P=.
78 P1.C illustrating pointers 87
#include <stdio.h>
main()
{
int count - 1/3 93 8int)pointer;
78 this assigns the memory address of count to int)pointer 87
int)pointer - Mcount;
78 assigns the (alue stored at the address specified $y int)pointer
to 9 87
9 - 8int)pointer;
printf("count - 2d3 9 - 2d\n"3 count3 9);

78 P4.C Iurther e9amples of pointers 87


HK
#include <stdio.h>
main()
{
char c - ?O?;
char 8char)pointer - Mc;
printf("2c 2c\n"3 c3 8char)pointer);
c - ?7?;
printf("2c 2c\n"3 c3 8char)pointer);
8char)pointer - ?(?;
78 assigns ( as the contents of the memory address specified $y
char)pointer 87
printf("2c 2c\n"3 c3 8char)pointer);

U Ietermine the output of the pointer programs P1, P3, and P=.
78 P1.C illustrating pointers 87
#include <stdio.h>
main()
{
int count - 1/3 93 8int)pointer;
78 this assigns the memory address of count to int)pointer 87
int)pointer - Mcount;
78 assigns the (alue stored at the address specified $y int)pointer
to 9 87
9 - 8int)pointer;
printf("count - 2d3 9 - 2d\n"3 count3 9);

count - 1/3 9 - 1/;


78 P4.C Iurther e9amples of pointers 87
#include <stdio.h>
main()
{
char c - ?O?;
char 8char)pointer - Mc;
printf("2c 2c\n"3 c3 8char)pointer);
c - ?7?;
printf("2c 2c\n"3 c3 8char)pointer);
8char)pointer - ?(?;
HH
78 assigns ( as the contents of the memory address specified $y
char)pointer 87
printf("2c 2c\n"3 c3 8char)pointer);

O O
7 7
( (
78 P5.C !nother program &ith pointers 87
#include <stdio.h>
main()
{
int i13 i43 8p13 8p4;
i1 - .;
p1 - Mi1;
i4 - 8p1 7 4 0 1/;
p4 - p1;
printf("i1 - 2d3 i4 - 2d3 8p1 - 2d3 8p4 - 2d\n"3 i13 i43 8p13 8p4);

i1 - .3 i4 - 143 8p1 - .3 8p4 - .


Pra/tise E8er/ise $= Pointers
1. Ieclare a pointer to an integer called address.
int 8address;
3. Assign the address of a float variable balance to the float pointer temp.
temp - M$alance;
=. Assign the character value $8$ to the variable pointed to by the char pointer letter.
8letter - ?Q?;
?. 8hat is the output of the following program segment>
int count - 1/3 8temp; sum - /;
1CC
temp - Mcount;
8temp - 4/;
temp - Msum;
8temp - count;
printf("count - 2d3 8temp - 2d3 sum - 2d\n"3 count3 8temp3 sum );
count - 4/3 8temp - 4/3 sum - 4/
B. Ieclare a pointer to the te)t string 1Pello1 called message.
char 8message - "*ello";
PO#NTERS AN1 STRUCTURES
Consider the following,
struct date {
int month3 day3 year;
;
struct date todays)date3 8date)pointer;
date)pointer - Mtodays)date;
(8date)pointer).day - 41;
(8date)pointer).year - 1S6.;
(8date)pointer).month - /;;
00(8date)pointer).month;
if((8date)pointer).month -- /6 )
......
Pointers to structures are so often used in C that a special operator e)ists. #he structure pointer
operator, the ;\, permits e)pressions that would otherwise be written as,
(89).y
to be more clearly e)pressed as
9L>y
making the if statement from above program
if( date)pointerL>month -- /6 )
.....
78 Program to illustrate structure pointers 87
#include <stdio.h>
1C1
main()
{
struct date { int month3 day3 year; ;
struct date today3 8date)ptr;
date)ptr - Mtoday;
date)ptrL>month - S;
date)ptrL>day - 4.;
date)ptrL>year - 1S65;
printf("#odays date is 2d72d72d.\n"3 date)ptrL>month3 \
date)ptrL>day3 date)ptrL>year 2 1//);

2o far, all that has been done could$ve been done without the use of pointers. 2hortly, the real value of
pointers will become apparent.
STRUCTURES CONTA#N#NG PO#NTERS
+aturally, a pointer can also be a member of a structure.
struct int)pointers {
int 8ptr1;
int 8ptr4;
;
n the above, the structure int_pointers is defined as containing two integer pointers, ptr1 and ptr. A
variable of type struct intOpointers can be defined in the normal way, eg,
struct int)pointers ptrs;
#he variable ptrs can be used normally, eg, consider the following program,
#include <stdio.h>
main() 78 Dllustrating structures containing pointers 87
{
struct int)pointers { int 8ptr13 8ptr4; ;
struct int)pointers ptrs;
int i1 - 1.F3 i4;
ptrs.ptr1 - Mi1;
ptrs.ptr4 - Mi4;
(8ptrs).ptr4 - LS;;
printf("i1 - 2d3 8ptrs.ptr1 - 2d\n"3 i13 8ptrs.ptr1);
printf("i4 - 2d3 8ptrs.ptr4 - 2d\n"3 i43 8ptrs.ptr4);

#he following diagram may help to illustrate the connection,


QEEEEEEEEEEEEQ
Q i1 QIEEEEEEEEEEEEEE
1C3
QEEEEEEEEEEEEQ Q
Q i; QIEEEEEEE Q
QEEEEEEEEEEEEQ Q Q
Q Q Q Q
QEEEEEEEEEEEEQ Q Q
Q 0tr1 QEEEEEEEEEEEEEEE
QEEEEEEEEEEEEQ Q 0trs
Q 0tr; QEEEEEEEE
QEEEEEEEEEEEEQ
PO#NTERS AN1 C2ARACTER STR#NGS
A pointer may be defined as pointing to a character string.
#include <stdio.h>
main()
{
char 8te9t)pointer - "Rood morningP";
for( ; 8te9t)pointer P- ?\/?; 00te9t)pointer)
printf("2c"3 8te9t)pointer);

or another program illustrating pointers to te)t strings,


#include <stdio.h>
main()
{
static char 8daysWX - {",unday"3 "Zonday"3 "#uesday"3 "Qednesday"3
\
"#hursday"3 "Iriday"3
",aturday";
int i;
for( i - /; i < @; 00i )
printf( "2s\n"3 daysWiX);

!emember that if the declaration is,


char 8pointer - ",unday";
then the null character 5 $9C$ 6 is automatically appended to the end of the te)t string. #his means that
:s may be used in a printf statement, rather than using a for loop and :c to print out the contents of
the pointer. #he :s will print out all characters till it finds the null terminator.
Pra/tise E8er/ise $$ Pointers O Stru/tures
1. Ieclare a pointer to a structure of type date called dates.
1C=
struct date 8dates;
3. f the above structure of type date comprises three integer fields, day, month, year, assign the value
1C to the field day using the dates pointer.
datesL>day - 1/;
=. A structure of type machine contains two fields, an integer called name, and a char pointer called
memory. 2how what the definition of the structure looks like.
QEEEEEEEEEEEQ IEEEEEEEEE
Q Q name Q
QEEEEEEEEEEEQ Q machine
Q Q memory Q
QEEEEEEEEEEEQ IEEEEEEEEE
?. A pointer called mpu121 of type machine is declared. 8hat is the command to assign the value
+'.. to the field memory.
mpu@F1L>memory - (char 8) <KAA;
B. Assign the address of the character array %34type to the field memory using the pointer mpu121.
mpu@F1L>memory - CPKtype;
F. Assign the value 1C to the field name using the pointer mpu121.
mpu@F1L>name - 1/;
G. A structure pointer times of type time %which has three fields, all pointers to integers, day, month and
year respectively& is declared. 'sing the pointer times, update the field day to 1C.
8(timesL>day) - 1/;
K. An array of pointers %1C elements& of type time %as detailed above in G.&, called sample is declared.
'pdate the field month of the third array element to 13.
1C?
8(sampleW4XL>month) - 14;
#include <stdio.h>
struct machine {
int name;
char 8memory;
;
struct machine p13 8mpu@F1;
main()
{
p1.name - 5;
p1.memory - "hello";
mpu@F1 - Mp1;
printf("name - 2d\n"3 mpu@F1L>name );
printf("memory - 2s\n"3 mpu@F1L>memory );
mpu@F1L>name - 1/;
mpu@F1L>memory - (char 8) <KAA;
printf("name - 2d\n"3 mpu@F1L>name );
printf("memory - 2s\n"3 mpu@F1L>memory );

#include <stdio.h>
struct time {
int 8day;
int 8month;
int 8year;
;
struct time t13 8times;
main()
{
int d-.3 m-143 y-1SS.;
t1.day - Md;
t1.month - Mm;
t1.year - My;
printf("dayUmonthUyear - 2dU2dU2d\n"3 8t1.day3 8t1.month3 8t1.year );
times - Mt1;
8(timesL>day) - 1/;
printf("dayUmonthUyear - 2dU2dU2d\n"3 8t1.day3 8t1.month3 8t1.year );

1CB
Pra/tise E8er/ise $$a Pointers O Stru/tures
Ietermine the output of the following program.
#include <stdio.h>
#include <string.h>
struct record {
char nameW4/X;
int id;
float price;
;
(oid editrecord( struct record 8 );
(oid editrecord( struct record 8goods )
{
strcpy( goodsL>name3 "Ga%ed Geans" );
goodsL>id - 44/;
(8goods).price - 4.4/;
printf("<ame - 2s\n"3 goodsL>name );
printf("DB - 2d\n"3 goodsL>id);
printf("Price - 2.4f\n"3 goodsL>price );

main()
{
struct record item;
strcpy( item.name3 "Jed Plum :am");
editrecord( Mitem );
item.price - 4.;.;
printf("<ame - 2s\n"3 item.name );
printf("DB - 2d\n"3 item.id);
printf("Price - 2.4f\n"3 item.price );

1. -efore call to editrecord%&


" item.name - "Jed Plum :am"
item.id - /
item.price - /./
3. After return from editrecord%&
" item.name - "Ga%ed Geans"
item.id - 44/
item.price - 4.4/
1CF
=. #he final values of values, item.name, item.id, item.price
" item.name - "Ga%ed Geans"
item.id - 44/
item.price - 4.;.
C)B E8amples on Pointer Usage
Ietermine the output of the following program.
#include <stdio.h>
#include <string.h>
struct sample {
char 8name;
int 8id;
float price;
;
static char productWX-"Jed Plum :am";
main()
{
int code - 5143 num$er;
char nameWX - "Ga%ed $eans";
struct sample item;
item.name - product;
item.id - Mcode;
item.price - 4.;.;
item.name - name;
num$er - 8item.id;
printf("<ame - 2s\n"3 item.name );
printf("DB - 2d\n"3 8item.id);
printf("Price - 2.4f\n"3 item.price );

" <ame - Ga%ed Geans


DB - 514
Price - 4.;.
C)F E8amples on Pointer Usage
Ietermine the output of the following program.
#include <stdio.h>
#include <string.h>
struct sample {
char 8name;
1CG
int 8id;
float price;
;
static char productWX - "Rreggs Coffee";
static float price1 - 5.4/;
static int id - ;;5;
(oid printrecord( struct sample 8 );
(oid printrecord( struct sample 8goods )
{
printf("<ame - 2s\n"3 goodsL>name );
printf("DB - 2d\n"3 8goodsL>id);
printf("Price - 2.4f\n"3 goodsL>price );
goodsL>name - MproductW/X;
goodsL>id - Mid;
goodsL>price - price1;

main()
{
int code - 1453 num$er;
char nameWX - "!pple Pie";
struct sample item;
item.id - Mcode;
item.price - 1.@.;
item.name - name;
num$er - 8item.id;
printrecord( Mitem );
printf("<ame - 2s\n"3 item.name );
printf("DB - 2d\n"3 8item.id);
printf("Price - 2.4f\n"3 item.price );

U 8hat are we trying to print out>


8hat does it evaluate to>
eg,
printf("DB - 2d\n"3 8goodsL>id);
2d is an integer
&e &ant the (alue to $e a (aria$le integer type
goodsL>id3
&hat is id3 its a pointer3 so &e mean contents of3
therefor &e use 8goodsL>id
&hich e(aluates to an integer type
<ame - !pple Pie
DB - 145
Price - 1.@.
1CK
<ame - Rreggs Coffee
DB - ;;5
Price - 5.4/
.ile 2an-ling E8ample
78 Iile handling e9ample for PJ1/1 87
78 processing an !,CDD file of records 87
78 Qritten $y G. Gro&n3 !pril 1SSF 87
78 process a goods file3 and print out 87
78 all goods &here the Vuantity on 87
78 hand is less than or eVual to the 87
78 reLorder le(el. 87
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdli$.h>
78 definition of a record of type goods 87
struct goods {
char nameW4/X; 78 name of product 87
float price; 78 price of product 87
int Vuantity; 78 Vuantity on hand 87
int reorder; 78 reLorder le(el 87
;
78 function prototypes 87
(oid mye9it( int );
(oid processfile( (oid );
(oid printrecord( struct goods );
int getrecord( struct goods 8 );
78 glo$al data (aria$les 87
IDA> 8fopen()3 8input)file; 78 input file pointer 87
78 pro(ides a tidy means to e9it program gracefully 87
(oid mye9it( int e9itcode )
{
if( input)file P- <KAA )
fclose( input)file );
e9it( e9itcode );

78 prints a record 87
(oid printrecord( struct goods record )
{
printf("\nProduct name\t2s\n"3 record.name );
printf("Product price\t2.4f\n"3 record.price );
printf("Product Vuantity\t2d\n"3 record.Vuantity );
printf("Product reorder le(el\t2d\n"3 record.reorder );

1CH
78 reads one record from inputfile into ?record?3 returns 1 for success 87
int getrecord( struct goods 8record )
{
int loop - /3 ch;
char $ufferWF/X;
ch - fgetc( input)file );
78 s%ip to start of record 87
&hile( (ch -- ?\n?) NN (ch -- ? ?) MM (ch P- >CI) )
ch - fgetc( input)file );
if( ch -- >CI ) return /;
78 read product name 87
&hile( (ch P- ?\n?) MM (ch P- >CI)) {
$ufferWloop00X - ch;
ch - fgetc( input)file );

$ufferWloopX - /;
strcpy( recordL>name3 $uffer );
if( ch -- >CI ) return /;
78 s%ip to start of ne9t field 87
&hile( (ch -- ?\n?) NN (ch -- ? ?) MM (ch P- >CI) )
ch - fgetc( input)file );
if( ch -- >CI ) return /;
78 read product price 87
loop - /;
&hile( (ch P- ?\n?) MM (ch P- >CI)) {
$ufferWloop00X - ch;
ch - fgetc( input)file );

$ufferWloopX - /;
recordL>price - atof( $uffer );
if( ch -- >CI ) return /;
78 s%ip to start of ne9t field 87
&hile( (ch -- ?\n?) NN (ch -- ? ?) MM (ch P- >CI) )
ch - fgetc( input)file );
if( ch -- >CI ) return /;
78 read product Vuantity 87
loop - /;
&hile( (ch P- ?\n?) MM (ch P- >CI)) {
$ufferWloop00X - ch;
ch - fgetc( input)file );

$ufferWloopX - /;
recordL>Vuantity - atoi( $uffer );
if( ch -- >CI ) return /;
78 s%ip to start of ne9t field 87
&hile( (ch -- ?\n?) NN (ch -- ? ?) MM (ch P- >CI) )
ch - fgetc( input)file );
if( ch -- >CI ) return /;
78 read product reorder le(el 87
11C
loop - /;
&hile( (ch P- ?\n?) MM (ch P- >CI)) {
$ufferWloop00X - ch;
ch - fgetc( input)file );

$ufferWloopX - /;
recordL>reorder - atoi( $uffer );
if( ch -- >CI ) return /;
return 1; 78 signify record has $een read successfully 87

78 processes file for records 87


(oid processfile( (oid )
{
struct goods record; 78 holds a record read from inputfile 87
&hile( P feof( input)file )) {
if( getrecord( Mrecord ) -- 1 ) {
if( record.Vuantity <- record.reorder )
printrecord( record );

else mye9it( 1 ); 78 error getting record 87

main()
{
char filenameWF/X; 78 name of data$ase file 87
printf(">9ample Roods JeLCrder Iile Program\n");
printf(">nter data$ase file ");
scanf(" 2s"3 filename );
input)file - fopen( filename3 "rt" );
if( input)file -- <KAA ) {
printf("Kna$le to open datafile 2s\n"3 filename );
mye9it( 1 );

processfile();
mye9it( / );

Please obtain the data file for this e)ample from your tutor, or via ftp.
.ile 2an-ling E8ample
#he data file for this e)ercise looks like,
baHed beans
1.;0
10
5
greggs coffee
;.C=
111
5
10
walls iceEcream
B.>C
5
5
cadburys chocs
>.5F
1;
10
&#N:E1 &#STS
A linked list is a comple) data structure, especially useful in systems or applications programming. A
linked list is comprised of a series of nodes, each node containing a data element, and a pointer to the
ne)t node, eg,
EEEEEEEE EEEEEEEE
Q data Q EEEJQ data Q
QEEEEEEEEQ Q QEEEEEEEEQ
Q 0ointerQEEEE Q 0ointerQ EEEJ *-,,
EEEEEEEE EEEEEEEE
A structure which contains a data element and a pointer to the ne)t node is created by,
struct list {
int (alue;
struct list 8ne9t;
;
#his defines a new data structure called list %actually the definition of a node&, which contains two
members. #he first is an integer called value. #he second is called next, which is a pointer to another
list structure %or node&. 2uppose that we declare two structures to be of the same type as list, eg,
struct list n13 n4;
#he ne)t pointer of structure n1 may be set to point to the n structure by
78 assign address of first element in n4 to the pointer ne9t of the n1
structure 87
n1.ne9t - Mn4;
which creates a link between the two structures.
78 AAD,#.C Program to illustrate lin%ed lists 87
#include <stdio.h>
struct list {
113
int (alue;
struct list 8ne9t;
;
main()
{
struct list n13 n43 n5;
int i;
n1.(alue - 1//;
n4.(alue - 4//;
n5.(alue - 5//;
n1.ne9t - Mn4;
n4.ne9t - Mn5;
i - n1.ne9tL>(alue;
printf(2d\n"3 n4.ne9tL>(alue);

+ot only this, but consider the following


n1.ne9t - n4.ne9t 78 deletes n4 87
n4)5.ne9t - n4.ne9t; 78 adds struct n4)5 87
n4.ne9t - Mn4)5;
n using linked list structures, it is common to assign the value of C to the last pointer in the list, to
indicate that there are no more nodes in the list, eg,
n5.ne9t - /;
Tra<ersing a linKe- list
78 Program to illustrate tra(ersing a list 87
#include <stdio.h>
struct list {
int (alue;
struct list 8ne9t;
;
main()
{
struct list n13 n43 n53 nF;
struct list 8list)pointer - Mn1;
n1.(alue - 1//;
n1.ne9t - Mn4;
n4.(alue - 4//;
n4.ne9t - Mn5;
n5.(alue - 5//;
n5.ne9t - MnF;
nF.(alue - F//;
nF.ne9t - /;
&hile( list)pointer P- / ) {
11=
printf("2d\n"3 list)pointerL>(alue);
list)pointer - list)pointerL>ne9t;

#his program uses a pointer called list_pointer to cycle through the linked list.
Pra/tise E8er/ise $) &ists
. Iefine a structure called node, which contains an integer element called data, and a pointer to a
structure of type node called next_node.
3. Ieclare three structures called node1, node, node5, of type node.
=. 8rite C statements which will link the three nodes together, with node1 at the head of the list, node3
second, and node= at the tail of the list. Assign the value +'.. to node=.ne)t to signify the end of the
list.
?. 'sing a pointer list, of type node, which has been initialised to the address of node1, write C
statements which will cycle through the list and print out the value of each nodes data field.
B. Assuming that pointer list points to node, what does the following statement do>
listL>ne9t)node - (struct node 8) <KAA;
F. Assuming the state of the list is that as in =., write C statements which will insert a new node
node1a between node1 and node3, using the pointer list %which is currently pointing to node1&.
Assume that a pointer new_node points to node node1a.
G. 8rite a function called delete_node, which accepts a pointer to a list, and a pointer to the node to be
deleted from the list, eg
(oid delete)node( struct node 8head3 struct node 8delnode );
K. 8rite a function called insert_node, which accepts a pointer to a list, a pointer to a new node to be
inserted, and a pointer to the node after which the insertion takes place, eg
(oid insert)node( struct node 8head3 struct node 8ne&node3 struct node
8pre(node );
Answers
11?
Pra/tise E8er/ise $) &ists
1. Iefine a structure called node, which contains an integer element called data, and a pointer to a
structure of type node called next_node.
struct node {
int data;
struct node 8ne9t)node;
;
3. Ieclare three structures called node1, node, node5, of type node.
struct node node13 node53 node5;
=. 8rite C statements which will link the three nodes together, with node1 at the head of the list, node3
second, and node= at the tail of the list. Assign the value +'.. to node=.ne)t to signify the end of the
list.
node1.ne9t)node - Mnode4;
node4.ne9t)node - Mnode5;
node5.ne9t)node - (struct node 8) <KAA;
?. 'sing a pointer list, of type node, which has been initialised to the address of node1, write C
statements which will cycle through the list and print out the value of each nodes data field.
&hile( list P- <KAA ) {
printf("2d\n"3 listL>data );
list - listL>ne9t)node;

B. Assuming that pointer list points to node, what does the following statement do>
listL>ne9t)node - (struct node 8) <KAA;
#he statement &rites a <KAA into the ne9t)node pointer3 ma%ing node4 the
end of
the list3 there$y erasing node5 from the list.
F. Assuming the state of the list is that as in =., write C statements which will insert a new node
node1a between node1 and node3, using the pointer list %which is currently pointing to node1&.
Assume that a pointer new_node points to node node1a.
11B
ne&)node.ne9t)node - list.ne9t)node;
list.ne9t)node - ne&)node;
G. 8rite a function called delete_node, which accepts a pointer to a list, and a pointer to the node to be
deleted from the list, eg
(oid delete)node( struct node 8head3 struct node 8delnode );
(oid delete)node( struct node 8head3 struct node 8delnode )
{
struct node 8list;
list - head;
&hile( listL>ne9t P- delnode ) {
list - listL>node;
listL>ne9t - delnodeL>ne9t;

K. 8rite a function called insert_node, which accepts a pointer to a list, a pointer to a new node to be
inserted, and a pointer to the node after which the insertion takes place, eg
(oid insert)node( struct node 8head3 struct node 8ne&node3 struct node
8pre(node );
(oid insert)node( struct node 8head3 struct node 8ne&node3 struct node
8pre(node )
{
struct node 8list;
list - head;
&hile( list P- pre(node )
list - listL>ne9t;
ne&nodeL>ne9t - listL>ne9t;
listL>ne9t - ne&node;

13NAM#C MEMOR3 A&&OCAT#ON DCA&&OC( S#LEO.( .REEE


t is desirable to dynamically allocate space for variables at runtime. t is wasteful when dealing with
array type structures to allocate so much space when declared, eg,
struct client clientsW1//X;
11F
#his practice may lead to memory contention or programs crashing. A far better way is to allocate
space to clients when needed.
#he C programming language allows users to dynamically allocate and deallocate memory when
re7uired. #he functions that accomplish this are calloc(), which allocates memory to a variable, si'eof,
which determines how much memory a specified variable occupies, and free(), which deallocates the
memory assigned to a variable back to the system.
S#LEO.
#he siMeof%& function returns the memory siMe of the re7uested variable. #his call should be used in
conRunction with the calloc() function call, so that only the necessary memory is allocated, rather than
a fi)ed siMe. Consider the following,
struct date {
int hour3 minute3 second;
;
int 9;
9 - si[eof( struct date );
x now contains the information re7uired by calloc() so that it can allocate enough memory to contain
another structure of type date.
CA&&OC
#his function is used to allocate storage to a variable whilst the program is running. #he function takes
two arguments that specify the number of elements to be reserved, and the siMe of each element
%obtained from si'eof& in bytes. #he function returns a character pointer %void in A+2 C& to the
allocated storage, which is initialiMed to Mero$s.
struct date 8date)pointer;
date)pointer - (struct date 8) calloc( 1/3 si[eof(struct date) );
#he %struct date Q& is a type cast operator which converts the pointer returned from calloc to a
character pointer to a structure of type date. #he above function call will allocate siMe for ten such
structures, and date_pointer will point to the first in the chain.
.REE
8hen the variables are no longer re7uired, the space which was allocated to them by calloc should be
returned to the system. #his is done by,
11G
free( date)pointer );
"ther C calls associated with memory are,
alloc allocate a $loc% of memory from the heap
malloc allocate a $loc% of memory3 do not [ero out
[ero [ero a section of memory
$loc%mo(e mo(e $ytes from one location to another
"ther routines may be included in the particular version of the compiler you may have, ie, for (2;
I"2 v=.C,
memccpy copies characters from one $uffer to another
memchr returns a pointer to the 1st occurrence of a
designated character searched for
memcmp compares a specified num$er of characters
memcpy copies a specified num$er of characters
memset initialise a specified num$er of $ytes &ith a gi(en
character
mo(edata copies characters
E"AMP&E O. 13NAM#C A&&OCAT#ON
78 lin%ed list e9ample3 pr1/13 1SSF 87
#include <string.h>
#include <alloc.h>
#include <stdio.h>
#include <ctype.h>
#include <stdli$.h>
#include <conio.h>
78 definition of a node 87
struct node {
char dataW4/X;
struct node 8ne9t;
;
struct node 8 initialise( (oid );
(oid freenodes( struct node 8 );
int insert( struct node 8 );
(oid delete( struct node 83 struct node 8 );
(oid list( struct node 8 );
(oid menu( struct node 83 struct node 8 );
(oid readline( char WX );
11K
(oid readline( char $uffWX )
{
int ch3 loop - /;
ch - getche();
&hile( ch P- ?\r? ) {
$uffWloopX - ch;
loop00;
ch - getche();

$uffWloopX - /;

struct node 8 initialise( (oid )


{
return( (struct node 8) calloc(13 si[eof( struct node 8) ));

78 free memory allocated for node 87


(oid freenodes( struct node 8headptr )
{
struct node 8temp;
&hile( headptr ) {
temp - headptrL>ne9t;
free( headptr );
headptr - temp;

78 insert a ne& node after nodeptr3 return 1 - success 87


int insert( struct node 8nodeptr )
{
char $ufferW4/X;
struct node 8ne&ptr;
ne&ptr - initialise(); 78 allocate a ne& node 87
if( ne&ptr -- <KAA ) {
return /;

else { 78 fill in its data and add to the list 87
ne&ptrL>ne9t - nodeptrL>ne9t;
nodeptrL>ne9t - ne&ptr;
nodeptr - ne&ptr;
printf("\n>nter data LLL>");
readline( $uffer );
strcpy( nodeptrL>data3 $uffer );

return 1;

78 delete a node from list 87


(oid delete( struct node 8headptr3 struct node 8nodeptr )
{
struct node 8deletepointer3 8pre(iouspointer;
char $ufferW4/X;
11H
deletepointer - headptrL>ne9t;
pre(iouspointer - headptr;
78 find the entry 87
printf("\n>nter name to $e deleted LLL>");
readline( $uffer );
&hile( deletepointer ) {
if( strcmp( $uffer3 deletepointerL>data ) -- / ) {
78 delete node pointed to $y delete pointer 87
pre(iouspointerL>ne9t - deletepointerL>ne9t;
$rea%;

else {
78 goto ne9t node in list 87
deletepointer - deletepointerL>ne9t;
pre(iouspointer - pre(iouspointerL>ne9t;


78 did &e find it+ 87
if( deletepointer -- <KAA )
printf("\n\//;>rror3 2s not found or list empty\n"3 $uffer);
else {
free( deletepointer );
78 ad'ust nodeptr to the last node in list 87
nodeptr - headptr;
&hile( nodeptrL>ne9t P- <KAA )
nodeptr - nodeptrL>ne9t;

78 print out the list 87


(oid list( struct node 8headptr )
{
struct node 8listpointer;
listpointer - headptrL>ne9t;
if( listpointer -- <KAA )
printf("\n#he list is empty.\n");
else {
&hile( listpointer ) {
printf("<ame U 24/s\n"3 listpointerL>data );
listpointer - listpointerL>ne9t;

78 main menu system 87


(oid menu( struct node 8headp3 struct node 8nodep )
{
int menuchoice - 1;
char $ufferW4/X;
&hile( menuchoice P- F ) {
printf("1 insert a node\n");
printf("4 delete a node\n");
printf("5 list nodes\n");
printf("F Vuit\n");
13C
printf(">nter choice LL>");
readline( $uffer );
menuchoice - atoi( $uffer );
s&itch( menuchoice ) {
case 1 U if( insert( nodep ) -- / )
printf("\n\//;Dnsert failed.\n");
$rea%;
case 4 U delete( headp3 nodep ); $rea%;
case 5 U list( headp ); $rea%;
case F U $rea%;
default U printf("\n\//;Dn(alid option\n"); $rea%;

main()
{
struct node 8headptr3 8nodeptr;
headptr - initialise();
nodeptr - headptr;
headptrL>ne9t - <KAA;
menu( headptr3 nodeptr );
freenodes( headptr );

Anot'er &inKe- &ist E8ample


78 lin%ed list e9ample 87
#include <stdio.h>
#include <alloc.h>
#include <stdli$.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
78 function prototypes 87
struct node 8 initnode( char 83 int );
(oid printnode( struct node 8 );
(oid printlist( struct node 8 );
(oid add( struct node 8 );
struct node 8 searchname( struct node 83 char 8 );
(oid deletenode( struct node 8 );
(oid insertnode( struct node 8 );
(oid deletelist( struct node 8 );
78 definition of a data node for holding student information 87
struct node {
char nameW4/X;
int id;
struct node 8ne9t;
;
78 head points to first node in list3 end points to last node in list 87
78 initialise $oth to <KAA3 meaning no nodes in list yet 87
131
struct node 8head - (struct node 8) <KAA;
struct node 8end - (struct node 8) <KAA;
78 this initialises a node3 allocates memory for the node3 and returns 87
78 a pointer to the ne& node. Zust pass it the node details3 name and id 87
struct node 8 initnode( char 8name3 int id )
{
struct node 8ptr;
ptr - (struct node 8) calloc( 13 si[eof(struct node ) );
if( ptr -- <KAA ) 78 error allocating node+ 87
return (struct node 8) <KAA; 78 then return <KAA3 else 87
else { 78 allocated node successfully 87
strcpy( ptrL>name3 name ); 78 fill in name details 87
ptrL>id - id; 78 copy id details 87
return ptr; 78 return pointer to ne& node 87

78 this prints the details of a node3 eg3 the name and id 87


78 must pass it the address of the node you &ant to print out 87
(oid printnode( struct node 8ptr )
{
printf("<ame L>2s\n"3 ptrL>name );
printf("DB L>2d\n"3 ptrL>id );

78 this prints all nodes from the current address passed to it. Df you 87
78 pass it ?head?3 then it prints out the entire list3 $y cycling through 87
78 each node and calling ?printnode? to print each node found 87
(oid printlist( struct node 8ptr )
{
&hile( ptr P- <KAA ) 78 continue &hilst there are nodes left 87
{
printnode( ptr ); 78 print out the current node 87
ptr - ptrL>ne9t; 78 goto the ne9t node in the list 87

78 this adds a node to the end of the list. You must allocate a node and 87
78 then pass its address to this function 87
(oid add( struct node 8ne& ) 78 adding to end of list 87
{
if( head -- <KAA ) 78 if there are no nodes in list3 then 87
head - ne&; 78 set head to this ne& node 87
endL>ne9t - ne&; 78 lin% in the ne& node to the end of the list 87
ne&L>ne9t - <KAA; 78 set ne9t field to signify the end of list 87
end - ne&; 78 ad'ust end to point to the last node 87

78 search the list for a name3 and return a pointer to the found node 87
78 accepts a name to search for3 and a pointer from &hich to start. Df 87
78 you pass the pointer as ?head?3 it searches from the start of the list 87
struct node 8 searchname( struct node 8ptr3 char 8name )
{
&hile( strcmp( name3 ptrL>name ) P- / ) { 78 &hilst name not found 87
ptr - ptrL>ne9t; 78 goto the ne9t node 87
if( ptr -- <KAA ) 78 stop if &e are at the 87
133
$rea%; 78 of the list 87

return ptr; 78 return a pointer to 87
78 found node or <KAA 87
78 deletes the specified node pointed to $y ?ptr? from the list 87
(oid deletenode( struct node 8ptr )
{
struct node 8temp3 8pre(;
temp - ptr; 78 node to $e deleted 87
pre( - head; 78 start of the list3 &ill cycle to node $efore temp 87
if( temp -- pre( ) { 78 are &e deleting first node 87
head - headL>ne9t; 78 mo(es head to ne9t node 87
if( end -- temp ) 78 is it end3 only one node+ 87
end - endL>ne9t; 78 ad'ust end as &ell 87
free( temp ); 78 free space occupied $y node 87

else { 78 if not the first node3 then 87
&hile( pre(L>ne9t P- temp ) { 78 mo(e pre( to the node $efore87
pre( - pre(L>ne9t; 78 the one to $e deleted 87

pre(L>ne9t - tempL>ne9t; 78 lin% pre(ious node to ne9t 87
if( end -- temp ) 78 if this &as the end node3 87
end - pre(; 78 then reset the end pointer 87
free( temp ); 78 free space occupied $y node 87

78 inserts a ne& node3 uses name field to align node as alpha$etical list 87
78 pass it the address of the ne& node to $e inserted3 &ith details all 87
78 filled in 87
(oid insertnode( struct node 8ne& )
{
struct node 8temp3 8pre(; 78 similar to deletenode 87
if( head -- <KAA ) { 78 if an empty list3 87
head - ne&; 78 set ?head? to it 87
end - ne&;
headL>ne9t - <KAA; 78 set end of list to <KAA 87
return; 78 and finish 87

temp - head; 78 start at $eginning of list 87
78 &hilst currentname < ne&name to $e inserted then 87
&hile( strcmp( tempL>name3 ne&L>name) < / ) {
temp - tempL>ne9t; 78 goto the ne9t node in list 87
if( temp -- <KAA ) 78 dont go past end of list 87
$rea%;

78 &e are the point to insert3 &e need pre(ious node $efore &e insert 87
78 first chec% to see if its inserting $efore the first nodeP 87
if( temp -- head ) {
ne&L>ne9t - head; 78 lin% ne9t field to original list 87
head - ne&; 78 head ad'usted to ne& node 87

13=
else { 78 o%ay3 so its not the first node3 a different approach 87
pre( - head; 78 start of the list3 &ill cycle to node $efore temp 87
&hile( pre(L>ne9t P- temp ) {
pre( - pre(L>ne9t;

pre(L>ne9t - ne&; 78 insert node $et&een pre( and ne9t 87
ne&L>ne9t - temp;
if( end -- pre( ) 78 if the ne& node is inserted at the 87
end - ne&; 78 end of the list the ad'ust ?end? 87

78 this deletes all nodes from the place specified $y ptr 87


78 if you pass it head3 it &ill free up entire list 87
(oid deletelist( struct node 8ptr )
{
struct node 8temp;
if( head -- <KAA ) return; 78 dont try to delete an empty list 87
if( ptr -- head ) { 78 if &e are deleting the entire list 87
head - <KAA; 78 then reset head and end to signify empty 87
end - <KAA; 78 list 87

else {
temp - head; 78 if its not the entire list3 read'ust end 87
&hile( tempL>ne9t P- ptr ) 78 locate pre(ious node to ptr 87
temp - tempL>ne9t;
end - temp; 78 set end to node $efore ptr 87

&hile( ptr P- <KAA ) { 78 &hilst there are still nodes to delete 87
temp - ptrL>ne9t; 78 record address of ne9t node 87
free( ptr ); 78 free this node 87
ptr - temp; 78 point to ne9t node to $e deleted 87

78 this is the main routine &here all the glue logic fits 87
main()
{
char nameW4/X;
int id3 ch - 1;
struct node 8ptr;
clrscr();
&hile( ch P- / ) {
printf("1 add a name \n");
printf("4 delete a name \n");
printf("5 list all names \n");
printf("F search for name \n");
printf(". insert a name \n");
printf("/ Vuit\n");
scanf("2d"3 Mch );
s&itch( ch )
{
case 1U 78 add a name to end of list 87
13?
printf(">nter in name LL ");
scanf("2s"3 name );
printf(">nter in id LL ");
scanf("2d"3 Mid );
ptr - initnode( name3 id );
add( ptr );
$rea%;
case 4U 78 delete a name 87
printf(">nter in name LL ");
scanf("2s"3 name );
ptr - searchname( head3 name );
if( ptr --<KAA ) {
printf("<ame 2s not found\n"3 name );

else
deletenode( ptr );
$rea%;
case 5U 78 list all nodes 87
printlist( head );
$rea%;
case FU 78 search and print name 87
printf(">nter in name LL ");
scanf("2s"3 name );
ptr - searchname( head3 name );
if( ptr --<KAA ) {
printf("<ame 2s not found\n"3 name );

else
printnode( ptr );
$rea%;
case .U 78 insert a name in list 87
printf(">nter in name LL ");
scanf("2s"3 name );
printf(">nter in id LL ");
scanf("2d"3 Mid );
ptr - initnode( name3 id );
insertnode( ptr );
$rea%;


deletelist( head );

PREPROCESSOR STATEMENTS
#he define statement is used to make programs more readable, and allow the inclusion of macros.
Consider the following e)amples,
#define #JK> 1 78 Bo not use a semiLcolon 3 # must $e first
character on line 87
#define I!A,> /
13B
#define <KAA /
#define !<B M
#define CJ N
#define >OK!A, --
game)o(er - #JK>;
&hile( list)pointer P- <KAA )
................
Macros
(acros are inline code which are substituted at compile time. #he definition of a macro, which accepts
an argument when referenced,
#define ,OK!J>(9) (9)8(9)
y - ,OK!J>(();
n this case, v is e7uated with x in the macro definition of s6uare, so the variable y is assigned the
s7uare of v. #he brackets in the macro definition of s6uare are necessary for correct evaluation. #he
e)pansion of the macro becomes
y - (() 8 (();
+aturally, macro definitions can also contain other macro definitions,
#define D,)ACQ>JC!,>(9) (( (9)>-?a?) MM ( (9) <-?[?) )
#define #C)KPP>JC!,>(9) (D,)ACQ>JC!,> (9)+(9)L?a?0?!?U(9))
&hile(8string) {
8string - #C)KPP>JC!,>(8string);
00string;

CON1#T#ONA& COMP#&AT#ONS
#hese are used to direct the compiler to compileJor not compile the lines that follow
#ifdef <KAA
#define <A 1/
#define ,P 54
#endif
n the preceding case, the definition of +. and 2P will only occur if +'.. has been defined prior to
the compiler encountering the Nifdef +'.. statement. #he scope of a definition may be limited by
13F
#undef <KAA
#his renders the identification of +'.. invalid from that point onwards in the source file.
type-ef
#his statement is used to classify e)isting C data types, eg,
typedef int counter; 78 redefines counter as an integer 87
counter '3 n; 78 counter no& used to define ' and n as integers
87
typedef struct {
int month3 day3 year;
B!#>;
B!#> todays)date; 78 same as struct date todays)date 87
ENUMERATE1 1ATA T3PES
Anumerated data type variables can only assume values which have been previously declared.
enum month { 'an - 13 fe$3 mar3 apr3 may3 'un3 'ul3 aug3 sep3 oct3 no(3
dec ;
enum month this)month;
this)month - fe$;
n the above declaration, month is declared as an enumerated data type. t consists of a set of values,
Ran to dec. +umerically, Ran is given the value 1, feb the value 3, and so on. #he variable this_month is
declared to be of the same type as month, then is assigned the value associated with feb. #hisOmonth
cannot be assigned any values outside those specified in the initialiMation list for the declaration of
month.
#include <stdio.h>
main()
{
char 8p&est - "&est"38pnorth - "north"3 8peast-"east"3 8psouth -
"south";
enum location { east-13 &est-43 south-53 north-F;
enum location direction;
13G
direction - east;
if( direction -- east )
printf("Cannot go 2s\n"3 peast);

#he variables defined in the enumerated variable location should be assigned initial values.
UN#ONS
#his is a special data type which looks similar to a structure, but is very different. #he declaration is,
union mi9ed {
char letter;
float radian;
int num$er;
;
union mi9ed all;
#he first declaration consists of a union of type mi)ed, which consists of a char, float, or int variable.
+"#A that it can be "+.* "+A of the variable types, they cannot coe)ist.
#his is due to the provision of a single memory address which is used to store the largest variable,
unlike the arrangement used for structures.
#hus the variable all can only be a character, a float or an integer at any one time. #he C language
keeps track of what all actually is at any given moment, but does not provide a check to prevent the
programmer accessing it incorrectly.
1EC&AR#NG %AR#AB&ES TO BE REG#STER BASE1
2ome routines may be time or space critical. Variables can be defined as being register based by the
following declaration,
register int inde9;
1EC&AR#NG %AR#AB&ES TO BE E"TERNA&
Pere variables may e)ist in separately compiled modules, and to declare that the variable is e)ternal,
e9tern int mo(e)num$er;
#his means that the data storage for the variable move_number resides in another source module,
which will be linked with this module to form an e)ecutable program. n using a variable across a
13K
number of independently compiled modules, space should be allocated in only one module, whilst all
other modules use the e)tern directive to access the variable.
NU&& STATEMENTS
#hese are statements which do not have any body associated with them.
78 sums all integers in array a containing n elements and initiali[es 87
78 t&o (aria$les at the start of the for loop 87
for( sum - /3 i - /; i < n; sum 0- aWi00X )
;
78 Copies characters from standard input to standard output until >CI is
reached 87
for( ; (c - getchar ()) P- >CI; putchar (c))
;
STR#NGS
Consider the following,
char 8te9t)pointer - "*ello said the man.";
#his defines a character pointer called text_pointer which points to the start of the te)t string $Pello
said the man$. #his message could be printed out by
printf("2s"3 te9t)pointer);
text_pointer holds the memory address of where the message is located in memory.
.ets append two strings together by using arrays.
#include <stdio.h>
main()
{
static char string1WX-{?*?3?e?3?l?3?l?3?o?3? ? ;
static char string4WX-{?s?3?a?3?i?3?d?3? ?3?t?3?h?3?e?3?
?3?m?3?a?3?n?3?.? ;
char string5W4.X;
int string)length1 - @3 string)length4 - 153 n;
for( n - /; n < string)length1; 00n )
string5WnX - string1WnX;
for( n - /; n < string)length4; 00n )
13H
string5Wn 0 string)length1X - string4WnX;
for(n - /; n < (stringlength10string)length4); 00n)
printf("2c"3 string5WnX);

Strings /ontinue-
#here are times that the length of a string may not be known. Consider the following improvements by
terminating each string with a null character.
#include <stdio.h>
main()
{
static char string1WX - "Gye Gye ";
static char string4WX - "lo(e.";
char string5W4.X;
int n - /3 n4;
for( ; string1WnX P- ?\/?; 00n )
string5WnX - string1WnX;
n4 - n; n - /;
for( ; string4WnX P- ?\/?; 00n )
string5Wn4 0 nX - string4WnX;
n4 0- n;
for(n - /; n < n4 ; 00n)
printf("2c"3 string5WnX);

Zinor modification to a$o(e program is3


string5Wn4 0 nX - ?\/?;
printf("2s"3 string5);
.URT2ER #MPRO%EMENTS by using PO#NTERS
#he previous program still re7uired the use of variables to keep track of string lengths. mplementing
concatenation by the use of pointers eliminates this, eg,
#include <stdio.h>
(oid concat( char 83 char 83 char 8 );
78 this functions copies the strings a and $ to the destination string c
87
(oid concat( char 8a3 char 8$3 char 8c)
1=C
{
&hile( 8a ) { 78 &hile( 8c00 - 8a00 ); 87
8c - 8a; 00a; 00c;

&hile( 8$ ) {
8c - 8$; 00$; 00c;

8c - ?\/?;

main()
{
static char string1WX - "Gye Gye ";
static char string4WX - "lo(e.";
char string5W4/X;
concat( string13 string43 string5);
printf("2s\n"3 string5);

US#NG str/at #N T2E &#BRAR3 ROUT#NE string>'


#he following program illustrates using the supplied function resident in the appropriate library file.
strcat() concatenates one string onto another and returns a pointer to the concatenated string.
#include <string.h>
#include <stdio.h>
main()
{
static char string1WX - "Gye Gye ";
static char string4WX - "lo(e.";
char 8string5;
string5 - strcat ( string13 string4 );
printf("2s\n"3 string5);

COMMAN1 &#NE ARGUMENTS


t is possible to pass arguments to C programs when they are e)ecuted. #he brackets which follow
main are used for this purpose. argc refers to the number of arguments passed, and argv+- is a pointer
array which points to each argument which is passed to main. A simple e)ample follows, which checks
to see if a single argument is supplied on the command line when the program is invoked.
#include <stdio.h>
main( int argc3 char 8arg(WX )
{
if( argc -- 4 )
printf("#he argument supplied is 2s\n"3 arg(W1X);
else if( argc > 4 )
1=1
printf("#oo many arguments supplied.\n");
else
printf("Cne argument e9pected.\n");

+ote that 7argv+0- is the name of the program invoked, which means that 7argv+1- is a pointer to the
first argument supplied, and 7argv+n- is the last argument. f no arguments are supplied, argc will be
one. #hus for n arguments, argc will be e7ual to n D 1. #he program is called by the command line,
myprog argument1
E"ERC#SE C)G
!ewrite the program which copies files, ie, FC"P*.C to accept the source and destination filenames
from the command line. nclude a check on the number of arguments passed.
Answer
!ewrite the program which copies files, ie, FC"P*.C to accept the source and destination filenames
from the command line. nclude a check on the number of arguments passed.
#include <stdio.h>
main( int argc3 char 8arg(WX)
{
IDA> 8in)file3 8out)file3 8fopen();
int c;
if( argc P- 5 )
{
printf("Dncorrect3 format is ICCPY source dest\n");
e9it(4);

in)file - fopen( arg(W1X3 "r");


if( in)file -- <KAA ) printf("Cannot open 2s for reading\n"3
arg(W1X);
else {
out)file - fopen( arg(W4X3 "&");
if ( out)file -- <KAA )
printf("Cannot open 2s for &riting\n"3 arg(W4X);
else {
printf("Iile copy program3 copying 2s to 2s\n"3
arg(W1X3 arg(W4X);
&hile ( (c-getc( in)file) ) P- >CI )
putc( c3 out)file );
putc( c3 out)file); 78 copy >CI 87
printf("Iile has $een copied.\n");
fclose( out)file);

fclose( in)file);

1=3

PO#NTERS TO .UNCT#ONS
A pointer can also be declared as pointing to a function. #he declaration of such a pointer is done by,
int (8func)pointer)();
#he parentheses around 7func_pointer are necessary, else the compiler will treat the declaration as a
declaration of a function. #o assign the address of a function to the pointer, the statement,
func)pointer - loo%up;
where loo*up is the function name, is sufficient. n the case where no arguments are passed to loo*up,
the call is
(8func)pointer)();
#he parentheses are needed to avoid an error. f the function loo*up returned a value, the function call
then becomes,
i - (8func)pointer)();
f the function accepted arguments, the call then becomes,
i - (8func)pointer)( argument13 argument43 argumentn);
SAMP&E CO1E .OR PO#NTERS TO .UNCT#ONS
Pointers to functions allow the creation of Rump tables and dynamic routine selection. A pointer is
assigned the start address of a function, thus, by typing the pointer name, program e)ecution Rumps to
the routine pointed to.
-y using a single pointer, many different routines could be e)ecuted, simply by re;directing the pointer
to point to another function. #hus, programs could use this to send information to a printer, console
device, tape unit etc, simply by pointing the pointer associated with output to the appropriate output
function4
#he following program illustrates the use of pointers to functions, in creating a simple shell program
which can be used to specify the screen mode on a C@A system.
1==
#include <stdio.h> 78 Iuncptr.c 87
#include <dos.h>
#define dim(9) (si[eof(9) 7 si[eof(9W/X) )
#define R>#ZCB> 1.
#define ,>#ZCB> /
#define \DBC!AA /E1/
#define ,CJ>><F/ 1
#define ,CJ>><6/ 5
#define ,CJ>><54/ F
#define ,CJ>><@F/ @
#define \DB)GDC,)C!AA(9) int6@( \DBC!AA3 M93 M9 )
int cls()3 scrF/()3 scr6/()3 scr54/()3 scr@F/()3 help()3 shellVuit();
union J>R, regs;
struct command)ta$le
{
char 8cmd)name;
int (8cmd)ptr) ();

cmdsWX-{"F/"3scrF/3"6/"3scr6/3"54/"3scr54/3"@F/"3scr@F/3"*>AP"3help3"CA,"3cls3">ED
#"3\
shellVuit;
cls()
{
regs.h.ah - R>#ZCB>; \DB)GDC,)C!AA( regs );
regs.h.ah - ,>#ZCB>; \DB)GDC,)C!AA( regs );

scrF/()
{
regs.h.ah - ,>#ZCB>;
regs.h.al - ,CJ>><F/;
\DB)GDC,)C!AA( regs );

scr6/()
{
regs.h.ah - ,>#ZCB>;
regs.h.al - ,CJ>><6/;
\DB)GDC,)C!AA( regs );

scr54/()
{
regs.h.ah - ,>#ZCB>;
regs.h.al - ,CJ>><54/;
\DB)GDC,)C!AA( regs );

scr@F/()
{
regs.h.ah - ,>#ZCB>;
regs.h.al - ,CJ>><@F/;
1=?
\DB)GDC,)C!AA( regs );

shellVuit()
{
e9it( / );

help()
{
cls();
printf("#he a(aila$le commands are; \n");
printf(" F/ ,ets F/ column mode\n");
printf(" 6/ ,ets 6/ column mode\n");
printf(" 54/ ,ets medium res graphics mode\n");
printf(" @F/ ,ets high res graphics mode\n");
printf(" CA, Clears the display screen\n");
printf(" *>AP #hese messages\n");
printf(" >ED# Jeturn to BC,\n");

get)command( $uffer )
char 8$uffer;
{
printf("\n,hellU ");
gets( $uffer );
strupr( $uffer );

e9ecute)command( cmd)string )
char 8cmd)string;
{
int i3 ';
for( i - /; i < dim( cmds); i00 )
{
' - strcmp( cmdsWiX.cmd)name3 cmd)string );
if( ' -- / )
{
(8cmdsWiX.cmd)ptr) ();
return 1;


return /;

main()
{
char input)$ufferW61X;
&hile( 1 )
{
get)command( input)$uffer );
if( e9ecute)command( input)$uffer ) -- / )
help();

1=B
.ORMATTERS .OR STR#NGS*C2ARACTERS
Consider the following program.
#include <stdio.h>
main() 78 ICJZ!#,.C 87
{
char c - ?#?;
static char sWX - "helloand&elcometoclanguage";
printf("CharactersU\n");
printf("2c\n"3 c);
printf("25c25c\n"3 c3 c);
printf("2L5c2L5c\n"3 c3 c);
printf(",tringsU\n");
printf("2s\n"3 s);
printf("2..s\n"3 s);
printf("25/s\n"3 s);
printf("24/..s\n"3 s);
printf("2L4/..s\n"3 s);

#he output of the above program will be,


CharactersD
.
. .
. .
(tringsD
helloandwelcometoclanguage
hello
helloandwelcometoclanguage
hello
hello
#he statement printf%1:.Bs9n1,s& means print the first five characters of the array s. #he statement
printf%1:=Cs9n1, s& means that the array s is printed right Rustified, with leading spaces, to a field width
of thirty characters.
#he statement printf%1:3C.Bs9n1, s& means that the first five characters are printed in a field siMe of
twenty which is right Rustified and filled with leading spaces.
#he final printf statement uses a left Rustified field of twenty characters, trailing spaces, and the .B
indicating to print the first five characters of the array s.
1=F
S3STEM CA&&S
Calls may be made to the "perating 2ystem to e)ecute standard "Psys calls, eg,
#include <process.h>
main() 78 ,Y,.C 87
{
char 8command - "dir";
system( "cls" );
system( command );

Io not use this method to invoke other programs. Functions like e)ec%& and spawn%& are used for this.
Suggeste- Mo-el Ans;ers
Exercise C1 The program output is,
Prog1
Programming in C is easy.
!nd so is Pascal.
Prog4
#he $lac% dog &as $ig. #he co& 'umped o(er the moon.
Prog5
*ello...
..oh my
...&hen do i stop+
Exercise C2 Typical program output is,
#he sum of 5. and 16 is .5
Exercise C3 Invalid variable names,
(alue=sum L must $e an underscore3 = sign is illegal
e9it flag L no spaces allo&ed
5lotsofmoney L must start &ith aL[ or an underscore
char L reser(ed %ey&ord
Qhen 2E\n is used3 the he9 digits a to f $ecome ! to I
1=G
Exercise C Constants
#define small(alue /.514
#define letter ?Q?
#define smallint 5;
Exercise C!
#he 2 of ./ $y 1/ is /.//
Exercise C"
#include <stdio.h>
main ()
{
int n - 13 t)num$er - /;
for ( ; n <- 4//; n00 )
t)num$er - t)num$er 0 n;
printf("#he 4//th triangular num$er is 2d\n"3 t)num$er);

Exercise C#
a -- 4 this is an eVuality test
a - 4 this is an assignment
78 program &hich illustrates relational assignments 87
#include <stdio.h>
main()
{
int (al1 - ./3 (al4 - 4/3 sum - /;
printf("./ 0 4/ is 2d\n"3 (al1 0 (al4 );
printf("./ L 4/ is 2d\n"3 (al1 L (al4 );
printf("./ 8 4/ is 2d\n"3 (al1 8 (al4 );
printf("./ 7 4/ is 2d\n"3 (al1 7 (al4 );

Exercise C$
Prints result &ith t&o leading places
Exercise C%
main()
{
int n - 13 t)num$er - /3 input;
1=K
printf(">nter a num$er\n");
scanf("2d"3 Minput);
for( ; n <- input; n00 )
t)num$er - t)num$er 0 n;
printf("#he triangular)num$er of 2d is 2d\n"3 input3 t)num$er);

Exercise C1&
#include <stdio.h>
main()
{
int grade; 78 to hold the entered grade 87
float a(erage; 78 the a(erage mar% 87
int loop; 78 loop count 87
int sum; 78 running total of all entered grades 87
int (alid)entry; 78 for (alidation of entered grade 87
int failures; 78 num$er of people &ith less than @. 87
sum - /; 78 initialise running total to / 87
failures - /;
for( loop - /; loop < .; loop - loop 0 1 )
{
(alid)entry - /;
&hile( (alid)entry -- / )
{
printf(">nter mar% (1L1//)U");
scanf(" 2d"3 Mgrade );
if ((grade > 1 ) MM (grade < 1// ))
{
(alid)entry - 1;


if( grade < @. )
failures00;
sum - sum 0 grade;

a(erage - (float) sum 7 loop;
printf("#he a(erage mar% &as 2.4f\n"3 a(erage );
printf("#he num$er less than @. &as 2d\n"3 failures );

Exercise C11
#include <stdio.h>
main ()
{
int in(alid)operator - /;
1=H
char operator;
float num$er13 num$er43 result;
printf(">nter t&o num$ers and an operator in the format\n");
printf(" num$er1 operator num$er4\n");
scanf( "2f 2c 2f"3 Mnum$er13 Moperator3 Mnum$er4);
s&itch( operator )
{
case ?8? U result - num$er1 8 num$er4; $rea%;
case ?L? U result - num$er1 L num$er4; $rea%;
case ?7? U result - num$er1 7 num$er4; $rea%;
case ?0? U result - num$er1 0 num$er4; $rea%;
default U in(alid)operator - 1;

s&itch ( in(alid)operator )
{
case 1U printf("Dn(alid operator.\n"); $rea%;
defaultU printf("24.4f 2c 24.4f is 24.4f\n"3
num$er13operator3num$er43result); $rea%;

Exercise C12
ma9)(alue - .
Exercise C13
#include <stdio.h>
main()
{
static int mWXWX - { {1/3.3L53 {S3 /3 /3 {5434/313 {/3/36 ;
int ro&3 column3 sum;
sum - /;
for( ro& - /; ro& < F; ro&00 )
for( column - /; column < 5; column00 )
sum - sum 0 mWro&XWcolumnX;
printf("#he total is 2d\n"3 sum );

Exercise C1
\aria$les declared type static are initialised to [ero. #hey are created and
initialised only once3 in their o&n data segment. !s such3 they are permanent3
and still remain once the function terminates ($ut disappear &hen the program
terminates).
\aria$les &hich are not declared as type static are type automatic $y default.
C creates these on the stac%3 thus they can assume non [ero (alues &hen created3
and also disappear once the function that creates them terminates.
1?C
Exercise C1!
#include <stdio.h>
int calc)result( int3 int3 int );
int calc)result( int (ar13 int (ar43 int (ar5 )
{
int sum;
sum - (ar1 0 (ar4 0 (ar5;
return( sum ); 78 return( (ar1 0 (ar4 0 (ar5 ); 87

main()
{
int num$1 - 43 num$4 - 53 num$5-F3 ans&er-/;
ans&er - calc)result( num$13 num$43 num$5 );
printf("2d 0 2d 0 2d - 2d\n"3 num$13 num$43 num$53 ans&er);

Exercise C1"
#include <stdio.h>
int add4darray( int WXW.X3 int ); 78 function prototype 87
int add4darray( int arrayWXW.X3 int ro&s )
{
int total - /3 columns3 ro&;
for( ro& - /; ro& < ro&s; ro&00 )
for( columns - /; columns < .; columns00 )
total - total 0 arrayWro&XWcolumnsX;
return total;

main()
{
int num$ersWXWX - { {13 43 5.3 ;3 1/3 {@3 ;3 F3 13 / ;
int sum;
sum - add4darray( num$ers3 4 );
printf("the sum of num$ers is 2d\n"3 sum );

Exercise C1#
time - time L .;
a - a 8 ($ 0 c);
1?1
Exercise C1$
#include <stdio.h>
(oid sort)array( int WX3 int );
(oid sort)array( (alues3 num$er)of)elements )
int (aluesWX3 num$er)of)elements;
{
int inde9)pointer3 $ase)pointer - /3 temp;
&hile ( $ase)pointer < (num$er)of)elements L 1) )
{
inde9)pointer - $ase)pointer 0 1;
&hile ( inde9)pointer < num$er)of)elements )
{
if( (aluesW$ase)pointerX > (aluesWinde9)pointerX )
{
temp - (aluesW$ase)pointerX;
(aluesW$ase)pointerX - (aluesWinde9)pointerX;
(aluesWinde9)pointerX - temp;

00inde9)pointer;

00$ase)pointer;

main ()
{
static int arrayWX - { F3 /3 63 53 43 S3 @3 13 ;3 . ;
int num$er)of)elements - 1/3 loop)count - /;
printf("Gefore the sort3 the contents are\n");
for ( ; loop)count < num$er)of)elements; 00loop)count )
printf("!rrayW2dX is 2d\n"3 loop)count3arrayWloop)countX);
sort)array( array3 num$er)of)elements );
printf("!fter the sort3 the contents are\n");
loop)count - /;
for( ; loop)count < num$er)of)elements; 00loop)count )
printf("!rrayW2dX is 2d\n"3 loop)count3arrayWloop)countX);

Exercise C1%
#include <stdio.h>
long int triang)rec( long int );
long int triang)rec( long int num$er )
{
long int result;
if( num$er -- /l )
result - /l;
1?3
else
result - num$er 0 triang)rec( num$er L 1 );
return( result );

main ()
{
int reVuest;
long int triang)rec()3 ans&er;
printf(">nter num$er to $e calculated.\n");
scanf( "2d"3 MreVuest);
ans&er - triang)rec( (long int) reVuest );
printf("#he triangular ans&er is 2l\n"3 ans&er);

<ote this (ersion of function triang)rec


#include <stdio.h>
long int triang)rec( long int );
long int triang)rec( long int num$er )
{
return((num$er -- /l) + /l U num$er8triang)rec( num$erL1));

Exercise C2&
$
Exercise C21
#include <stdio.h>
struct date {
int day3 month3 year;
;
int daysWX - { 513 463 513 5/3 513 5/3 513 513 5/3 513 5/3 51 ;
struct date today3 tommorro&;
(oid gettodaysdate( (oid );
(oid gettodaysdate( (oid )
{
int (alid - /;
&hile( (alid -- / ) {
printf(">nter in the current year (1SS/L1SSS)LL>");
scanf("Md"3 Mtoday.year);
if( (today.year < 1SS/) NN (today.year > 1SSS) )
printf("\//;Dn(alid year\n");
1?=
else
(alid - 1;

(alid - /;
&hile( (alid -- / ) {
printf(">nter in the current month (1L14)LL>");
scanf("Md"3 Mtoday.month);
if( (today.month < 1) NN (today.month > 14) )
printf("\//;Dn(alid month\n");
else
(alid - 1;

(alid - /;
&hile( (alid -- / ) {
printf(">nter in the current day (1L2d)LL>"3
daysWtoday.monthL1X);
scanf("Md"3 Mtoday.day);
if( (today.day < 1) NN (today.day > daysWtoday.monthL1X) )
printf("\//;Dn(alid day\n");
else
(alid - 1;

main()
{
gettodaysdate();
tommorro& - today;
tommorro&.day00;
if( tommorro&.day > daysWtommorro&.monthL1X ) {
tommorro&.day - 1;
tommorro&.month00;
if( tommorro&.month > 14 )
tommorro&.year00;

printf("#ommorro&s date is 2/4dU2/4dU2/4d\n"3 \


tommorro&.day3 tommorro&.month3 tommorro&.year );

Exercise C22
#include <stdio.h>
struct date { 78 Rlo$al definition of date 87
int day3 month3 year;
;
main()
{
struct date datesW.X;
int i;
for( i - /; i < .; 00i ) {
printf("Please enter the date (ddUmmUyy)" );
scanf("2dU2dU2d"3 MdatesWiX.day3 MdatesWiX.month3
MdatesWiX.year );
1??

Exercise C23
count - 1/3 9 - 1/;
O O
7 7
( (
Exercise C2
i1 - .3 i4 - 143 8p1 - .; 8p4 - .
Exercise C2!
<ame - Ga%ed Geans
DB - 514
Price - 4.;.
Exercise C2"
<ame - !pple Pie
DB - 145
Price - 1.@.
<ame - Rreggs Coffee
DB - ;;5
Price - 5.4/
Exercise C2#
#include <stdio.h>
main( int argc3 char 8arg(WX)
{
IDA> 8in)file3 8out)file3 8fopen();
int c;
if( argc P- 5 )
{
printf("Dncorrect3 format is ICCPY source dest\n");
e9it(4);

in)file - fopen( arg(W1X3 "r");
if( in)file -- <KAA ) printf("Cannot open 2s for reading\n"3 arg(W1X);
else
{
out)file - fopen( arg(W4X3 "&");
1?B
if ( out)file -- <KAA ) printf("Cannot open 2s for &riting\n"3
arg(W4X);
else
{
printf("Iile copy program3 copying 2s to 2s\n"3 arg(W1X3 arg(W4X);
&hile ( (c-getc( in)file) ) P- >CI ) putc( c3 out)file );
putc( c3 out)file); 78 copy >CI 87
printf("Iile has $een copied.\n");
fclose( out)file);

fclose( in)file);

Practise Exercise 1' (ns)ers


1. int sum;
4. char letter;
5. #define #JK> 1
F. float money;
.. dou$le arctan;
@. int total - /;
;. int loop;
6. #define R,# /.14.
Practise Exercise 2' (ns)ers
1. total - num$er1;
4. sum - loop)count 0 petrol)cost;
5. discount - total 7 1/;
F. letter - ?Q?;
.. costing - (float) sum 7 /.4.;
Practise Exercise 3' (ns)ers
1. printf("2d"3 sum );
4. printf("Qelcome\n");
5. printf("2c"3 letter );
F. printf("2f"3 discount );
1?F
.. printf("2.4f"3 dump );
@. scanf("2d"3 Msum );
;. scanf("2f"3 Mdiscount)rate );
6. scanf(" 2c"3 Moperator );
Practise Exercise ' (ns)ers
1. for( loop - 1; loop <- 1/; loop00 )
printf("2d\n"3 loop );
4. for( loop - 1; loop <- .; loop00 ) {
for( count - 1; count <- loop; count00 )
printf("2d"3 loop );
printf("\n");

5. total - /;
for( loop - 1/; loop <- 1//; loop00 )
total - total 0 loop;
or
for( loop - 1/3 total - /; loop <- 1//; loop00 )
total - total 0 loop;
.. for( loop - ?!?; loop <- ?H?; loop00 )
printf("2c"3 loop );
Practise Exercise !' (ns)ers
1. loop - 1;
&hile( loop <- 1/ ) {
printf("2d"3 loop );
loop00;

4. loop - 1;
&hile ( loop <- . ) {
count - 1;
&hile( count <- loop )
printf("2d"3 loop);
printf("\n");

5. if( sum < @. )


printf(",orry. #ry again");
F. if( total -- good)guess )
printf("2d"3 total );
else
printf("2d"3 good)guess );
1?G
Practise Exercise "' (ns)ers
1. if( (sum -- 1/) MM (total < 4/) )
printf("incorrect.");
4. if( (flag -- 1) NN (letter P- ?E?) )
e9it)flag - /;
else
e9it)flag - 1;
5. s&itch( letter ) {
case ?E? U sum - /; $rea%;
case ?H? U (alid)flag - 1; $rea%;
case ?!? U sum - 1; $rea%;
defaultU printf("Kn%no&n letter LL>2c\n"3 letter ); $rea%;

Practise Exercise #' (ns)ers


1. char lettersW1/X;
4. lettersW5X - ?H?;
5. total - /;
for( loop - /; loop < .; loop00 )
total - total 0 num$ersWloopX;
F. float $alancesW5XW.X;
.. total - /./;
for( ro& - /; ro& < 5; ro&00 )
for( column - /; column < .; column00 )
total - total 0 $alancesWro&XWcolumnX;
@. char &ordsWX - "*ello";
;. strcpy( stuff3 "Qelcome" );
6. printf("2d"3 totalsW4X );
S. printf("2s"3 &ords );
1/. scanf(" 2s"3 M&ordsW/X );
or
scanf(" 2s"3 &ords );
11. for( loop - /; loop < .; loop00 )
scanf(" 2c"3 M&ordsWloopX );
1?K
Practise Exercise $' (ns)ers
1. (oid menu( (oid )
{
printf("Zenu choices");

4. (oid menu( (oid );


5. (oid print( char messageWX )
{
printf("2s"3 message );

F. (oid print( char WX );


.. int total( int arrayWX3 int elements )
{
int count3 total - /;
for( count - /; count < elements; count00 )
total - total 0 arrayWcountX;
return total;

@. int total( int WX3 int );


Practise Exercise %' (ns)ers
1. struct client {
int count;
char te9tW1/X;
float $alance;
;
4. struct date today;
5. struct client clientsW1/X;
F. clientsW4X.count - 1/;
.. printf("2s"3 clientsW/X.te9t );
@. struct $irthdays
{
struct time $time;
struct date $date;
;
Practise Exercise %(' (ns)ers
1. IDA> 8input)file;
4. input)file - fopen( "results.dat"3 "rt" );
1?H
5. if( input)file -- <KAA ) {
printf("Kna$le to open file.\n");\
e9it(1);

F. int ch3 loop - /;


ch - fgetc( input)file );
&hile( ch P- ?\n? ) {
$ufferWloopX - ch;
loop00;
ch - fgetc( input)file );

$ufferWloopX - <KAA;
.. fclose( input)file );
Practise Exercise 1&' (ns)ers
1. int 8address;
4. temp - M$alance;
5. 8letter - ?Q?;
F. count - 4/3 8temp - 4/3 sum - 4/
.. char 8message - "*ello";
@. array - (char 8) getmem( 4// );
Practise Exercise 11' (ns)ers
1. struct date 8dates;
4. (8dates).day - 1/;
or
datesL>day - 1/;
5. struct machine {
int name;
char 8memory;
;
F. mpu@F1L>memory - (char 8) <KAA;
.. mpu@F1L>memory - CPKtype;
W L> means mpu@F1 is a pointer to a structure X
W memory is a pointer3 so is assigned an address (note M)
X
W the name of an array is eVui(alent to address of first element
X
@. mpu@F1L>name - 1/;
1BC
W L> means mpu@F1 is a pointer to a structure X
W name is a (aria$le3 so normal assignment is possi$le X
;. 8(timesL>day) - 1/;
W L> means times is a pointer to a structure X
W day is a pointer3 so to assign a (alue reVuires 8 operator X
W 8timesL>day is not Vuite correct X
W using the pointer times3 goto the day field X timesL
>day
W this is an address X 9
W let the contents of this address $e eVual to 1/ X
8(9) - 1/
6. 8(timesW4XL>month) - 14;
Practise Exercise 11a' (ns)ers
1. Gefore call to editrecord()
item.name - "Jed Plum :am"
item.id - /
item.price - /./
4. !fter return from editrecord()
item.name - "Ga%ed Geans"
item.id - 44/
item.price - 4.4/
5. #he final (alues of (alues3 item.name3 item.id3 item.price
item.name - "Ga%ed Geans"
item.id - 44/
item.price - 4.;.
Practise Exercise 12' (ns)ers
1. struct node {
int data;
struct node 8ne9t)node;
;
4. struct node node13 node43 node5;
5. node1.ne9t - Mnode4;
node4.ne9t - Mnode5;
node5.ne9t - (struct node 8) <KAA;
F. &hile( list P- (struct node 8) <KAA ) {
printf("data - 2d\n"3 listL>data );
list - listL>ne9t)node;

1B1
.. terminates the list at node43 effecti(ely deleting node5 from the list.
@. ne&)nodeL>ne9t - listL>ne9t;
listL>ne9t - ne&)node;
;. (oid delete)node( struct node 8head3 struct node 8delnode )
{
struct node 8list;
list - head;
&hile( listL>ne9t P- delnode ) {
list - listL>node;
listL>ne9t - delnodeL>ne9t;

6. (oid insert)node( struct node 8head3 struct node 8ne&node3 struct node
8pre(node )
{
struct node 8list;
list - head;
&hile( list P- pre(node )
list - listL>ne9t;
ne&nodeL>ne9t - listL>ne9t;
listL>ne9t - ne&node;

Practise Exercise 13' (ns)ers


1. IDA> 8input)file;
4. input)file - fopen( "results.dat"3 "rt" );
5. if( input)file -- <KAA ) {
printf("Kna$le to open file\n");
e9it( 1 );

F. loop - /;
ch - fgetc( input)file );
&hile( (ch P- ?\n?) MM (ch P- >CI) ) {
$ufferWloopX - ch;
loop00;
ch - fgetc( input)file );

$ufferWloopX - /;
.. fclose( input)file );
1B3

You might also like