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