You are on page 1of 192

FUNCTIONS

INTRODUCTION
We have mentioned earlier that one of the
strengths of C language is that C function are easy to
define and use. We have used functions in every
rogram that !e have discussed so far. "o!ever# they
have $een rimarily limited to the three functions#
namely# main# rintf# and scanf. In this chater# !e
shall consider in detail ho! a function is designed#
ho! t!o or more functions are ut together and ho!
they communicate !ith one another.
C functions can $e classified into t!o
categories# namely# li$rary functions and user %
defined functions. &ain is an e'amle of user(defined
functions. )rintf and scanf $elong to the category of
li$rary functions. We have also used other li$rary
functions such as s*rt# cos# strcat# etc. The main
distinction $et!een these t!o categories is that li$rary
functions are not re*uired to $e !ritten $y us !hereas
a user %defined function has to $e develoed $y the
user at the time of !riting a rogram. "o!ever# a
user(defined function can alter $ecome a art of the C
rogram li$rary. In fact# this is one of the strengths of
C language.
N++D FOR US+R D+FIN+D FUCNTIONS
,s ointed out earlier# main is a secially
recogni-ed function in C. +very rogram must have a
main function to indicate !here the rogram has to
$egin its e'ecution. While it is ossi$le to code any
rogram utili-ing only main function# it leads to a
num$er of ro$lems. The rogram may $ecome
difficult. If a rogram is divided into functional arts#
then each art may $e indeendently coded and later
com$ined into a single unit. These su$rogram called
.functions/ are much easier to understand# de$ug# and
test.
There are times !hen certain tye of
oerations or calculations is reeated at many oints
through out a rogram. For instance# !e might use the
factorial of a num$er at several oints in the rogram.
In such situations# !e may reeat the rogram
statements !herever they are needed. ,nother
aroach is to design a function that can $e called and
used !henever re*uired. This saves $oth time and
sace.
This 0division1 aroach clearly results in a
num$er of advantages.
2. It facilitates to(do!n modular
rogramming as sho!n in Fig.3.2. In
this rogramming style# the high level
logic of the overall ro$lem is solved
first !hile the details of each lo!er(
level function are addressed later.
4. The length of a source rogram can $e
reduced $y using functions at
aroriate laces. This factor is
articularly critical !ith
microcomuters !here memory sace
is limited.
5. It is easy to locate and isolate a faulty
function for further investigations.
6. , function may $e used $y many other
rograms. This means that a C
rogrammer can $uild on !hat others
have already done# instead of starting
all over again from scratch.
&ain )rogram
Function Function Function
, 7 C
72 74
To(do!n modular rogramming using
functions
, &U8TI FUNCTION )RO9R,&
, function is a self %contained $loc: of
code that erforms a articular tas:. Once a function
has $een designed and ac:ed# it can treated as a
.$loc: $o'/ that ta:es some data from main rogram
and returns a value. The inner details of oeration are
invisi$le to the rest of the rogram. ,ll that the
rogram :no!n a$out a function is; What goes in and
!hat comes out. +very C r<ogram can $e designed
using a collection of these $loc: $o'es :no!n as
functions

Consider a set of statements as sho!n
$elo!;
void rint line =void>
?
int i@
for =i(2@ iA6B@ iCC>
rintf =0 % 0>@
rintf = 0Dn1>@
E
The a$ove set of statements defines a
function called rintline# !hich could rint a line of
53(char(acter length. This function can $e used in a
rogram as follo!s;
void rintline =void>@ FG declaration GF
main= >
?
rintline= >@
rintf = 0This illustrates the use of
C functions Dn1>@
E
void rintline =void>
?
int i@
for =iH2@ iA6B@ iCC>
rintf =0 % 0>@
rintf = 0Dn1>@
E
This rogram !ill rint the follo!ing outut;
This illustrates the use of C functions
The a$ove rogram contains t!o(user defined
functions;
&ain = > function
)rintline = > function
,s !e :no!# the rogram e'ecution rintline is
to $e e'ecuted. ,t this oint# the rogram control is
transferred to the function rintline. ,fter e'ecuting
the rintline function# !hich oututs a line of 53
character length# the control is transferred $ac: to the
main. No!# the e'ecution continues at the oint
!here the function call !as e'ecuted. ,fter e'ecuting
the rint statement# the control is again transferred to
the rintline function for rinting the line once more.
The main function call the user(defined
rintline function t!o times and the li$rary function
rintf once. We may notice that the rintline function
itself calls the li$rary function rintf53 times
reeatedly.
,ny function can call any other function. In
fact# it can call itself. , .called function/ can also call
another function. , function can $e called more than
once. In fact# this is one of the main features of using
functions. Figure 3.4 illustrates the flo! of control in
a multi(function rogram.
+'cet the starting oint# there are no other
redetermined relationshis# rules of recedence# or
hierarchies among the functions that ma:e u a
comlete rogram. The functions can $e laced in any
order. , called function can $e laced either $efore or
after the calling function. "o!ever# it is the usual
ractice to ut all the called functions at the end. See
the $o' 0&odular )rogramming1
&ain = >
?
IIIIIIII
IIIIIIII
IIIIIIII
function 2 = >@
IIIIIIIII
IIIIIIIII
IIIIIIIII
function4= >@
IIIIIIIII
IIIIIIIII
function2= >@
IIIIIIIII
E
function2= >@
?
IIIIIIIII
IIIIIIIII
IIIIIIIII
E
function4= >@
?
IIIIIIIII
function5= >@
IIIIIIIII
E
function5= >@
?
IIIIIIII
IIIIIIII
E
Flo! of control in a multi(function
rogram
&odular rogramming
&odular rogramming is a strategy alied to
the design and develoment of soft!are system. It is
defined as organi-ing a large rogram into small#
indeendent rogram segments called modules that
are searately named and individually calla$le
rogram units. These modules are carefully integrated
to $ecome a soft!are system that satisfies the system
re*uirements. It is $asically a 0divide % and %con*uer1
aroach to ro$lem solving.
&odules are identified and designed such that
they can $e organi-ed into a to(do!n hierarchical
structure =similar to an organi-ation chart>. In C# each
module refers to a function that is resonsi$le for a
single tas:.
Some characteristics of modular rogramming
are;
2. +ach module should do only one thing.
4. Communication $et!een modules is allo!ed
only $y a calling module.
5. , module can $e called $y one and only one
higher module.
6. No communication can ta:e lace directly
$et!een modules that do not have calling
called relationshi.
J. ,ll modules are designed as single entry#
single e'it systems using control structures.
+8+&+NTS OF US+R D+FIN+D FUCNTIONS
We have discussed and used a variety of data
tyes and varia$les in our rograms so far. "o!ever#
declaration and use of these varia$les !ere rimarily
done inside the main function. ,s !e mentioned in
Chater 6# functions are classified as one of the
derived data tyes in C. We can therefore define
functions and use them li:e any other varia$les in C
rograms. It is therefore not a surrise to note that
there e'ist some similarities $et!een functions and
varia$le in C.
7oth function names and varia$le
names are considered identifiers and
there they must adhere to the rules for
identifiers.
8i:e varia$les# functions have tyes
=such as int> associated !ith them.
8i:e varia$les# functions names and
their tyes must $e declared and
defined $efore they are used in a
rogram.
In order to ma:e use of a user(defined function#
!e need to esta$lish three elements that are related to
functions.
2. Function definition
4. Function call
5. Function declaration
The function definition is an indeendent
rogram module that is secially !ritten to imlement
the re*uirements of the function. In order to use this
function !e need to invo:e it at a re*uired lace in the
rogram. This is :no!n as the function call. The
rogram =or a function> that calls the function is
referred to as the calling rogram or calling function.
The calling rogram should declare any function =li:e
declaration of a varia$le> that is to $e used later in the
rogram. This is :no!n as the function declaration or
function rototye.
D+FINITION OF FUCNTIONS
, function definition# also :no!n as
function imlementation shall include the follo!ing
elements
2. Function name
4. Function tye
5. 8ist of arameters
6. 8ocal varia$les declarations
J. Function statements
K. , return statement
,ll the si' elements are groued into t!o
arts# namely.
Function header =First three elements>
Function $ody =Second three elements>
, general formal of a function definition to
imlement these t!o arts is given $elo!;
functionItye functionIname =arameter
list>
?
local varia$le declaration@
e'ecuta$le statement2@
e'ecuta$le statement4@
. . . . . .
. . .. . .
return statement@
E
The first line
FunctionItye function(name=arameter
list>
Is :no!n as the function header and the
statements !ithin the oening and closing $races
constitute the function $ody# !hich is a comound
statement.
FUNCTION "+,D+R
The function header consists of three
arts; The function tye =also :no!n as return tye#
the function name and the formal arameter list. Note
that a semicolon is not used at the end of the function
header.
N,&+ ,ND TL)+
The function tye secifies the tye of
value =li:e float or dou$le> that the function is
e'ected to return to the rogram calling the function.
If the return tye is not e'licitly secified# C !ill
assume that it is an integer tye. If the function is not
returning anything# then !e need to secify the return
tye as void. Remem$er# void is one of the
fundamental data tyes in C. It is a good rogramming
ractice to code e'licitly the return tye# even !hen
it is an integer. = The value returned is the outut
roduced $y the function>.
The function name is any valid C
identifier and therefore must follo! the same rules of
formation as other varia$le names in C. The name
should $e aroriate to the tas: erformed $y the
function. "o!ever# care must $e e'ercised to avoid
dulicating li$rary routine names or oerating system
commends.
FOR&,8 ),R,&+T+R 8IST
The arameter list declares the varia$les
that !ill receive the data sent $y the calling rogram.
They serve as inut data to the function to carry out
the secified tas:. Since they reresent actual inut
values# they are often referred to as formal arameters.
These arameters can also $e used to send values to
the calling rograms. This asect !ill $e covered later
!hen !e discuss more a$out functions. The
arameters are also :no!n as arguments.
The arameter list contains declaration of
varia$les searated $y commas and surrounded $y
arentheses. +'amles@
float *uadratic =int # int $# int c> ?. . . .E
dou$le o!er =dou$le '# int n> ?. . .. E
float mul =float '# float y> ? . . ..E
int sum =int a# int $> ?. . . .E
Remem$er# there is no semicolon after the
closing arenthesis. Note that the declaration of
arameter varia$les cannot $e com$ined. That is#
Int sum =int a# $>
Is illegal
, function need not al!ays receive
values from the calling rogram. In such cases#
functions have no formal arameters. To indicate that
the arameter list is emty# !e use the :ey!ord void
$et!een the arentheses as in
void rintline = void>
?
. . . . .
E
This function neither receives any inut
values nor returns $ac: any value. &any comilers
accet an emty set of arentheses# !ithout secifying
anything as in
Moid rintline= >
7ut# it is a good rogramming style to
use void to indicate a nill arameter list.
FUNCTION 7ODL
The function $ody contains the
declarations and statements necessary for erforming
the re*uired tas:. The $ody enclosed in $races#
contains three arts# in the order given $elo!;
2. 8ocal declarations that secify the varia$les
needed $y the function.
4. Function statements that erform the tas: of
the function
5. , return statements that returns the value
evaluated $y the function.
If a function does not return any value =li:e the
rintline function># !e can omit the return statement.
"o!ever# note that its return tye should $e secified
as void. ,gain# it is nice to have a return statement
even for void functions.
Some e'amles of tyical function definitions
are@
=a> float mul =float '# float y>
?
float result @ FG local varia$le GF
result H ' G y@ FG comutes the
roduct GF
return =result>@ FG returns the result GF
E
=$> void sum =int a# int $>
?
rintf = 0sum H Ns1# a C $>@ FG no
local varia$les GF
return@ FG
otional GF
E
=c> void dislay =void>
? FG no local varia$les
GF
rintf = 0No tye# no arameters1>@
FG no return statement
GF
E
Note
2. When a function reaches its return
statement# the control is transferred
$ac: to the calling rogram. In the
a$sence of a return statement# the
closing $race acts as a void return.
4. , local varia$le is a varia$le that is
defined inside a function and used
!ithout having any role in the
communication $et!een functions.
R+TURNS M,8U+S ,ND T"+IR TL)+S
,s ointed out earlier# a function may or
may not send $ac: any value to the calling function. If
it does# it is done through the return statement. While
it is ossi$le to ass to the called function any num$er
of values# the called can ta:e one of the follo!ing
forms
return @
or
return =e'ression>@
The first the .lain/ return does not
return any value@ it acts much as the closing $race of
the function. When a return is encountered# the control
is immediately assed $ac: to the calling function. ,n
e'amle of the use of a simle return is as follo!s;
if =error>
return
The second forms of return !ith an e'ression
returns the value of the e'ression. For e'amle# the
function
int mul =int '# int y>
?
int @
H 'Gy@
return =>@
E
Returns the value of !hich is the roduct of
the values of ' and y. The last t!o statements can $e
com$ined into one statements as follo!s;
Return ='Gy>@
, function may have more than one return
statements. This situation arises !hen the value
returned is $ased on certain condition. For e'amle;
if = ' AH B >
return =B>@
else
return =2>@
What tye of data does a function returnO ,ll
functions $y default return int tye data. $ut !hat
haens if a function must return some other tyeO We
can force a function to return a articular tye of data
$y using a tye secifier in the function header as
discussed earlier.
When a value is returned# it is automatically
cast to the function/s tye. In function that do
comutations using dou$les# yet return ints# the
returned value !ill $e truncated to an integer. For
instance# the function
int roduct =void>
?
return =4.J G 5.B>@
E
Will return the value P# only the integer art of the
result
FUNCTION C,88S
, function can $e called $y simly using the
function name follo!ed $y a list of actual arameters
=or arguments># if any# enclosed in arentheses.
+'amle;
main = >
?
int y@
y H mul =2B# JB>@ FG
Function call GF
rint =0dDn1# y>@
E
When the comiler encounters a function call#
the control is transferred to the function mul= >. This
function is then e'ecuted line $y line as descri$ed and
a value is returned !hen a return statement is
encountered. This value is assigned to y. This is
illustrated $elo!;
main = >
?
int y@
y H mul =2B#J>@ FG call GF
. . ..
E
int mul =int '# int y>
?
int @ FG local
varia$le GF
H G y@ FG ' H 2B#
y H J GF
return =>@
E
The function call sends t!o integer values 2B
and J to the function.
Int mul =int '# int y>
Which are assigned to ' and y resectively. The
function comuters the roduct ' and y# assigns the
result to the local varia$le # and then returns the
value 4J to the main !here it is assigned to y again.
There are many different !ays to call a
function. 8isted $elo! are some of the !ays the
function mul can $e invo:ed.
mul =2B# J>
mul =m# J>
mul =2B# n>
mul =m# n>
mul =mCJ# 2B>
mul =2B# mul=m#n> >
mul =e'ression2# e'ression4>
Note that the si'th call uses its o!n call as its
one of the arameters. When !e use e'ressions# they
should $e evaluated to single values that can $e
assed as actual arameters.
, function !hich returns a value can $e used in
e'ressions li:e any other varia$le. +ach of the
follo!ing statements is valid;
rintf =0dDn1# mul =#*> >@
y H mul 3# *> F =C*>@
if =mul =m#n> Q total > rintf
=0large1>@
"o!ever# a function cannot $e used on the right
side of an assignment statement. For instance#
&ul =a# $> H 2J@
Is invalid
, function that does not return any value may
not $e used in e'ressions@ $ut can $e called in to
erform certain tas:s secified in the function. The
function rintline = > discussed in Section 3.5 $elongs
to this category. Such functions may $e called in $y
simly stating their names as indeendent statements.
+'amle
main = >
?
rintline= >@
E
Note the resence of a semicolon at the end.
Function Call
, function call is a ostfi' e'ression. The
oerator =. .> is at a very high level of recedence.
=See Ta$le 5.R> Therefore# !hen a function call is used
as a art of an e'ression# it !ill $e evaluated first#
unless arentheses are used to change the order of
recedence.
In a function call# the function name is the
oerand and the arentheses set =. .> !hich contains
the actual arameters is the oerator. The actual
arameters must match the function/s formal
arameters in tye# order and num$er. &ultile actual
arameters must $e searated $y commas.
Note;
2. If the actual arameters are more than
the formal arameters# the e'tra actual
arguments !ill $e discarded
4. On the other hand# if actuals are less
than the formals# the unmatched
formal arguments !ill $e initiali-ed to
some gar$age.
5. ,ny mismatch in data tyes may also
result in some gar$age values.

FUNCTION D+C8,R,TION
8i:e varia$les# all functions in a C
rogram must $e declared# $efore they are invo:ed. ,
function declaration =also :no!n as function
rototye> consist of four arts.
Function tye =return tye>
Function name
)arameter list
Terminating semicolon
They are coded in the follo!ing format;
Function(tye function(name
=arameter list>@
This is very similar to the function header line
e'cet the terminating semicolon. For e'amle#
mul function defined in the in the revious
section !ill $e declared as;
Int mul= int m# int n>@ FG Function
rototye GF
)oint to note;
2. The arameter list must $e searated $y
commas.
4. The arameter names do not need to $e the
same in the rototye declaration and the
fucniton definition.
5. The tye must match the tyes of arameters
in the function definition# in num$er and
order.
6. Use of arameter names in the declaration is
otional.
J. If the function has no formal arameters# the
list is !ritten as =void>.
K. The return tye is otional# !hen the
function returns int tye data.
P. The retye must $e void if no value is
returned.
R. When the declared tyes do not match !ith
the tyes in the function definition# comiler
!ill roduce an error.
+*ually acceta$le forms of declaration of mul
function are;
int mul =int# int>@
mul =int a# int $>@
mul =int# int>@
When a function does not ta:e any arameters
and does not return any value# its rototye is !ritten
as;
Moid dislay =void>@
, rototye declaration may $e laced in t!o
laces in a rogram.
2. ,$ove all the functions =including main>
4. Inside a function definition.
When !e lace the declaration a$ove all the
functions =int the glo$al declaration section># the
rototye is referred to as a glo$al rototye. Such
declarations are availa$le for all the functions in the
rogram.
When !e lace it in a function definition =in the
local declaration section># the rototye is called a
local rototye. Such declarations are rimarily used
$y the functions containing them.
The lace of declaration of a function defines a
region in a rogram in !hich the function may $e
used $y other functions. This region is :no!n as the
scoe of the function. =Scoe is discussed later in this
chater.> It is a good rogramming style to declare
rototye in the glo$al declaration section $efore
main. It adds fle'i$ility# rovides as e'cellent *uic:
reference to the functions used in the rogram# and
enhances documentation.
C,T+9ORL OF FUCNTIONS
, function# deending on !hether
arguments are resent or not and !hether a value is
returned or not# may $elong to one of the follo!ing
categories.
Category2; Function !ith no arguments and no
return values
Category4; Function !ith argument and no
return values.
Category5; Function !ith argument and one
return value.
Category6; Function !ith no arguments $ut
return a value.
CategoryJ; Function that return multile
values.
In the sections to follo!# !e shall discuss these
categories !ith e'amles. Note that# from no! on# !e
shall use the term arguments =rather than arameters>
more fre*uently.
NO ,R9U&+NTS ,ND NO R+TURN
M,8U+S
When a function has no arguments# it
does not receive any data from the calling function.
Similarly# !hen it does not return a value# the calling
function does not receive any data from the called
function. In effect# there is no data transfer $et!een
the calling function and the called function. This is
deicted in Fig. 3.5. The dotted lines indicate that
there is only a transfer of control $ut not data.
control
funciton2 = >
function4= >
? No inut ?
SSSS..
SSSS.
SSSS..
SSSS.
function4= >
SSSS.
SSSS.. No outut
SSSS.
SSSS.
SSSS.
E E
control
No data communication $et!een
functions
,s ointed out earlier# a function that
does not return any value cannot $e used in an
e'ression. It can only $e used as an indeendent
statement.
+'amle 3.2 Write a rogram !ith
multile function that do not communicate any data
$et!een them.
, rogram !ith three user(defined
functions is given in Fig.3.6 main is the calling
function that call rintline and value functions. Since
$oth the called functions contain no arguments# there
are no argument declarations. The rintline function#
!hen encountered# rints a line !ith a length of 5J
characters as rescri$ed in the function. The value
function calculates the value of rincial amount after
certain eriod of years and rint the results. The
follo!ing e*uation is evaluated reeatedly
value H rincial =2Cinterest % rate>
rogram
FG Function declaration GF
void rintline =void>@
void value =void>@
main = >
?
rintline= >@
value= >@
rintline= >@
E
FG Funciton2; rintline = >
GF
void rintline =void> FG contains no
arguments GF
?
int i@
for =iH2@ iAH5J@ iCC>
rintf =0Nc1# .(.>@
rintf =0Dn1>@
E
FG Fucntion4; value= > GF
void value =void> FG
contains no arguments GF
?
int year# eriod@
float intate# sum# rincial@
rintf =0)rincial amountO1>@
scanf = 0Nf1# T rincial >@
rintf = 0Interest rateO1>
scanf = 0Nf# Tinrate >@
rintf = 0)eriodO1>@
scanf = 0Nd1# Teriod>@
sum H rincial@
year H 2@
!hile =year AH eriod>
?
sum H sum
G=2Cinrate>@
year H year C2@
E
)rintf = 0nNR.4f NJ.4f NJd
N24.4fDn1# rincial# inrate# eriod# sum>@
E
Outut
((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((
)rincial amoutO JBBB
Interest rate O B.24
)erodO J
JBBB.BB B.24 J RR22.P2
((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((
It is imortant to note that the function
value receives its data directly from the terminal. The
inout data include rincial amount# interest rate and
the eriod for !hich the final value is to $e calculated.
The !hile loo calculates the final value and the
results are rinted $y the li$rary function rintf. When
the closing $race of value = > is reached# the control is
transferred $ac: to the calling function main. Since
everything is done $y the value itself there is in fact
nothing left to $e sent $ac: to the called function.
Return tyes of $oth rintline and value are declared
as void.
Note that no return statement is
emloyed. When there is nothing to $e returned# the
return statement is otional. The closing $race of the
function signals the end of e'cution of the function#
thus returning the control# $ac: to the calling fucniton.
,R9U&+NTS 7UT NO R+TURN M,8U+S
In Fig. 3.6 the main function has no
control over the !ay the functions receive inut data.
For e'amle# the fucniton rintline !ill rint the same
line each time it is called. Same is the case !ith the
function value. We could ma:e the calling function to
read data from the retminal and ass it on to the called
function. This aroach seems to $e !iser $ecause the
calling fucniton can chec: for tehvalidity of data# if
necessary# $efore it is handed over to the called
fucniton.
The nature of data communication
$et!een the calling fucniton and the called fucniton
!ith arguments $ut no return value is hso!n in Fig 3.J
function2= > Malues
function4= >
? of argument
SSSS..
SSSS.. ?
function4=a>
SSSS.
SSSS..
SSSS.
SSSS. No return value
SSSS..
E E
Fig 3.J One(!ay data
communication
We shall modify the definitions of $oth the
called functions to include arguments as follo!s;
void rintline =char ch>
void value =float # float r# int n>
The arguments ch# # r# and n are called the
formal arguments. The calling function can no! send
values to these arguments using function calls
containing aroriate arguments. For e'amle# the
function call
Malue =JBB.B.24#J>
Would send the values JBB#B.24 and J to the
function
Moid value =float # float r# in n>
,nd assign JBB to # B.24 to r and J to n. The
values JBB# B.24 and J are the actual arguments#
!hich $ecome the values of the formal arguments
inside the called fucniton.
The actual and formal arguments should match
in num$er# tye# and order. The values of actual
arguments are assigned to the formal arguments on a
one to one $asis# starting !ith the first arguments as
sho!n in Fig 3.K
&ain = >
?
actual arguments
Function ((((((((((
call funciton2
=a2# a4# a5#S#am>
(((((((((((
E
function2
=f2# f4# f5#S.#fn>
called
formal arguments
fucniton ?
((((((((((((
((((((((((((
E
,rguments matching
$et!een the function call the called fucniton
We should ensure that the fucniton call has
matching arguments. In case# the actual arguments are
more than the formal arguments =mQn># the e'tra
actual arguments are discarded. On the other hand# if
the actual arguments are less than the formal
arguments# the unmatched formal arguments are
initiali-ed to some gar$age values. ,ny mismatch in
data tye may also result in assing of gar$age values.
Remem$er# no error message !ill $e generated.
While the fomal arguments must $e valid
varia$le names# the actual arguments may actual
arguments is assed into the called fucniton. What
occurs inside the function !ill have no effect on the
varia$les used in the actual argument list.
+'amle 3.4
&odify the rogram of +camle
3.2 to include the arguments in the function calls.
The modified rogram !ith function arguments
is resented in Fig.3.P. &ost of the rogram is
identical to the rogram in Fig.3.6. The inut romt
and scanf assignment statement have $een moved
from value fucn iton to mian. The varia$les rincial#
inrate# and eriod are declared in main $ecause they
are used in main to receive data. The function call
Malue =rincial# inrate# eriod>@
)asses information it contains to the function
value.
The function header of value has three formal
arguments #r# and n !hich corresond to the actual
arguments in the fucniton call# namely# rincial#
inrate# and eriod. On e'ecution of the fucniton call#
the values of the actual arguments are accomlished
across the function $oundaries;
H rincial@
r H inrate@
n H eriod@
rogram
FG rototyes GF
void rintline =char c>@
void value =float# float# int>@
main= B
?
float rincial# inrate@
int eriod@
rintf = 0+nter rincial
amount# interest1>@
rintf = 0rate# and eriod
Dn1>@
scanf = 0Nf Nf Nd1#
Grincial# Tinrate# Geriod>@
rintline =.-/>@
value =rincial# inrate#
eriod>@
rintline =.C/>@
E
void rintline =char ch>
?
int i@
for =iH2@ iAHJ4@ iCC>
rintf = 0Nc1# ch>@
rintf = 0Dn1>@
E
void value =float # loat r# int n>
?
int year @
float sum@
sum H @
year H 2@
!hile =year AH n>
?
Sum H sum G =2Cr>@
Lear H year C2@
E
)rintf = 0NfDtNfDtNdDNfDnE#
# r# n# sum>@
E
Outut
+nter rincial amount# interest
rate# and eriod JBBB B.24 J
U-----------------------------------------------------
----
JBBB. BBBBBB B.24BBBB J
RR22.PBR3R6
Cccccccccccccccccccccccccccccccccccccccccccccccccccc
Fig.3.P. Funciton !ith arguments
$ut no return values
The varia$les declared inside a function are
:no!n as local varia$les and therefore their values are
local to the fucniton and cannot $e accessed $y any
other function. We shall discuss more a$out this later
in the chater.
The function value calculates the final amount
for a given eriod and rints the result as $efore.
Control is transferred any value.
The fucniton rintline is called t!ice. The frist
call asses the character .U/# !hile the second asses
the charater .C/ to the function. These are assigned to
the formal argument ch for rinting lines =see the
outut>.
,R9U&N+TS WIT" R+TURN M,8U+S
The function value in Fig.3.P. receives
data from the calling fucniton through arguments# $ut
does not send $ac: any value. Rather# it dislay the
results of calculations at the terminal. "o!ever# !e
may not al!ays !ish to have th result of a fucniton
dislayed. We may use it in the calling function for
further rocessing. &orever# to assure a high degree of
orta$ility $et!een rograms# a fucniton should
generally $e coded !ithout involving any IFO
oerations. For e'amle# different rograms may
re*uire different outut formats to its calling fucniton
!here the results. These shortcomings can $e
overcome $y handling over the result of a function to
its calling fucniton !here the returned value can $e
used as re*uired $y the rogram.
, self % contained and indeendent fucniton
should $ehave li:e a .$loc: $o'/ that receives a
redefined from of inut and oututs a desired value.
Such fucnitons !ill have t!o(!ay data
communication as sho!n in Fig3.R.
function2 = > values
fucntion4=f>
? of argument
?
SSSSS
SSSS..
function4=a>
SSSS..
SSSS. Function
result SSSS..
SSSS.
return=e>
E
E
Fig.3.R T!o(!ay data
communication $et!een fucntions
We shall modify the rogram in Fig.3.P to
illustrate the use of t!o(!ay data communication
$et!een the calling and the called fucnitons.
+'amle 3.5
In the rogram resented in Fig.3.P
modify the fucniton value# to return the final amount
calculated to the main# !hich !ill dislay the re*uired
outut at the terminal. ,lso e'tend the versatility of
the function rintline $y having it to ta:e the length of
the line as an argument.
The modified rogram !ith the roosed
changes is resented in Fig.3.3. One maVor change is
the movement of the rintf statement from value to
main.
)rogram
void rintline =char ch# int len>@
value =float# float# int>@
main = >
?
float rincial# inrate#
amount@
int eriod@
rintf =0+netr rincial
amount# interest1>@
rintf =0rate# and eriodDn1>@
scanf =Nf Nf Nd1#
Grincial# Trincial# Tinrate# Teriod>@
rintline = .G/# J4>@
amount H value =rincial#
inrate# eriod>@
rintf = 0DnNfDtNfDtNdD
NfDnDn1# rincial# inrate# eriod# amount>@
rintline =.H/# J4>@
E
void rinline =char ch# int len>
?
int i@
for =iH2@ iAlen@ iCC> rintf
= 0Nc1# ch>@
rintf = 0Dn1>@
E
value =float # loat r# int n> FG
default return tye GF
?
int year@
float sum@
sum H @ year H 2@
!hile =year AH n>
?
sum H sum G = lCr>@
year H year C2@
E
return =sum>@ FG returns
int art of sum GF
E
Outut
+nter rincial amount#
interest rate# and eriod
JBBB B.24 J
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
JBBB.BBBBBB
B.24BBBBB J RR22.BBBBBB
H H H H H H H H H H H H H H
H H H H H H HH H H
Fig.3.3 Funciton !ith arguments
and return values
The calculated value is assed on to main
through statement;
return=sum>@
Since# $y default# the return tye of value
fucniton is int# the .integer/ value of sum at this oint
is returned to main and assigned to the varia$le
amount $y the functional call.
amount H value =rincial# inrate#
eriod>@
The follo!ing events occur# in order# !hen the
a$ove fucniton call is e'ecuted;
2. The function call transfers the control
along !ith coies of the values of the
actual arguments to the fucniton value
!here the formal argument #r# and n
are assigned the actual values of
rincial# inrate and eriod
resectively.
4. The called fucniton value is e'ecuted
line $y line in a normal fashion until
the return =sum>@ statement is
encountered. ,t this oint# the integer
value of sum is assed $ac: to the
fucniton call in the main and the
follo!ing indirect assignment accurs;
Malue =rincial#
inrate# eriod> H sum@
5. The calling statement is e'ecuted
normally and the returned value is thud
assigned to amount# a float varia$le.
6. Since amount is a float varia$le# the
returned integer art of sum is
converted to floating oint value. See
the outut.
,nother imortant change is the inclusion of
second argument to rintline fucniton to receive the
value of length of the line from the calling fucniton.
This# the function call
)rintline =.G/# J4>@
Will transfer the control to the fuciton rintline
and assign the follo!ing values to the formal
arguemts ch# and len@
ch H .G/@
len H J4@
R+TURNIN9 F8O,T M,8U+S
We mentioned earlier that a C fucniton
retuns a value of the tye int as the defult case !hen
no other tye is secified e'licitly. For e'amle# the
fuciton value of +'amle 3.5 does all calculations
suign floats $ut the return statement
return =sum>@
returns only the integer art of sum. This due to
the a$sence of the tye(secifier in the fucniton
header. In this case# !e can accet the integer value of
sum $ecause the truncated decimal art is
insignificant comared to the integer art. "o!ever#
there !ill $e times !hen !e may find it necessary to
receive the float or dou$le tye of data. For e'amle#
a fucniton that calculates the mean or standard
deviation of a set of values should return the function
value in either float or dou$le.
In all such cases# !e must e'licitly secify the
return tye in $oth the fucniton definition and the
rototye declaration.
If !e have a mismatch $et!een the tye fo data
that the called fucniton returns and the tye of data
that the calling fucniton e'ects# !e !ill have
unredicata$le results. We must# therefore# $e $ery
careful to ma:e sure that $oth tyes are comati$le.
+'amle 3.6
Write a function o!er that
comutes ' raised to the o!er y for integers ' and y
and retunrs dou$le % tye value.
Fig.3.2B sho!s a o!er function that returns a
dou$le. The rototye declaration
Dou$le o!er =int# int>@
,ears in main# $efore o!er is called.
)rogram
main= >
?
int '#y@ FGinut data GF
dou$le o!er =int# int>@ FG
rototye declaration GF
rintf =0+netr '# y;1>@
scanf = 0Nd Nd1# T'# Ty>@
rintf = Nd to o!er Nd is
NfDn1# '#y# o!er ='#y> >@
E
dou$le o!er =int '# int y>
?
dou$le @
H 2. B@ FG ' to o!er
-ero GF
if =y QH B>
!hile =y( (> FG comutes
ositive o!er GF
GH '@
else
!hile =yCC> FG comutees
negative o!er GF
FH '@
return =>@ FG returns
dou$le tye GF
E
Outut
+nter '# y1 2K 4
2K to o!er 4 is 4JK.BBBBBB
+nter '# y; 2K % 4
2K to o!er (4 is B.BB53BK
Fig.3.2B )o!er fucnitons;
Illustration of return of float values
,nother !ay to guarantee that o!er/s tye is
declaraed $efore it is called in main is to define the
o!er fucniton $efore !e define main. )o!er/s tye
is then :no!n from its definition# so !e no longer
need its tye declaration in main.
NO ,R9U&+NTS 7UT R+TURNS , M,8U+
There could $e occasions !here !e may
need to design fucitons that may not ta:e any
arguments $ut returns a value to the calling function.
, tyical e'amle is the hetcher fucniton declared in
the header fileAstdio.hQ. We have used this integer
tye data that reresents a charater.
We can desing similar fucnitons and use in our
rograms. +'amle@
int getInum$er =void>@
main
?
int m H getInume$r= >@
rintf = 0Nd1# m>@
E
int getInum$er =void>
?
int num$er@
scanf = 0Nd1# Tnum$er>@
return =num$er>@
E
)OINT+R
Introduction
In rogramming !ith C# there are far too
many thing that can only $e done !ith ointers. In
many cases# C rogrammers use ointers $ecause they
ma:e the code more efficient. 7ut at times# ointers
seem to ma:e the code harder to understand.
"o!ever# !ith increased o!er# ointers $ring
increased resonsi$ility. )ointers allo!s ne! and ugly
tyes of $ugs# and ointer $ugs can crash in random
!ays# !hich ma:es them more difficult to de$ug.
Nonetheless# even !ith their ro$lems# ointers are a
o!erful rogramming construct. The only eculiarity
of C# comared to other languages is its heavy
reliance on ointers and the relatively ermissive vie!
of ho! they can $e used.
7efore going on to discuss the concet of
ointers# it is necessary to understand the use of
memory in a C rogram.
Understanding &emory ,ddresses
,ll comuters have rimary memory#
also :no!n as R,& or Random ,ccess &emory. For
e'amle# a comuter may have 2K# 54# K6# 24R# 4JK#
or J24 &7 of R,& installed. R,& holds the
rograms that the comuter is currently running along
!ith the data they are currently maniulating =their
varia$le and data structures>. ,ll the varia$les used in
a rogram =and indeed# the rogram itself> reside in
the memory !hen the rogram is e'ecuted. The
organi-ation of the memory is rather straightfor!ard.
It is a se*uence of a large num$er of memory
locations =cells> each of !hich has an address. +ach
memory location is caa$le of storing a small num$er
=B to 4JK># !hich is :no!n as a $yte. , char data is 2
$yte in si-e and hence needs one memory locations in
a 54($it machine. The si-e needed for a articular tye
varies !ith the latform in !hich the rogram is run.
+ven if an int F float num$er is small# it !ill still
occuy four locations. When a rogram in C is !ritten
and comiled# the comiler !ill allocate the memory
necessary to run the rogram. This is art f the
reason !hy declaring varia$les is so imortant. For
e'amle#
int '@
'H2BBB@
!ill first convey to the C comiler that ' is an integer
$efore assigning a value of 2BBB to it. The declaration
statements informs the comiler to allocate enough
memory to store an integer and assign an address to
that sace in memory. Since an integer re*uires t!o or
four $ytes of memory# the comiler searches for t!o
or four free $ytes and holds them until a value is
redefined as something else. The same goes for other
data tyes in C. Declaring varia$les first al!ays
allo!s the comiler to set aside a sace in memory
!hich can then $e filled u !ith useful num$ers.
Figure 25.2 reresents these facts.
Figure 25.2 defines the memory elements of
any rogram !ith a grahical reresentation. It
illustrates ho! the various entities of a C rogram are
stored !ithin the comuter memory.
The entire area of Fig. 25.4 including the area
to the right that loo:s li:e a ladder reresents the
memory in the comuter. ,ll e'ecuta$le codes and all
varia$les !ithin any given rogram are stored !ithin
the area illustrated $y the figure. The $ig *uestion is#
ho! are the various entities stored in this saceO
B
,ddr &em
2
B 4

2 5
char .a/ in memory
4 6
5 J
6 .
KJ
J One location .
. .
int num$er 2BBB in
. 4PJPK
. 4PJPP
float num$er
4PJPK 4PJPR

4PJPP
4PJPR
Fig 25.2 The
Comuter &emory
Stac:
Maria$le
main = > "ea

Fig 25.4 9rahical Reresentation of
&emory +lements of a C )rogram
There are three areas of memory that have secial
caa$ilities assigned $y comiler and lin:er.
Stac:
What loo:s li:e a ladder on the right of the
figure is the stac:. It is allocated $y the system to $e
of a fi'ed si-e and is filled as needed from the $ottom
to the to# one element at a time. +lements are
removed from the to to the $ottom# one element at a
time. Thus the last element added to the stac: is the
first element that is removed !hen no longer needed.
,ny element on the stac: is otentially availa$le for
reference or modification $y the e'ecuting code# $ut
elements are added and removed only from the to.
"o! is the stac: usedO
,s varia$le or ointers are needed $y the system#
they are assigned to the stac: se*uentially starting at
the $ottom# !ith each successive element $eing
stac:ed on to of the others# or assigned at the ne't
location to!ards the to of the figure. +ach $o' in the
icture of the stac: can store any one of the simle
varia$les indeendent of the si-e of the varia$le. =The
system :no!n ho! many $ytes it ta:es to store each
tye of varia$le and it !ill ta:e care of the various
si-es automatically.> Once a varia$le is stored on the
stac:# it can $e referred to $y the code that uts it on
the stac:# so that it is a varia$le availa$le for use in
much the same manner as glo$al varia$les are
availa$le. "o!ever# !hen the rogram has finished
using the data on the stac:# it can $e discarded to
allo!s the stac: to $e used for other data !hen
needed. This is ro$a$ly unclear at this oint# $ut it
!ill ma:e more sense !hen one gets to the accrual
usage.
Thin: of the stac: as gro!ing u!ards as
needed and shrin:ing do!n!ards !hen some of the
data is discarded $ecause it is no longer needed.
"ea
"ea is an area !ithin the $o'. This is allocated
$y the system to $e of a fi'ed si-e and is used $y the
system as needed in a random fashion. Random does
not mean that there is any disorder in the !ay this area
is used. It means the memory is not assigned in any
articular order. It can# in fact# $e assigned in $loc:s
as needed from any lace !ithin the hea. ,ny
memory !ithin the hea that is not currently allocated
for the rogram is stored in the free list# a list of
memory $loc: that can $e assigned to the rogram as
needed.
"o! is the hea usedO
The hea is a contiguous $loc: of memory that
is availa$le for use $y any art of the rogram
!henever it is needed and for as long as it is needed.
When the rogram re*uests a $loc: of data# the
dynamic allocation scheme carves out a $loc: from
the hea and assigns it to the user $y returning a
ointer to the $eginning of the $loc:. When the
system has finished using the $loc:# it returns the
$loc: to the hea !here it is returned to the ool of
availa$le memory called the free list. This is called
de(allocation.
9lo$al &emory
This is all of the memory on the machine
that is not assigned to the stac: or the hea.
"o! is glo$al memory assignedO
The $loc: of code that is the main= >
rogram is stored in glo$al memory as is every
function that is re*uired for the rogram to e'ecute.
+ven through the system !ill assign the various $loc:
of code in a very orderly manner# it must $e assumed
that they are actually assigned in on articular order.
In fact it should $e assumed that they are randomly
assigned all over the glo$al storage area that one
function is not contiguous to another function.
Some comilation F lin:ing systems
ermit locating of code and varia$les !here one !ants
them in memory# $ut that is $eyond the scoe of this
te't.
Figure 25.4 contains a $o' !ith the title main= >. This
$o' reresents the $loc: of code for the main= >
rogram. +ven through all the functions in any
rogram aear as code $loc:s !ithin the glo$al
memory# they !ill not $e included in any of the
remaining figures since they are inaroriate to this
discussion. It can# therefore# $e assumed that the code
is there# ready to $e e'ecuted# $ut since it !ill clutter
u the figure# it is not sho!n or discussed any further.
, glo$al varia$le The $o' la$eled .varia$le/ in
Fig.25.4 reresents glo$al varia$les that are stored in
glo$al memory. The system carves out enough
memory to store the varia$le in *uestion and assigns
that memory to the varia$le. The glo$al varia$le e'ists
for the entire time of rogram e'ecution.
Note that a char tye varia$le usually uses only
one $yte of storage# $ut a dou$le tye varia$le !ill
use a$out eight $ytes of storage. Therefore# the $o'
la$eled varia$le can store a char# an int# a dou$le# or
any other simle varia$le and the system !ill ensure
that there is enough room to store the entity that the
rogrammer has re*uested. +ven through the $o'es
are all the same si-e in this grahical reresentation#
they may $e referring to different amounts of hysical
memory.
There may $e several glo$al varia$les declared
in the rogram# $ut they !ill not $e stored
contiguously# since the comiler is not comelled to
store them in any order convenient to the rogrammer.
They are randomly stored throughout the availa$le
glo$al memory even through it is a fact that every C
comiler !ill ro$a$ly assign them in some
contiguous manner.
There is virtual memory# cache memory#
registers# and other :inds of memory that ma:e the
system run a little faster or aear to have more
memory. The $loc:s returned to the rogram from the
hea have additional house:eeing memory
associated !ith them and there are $yte alignment
considerations. For e'amle# the comiler may re*uire
that all float and dou$le tye varia$les start on an even
num$ered $yte $oundary# or on a $yte $oundary that is
modulo four. This may re*uire some $ytes added as
adding to get to the $oundary !hen one of these is
encountered. The comilerFlin:er !ill ta:e care of
these details.
Since !e are interested only in the logical
assignment of memory# !e can ignore all of these
e'tra considerations# and still !rite efficient# ro$ust
rograms. The comiler !rites have a $ig Vo$ to do
$ecause they must :ee trac: of all of these entities in
order o ma:e our Vo$ easier.
C uses ointers in three main !ays.
2. )ointers in C rovide an alternative means of
accessing information stored in arrays# !hich is
esecially valua$le !hen !or:ing !ith string.
There is an intimate lin: $et!een arrays and
ointers in C.
4. C uses ointers to handle varia$le arameters
assed to functions.
5. They are used to create dynamic data structures#
those that are $uilt u from $loc:s of memory
allocated from the hea at run(time. This is only
visi$le through the use of ointers.
Ta$le 25.2 descri$es the memory layout of the
memory elements of a C rogram.
Ta$le 25.2 &emory 8ayout Summary
&emory
Section
Name
Descrition
Te't =or the
code
segment>
Data
7SS
Stac:
"ea
Shared
li$raries
This is the area of
memory that contains
the machine
instructions
corresonding to the
comiled rogram.
This area is R+,D
ON8L and is shared $y
multile instances of a
running rogram.
This area in the
memory image of a
running rogram
contains storage for
initiali-ed glo$al
varia$les. This area is
searate for each
running instance of a
rogram.
This is the memory
area that contains
storage for
uninitiali-ed glo$al
varia$les. It is also
searate for each
running instance of a
rogram.
This region of the
memory image of a
running rogram
contains storage for the
automatic =local>
varia$les of the
rogram. It also stores
conte't(secific
information $efore a
function call# e.g.# the
value of the instruction
ointer =rogram
counter> register $efore
a function call is made.
On most architectures#
the stac: gro!s from
higher memory to
lo!er memory
addresses.
This memory region is
reserved for
dynamically allocating
memory for varia$les
at run(time. Dynamic
memory allocation is
done $y using the
malloc or calloc
functions.
This region contains
the e'ecuta$le image
of shared li$raries
$eing used $y the
rogram.

25.5 ,ddress Oerator=T>
Readers might have noticed that !hen !e
call certain functions in C the T sing is used. For
e'amle#
scanf =0Nd1# Tn>@
ta:es the inut from the terminal and
stores it in integer format in the varia$le named n. The
T sign indicates to the address in memory of the
integer n# !hich must $e reviously declared using
int n@
!here the function stores the inutted data. Wust
li:e a house address in a to!n# the memory address is
an integer secifying the location !here something
resides. scanf needs to :no! this in order to redirect
the data. If one forgets and tyes n instead# the scanf
function interrets the actual integer value of n as an
address and tries to send its outut there. This address
may not e'ist# it may $e used $y the oerating system
or other!ise $loc:ed# or it may $e imossi$le to find
again. It is li:ely to get a
segmentation fault
error !hen one comiles# and one !ill certainly
get nonsense values it the rogram runs. To reca# the
comiler thin:s n means the value of n =!hich !ill $e
Vun: if it has not $een assigned yet> and Tn means n/s
address. ,t the moment the varia$le is declared# it
must $e stored in a concrete location in the succession
of cells in the memory. The rograms do not decide
!here the varia$le is to $e laced. That is done
automatically $y the comiler and the oerating
system at run(time. 7ut once the oerating system has
assigned an address there may $e cases !here it may
$e of interest to :no! the location of the varia$le.
This means .address of/.
No! !e illustrate the a$ove ideas !ith some
more details. Consider the declaration#
int i H 5@
This declaration tells the C comiler to
reserve sace in memory to hold the integer value
associate the name i !ith this memory location
store the value 5 at this location
We may reresent i/s location in the memory !ith the
memory ma sho!n in Fig. 25.5
i
5
426P6PR4PK
Fig 25.5 &emory
&a
We see that the comuter has selected memory
location 426P6PR4PK as the lace to store the value 5.
This location num$er 426P6PR4PK is not a num$er to
$e relied uon $ecause at some other time the
comuter may choose a different location for storing
the value 5. We can rint this address through the
follo!ing statement;
rintf = 0Dn ,ddress of i H Tu1# Ti>@
The outut !ill $e ; 426P6 PR4PK. 8oo: at the rintf= >
statement carefully. The 0T1 used in this statement is
C/s address oerator. The e'ression Ti returns the
address of the varia$le i# !hich in this case haened
to $e 426P6PR4PK.
The address is rinted using Nu control string as it is
of tye unsigned int. N' can also $e used. ,ctually
N should $e used $ecause it rints the inut
argument as a memory address.
The follo!ing statement
rintf = 0Dn ,ddress of i H N'1# Ti >@
!ill rint FFDC in he'adecimal as the address
of varia$le .i/.
Why an unassigned ointer should not $e usedO
,ccording to a verse taught in elementary
school# 0I shot an arro! into the air# !here it lands# I
don/t care.1 It may ryyme# $ut its message is really
not aroriate for little ones.
"o!ever# !hen a ointer is declared and the
used !ithout first assigning it a value# it is doing the
rogramming e*uivalent of the verse.
The follo!ing rogram declares a ointer and
then attemts to outut its value !ithout first
assigning it a value.
Xinclude Astdio.hQ
main= >
?
int Gtr@
rintf = 0Dn The value of tr is Nu1# tr >@
E
The result# deending on the comiler and
oerating system# may $e a comiler error# a run(
time error# or a comuter that loc:s u. Regardless#
attemting to use a declared ointer !ithout first
assigning it a value is not a good idea.
It may $e recalled from revious chaters that
!hen a varia$le is declared and then an attemt is
made to outut its value !ithout first assigning it a
value# the result is a so(called gar$age value that
ma:es little sense. The reason for this result is that the
comuter attemts to interret !hatever value is left
over from revious rograms at the address of the
varia$le.
When the varia$le is a ointer# that leftover
value is interreted as another memory address# !hich
the ointer then tries to access !hen !e attemt to
use it. There are a num$er of memory address ranges
that are not ermitted to access rogrammatically#
such as those reserved for use $y the oerating
system. If the leftover value is interreted as one of
those rohi$ited addresses# the result is an error.
)OINT+R
, ointer rovides a !ay of accessing a
varia$le a varia$le !ithout referring to the varia$le
directly. The mechanism used for this is the address of
the varia$le. , rogram statement can refer to a
varia$le indirectly using the address of the varia$le as
a sort of ost $o'.
, ointer varia$le is a varia$le that holds
the memory address of another varia$le. )ut another
!ay# the ointer does not hold a value in the
traditional sense@ instead# it holds the address of
another varia$le. They are called ointers for the
simle reason that# $y storing an address# they .oint/
to a articular oint in memory. , ointer oints to
that varia$le $y holding a coy of its address. 7ecause
a ointer holds an address rather than a value# it has
t!o arts. The ointer itself holds the address. The
address oints to a value. )ointers can $e used to
call $y address# there$y facilitating the changes
made to a varia$le in the called function to $ecome
ermanently availa$le in calling the function
return more than one value from a function
ass arrays and string more conveniently from one
function to another
maniulate arrays more easily $y moving ointers
to them =or to arts of them> instead of moving the
arrays themselves
create comle' data structures# such as lin:ed lists
and $inary trees# !here one data structure must
contain reference to other data structures
communicate information a$out memory# as in the
function mall= > !hich returns the location of free
memory $y using a ointer
comile faster# more efficient code than other
derived data tyes such as arrays
Therefore# a ointer varia$le is a varia$le is a varia$le
that stores the address of another varia$le. In C there
is an additional restriction on ointers % they are not
allo!ed to stored any memory address# $ut they can
only stored addresses of varia$les of a given tye.
D+C8,RIN9 , )OINT+R
Wust as any other varia$le in a rogram# a
ointer has to $e declared @ it !ill have a value# a
scoe# a lifetime# a name@ and it !ill occuy a certain
num$er of memory locations. The ointer oerator
availa$le in C is .G/# called value at address/ oerator.
It returns the value stored at a articular address. The
value at address oerator is also called .indirection/
oerator. , ointer varia$le is declared $y receding
its name !ith an asteris:. The synta' for declaring a
ointer varia$le is
datatye G ointerIvari$ale@
!here# datatye is the tye of data that the ointer is
allo!ed to hold the address of =that is# the tye of data
that the ointer is allo!ed to int to> and
ointerIvarai$le is the ointer varia$le name that is
used to refer to the address of a varia$le of tye
datatye.
,n e'amle of a ointer declaration !ould $e
char Gtr@
The a$ove declaration should $e evaluated as;
tr is a ointer to char tye data. char is not the data
tye of tr. )tr is an identifier of tye ointer and char
is a data secified that is used to indicate !hat tye of
data is at the memory address that tr is holding.
)ointers are varia$les that hold memory addresses. ,t
the memory address# held in a ointer is a value@ this
value has a data tye of one of the C data tyes or a
user(defined data tye =e.g.# structure>. In declaring a
ointer varia$le# the rogrammer is actually declaring
a varia$le that hold a memory address that ointer to a
secific tye of data value. Consider the follo!ing
declaration.
int Ga@
The a$ove declaration indicates that a is a
ointer tye varia$le that oints to int tye data. That
is# the int indicates that the ointer varia$le is intended
to store the address of an integer varia$le. Such a
ointer is said to .oint to/ an integer.
float Gt@
The a$ove declaration follo!s the fact that t is a
ointer tye varia$le that ointes to float tye data.
Some declaration are listed in Ta$le 25.4
Ta$le 25.4 &eaning of some )ointer Tye Maria$le
Declaration
Declaration What it means
int is a integer
int G
char
char G
long
long G
unsigned char
unsigned char G

is a ointer to an
integer
is a character
is a ointer to a
character
is a long integer
is a ointer to a
long integer
is an unsigned
character
is a ointer to an
unsigned character
Consider the follo!ing rogram.
Xinclude Astdio.hQ
main= >
?
int G@
float G*@
dou$le Gr@
rintf = 0Dn the si-e of integer ointer is
Nd1# si-e of => >@
rintf = 0Dn the si-e of float ointer is
Nd1# si-e of =*> >@
rintf = 0Dn the si-e of dou$le ointer is
Nd1# si-e of =r > >@
rintf = 0Dn the si-e of character ointer is
Nd1# si-e of =char G> >@
E
Outut;
In Tur$o C
the si-e of integer ointer is 4
the si-e of float ointer is 4
the si-e of dou$le ointer is 4
the si-e of character ointer 4
In 9CC
the si-e of integer ointer is 6
the si-e of float ointer is 6
the si-e of dou$le ointer is 6
the si-e of character ointer is 6
The outut sho!s that all the ointer tye
varia$les =# *# and r> ta:e u the same storage sace.
Deending uon the machine architecture# the si-e of
a ointer !ill range from $eing a 2K($it field on the
I7& )C class of machines# to a K6($it field on a Cray
suercomuter.
Why should ointers have data tyes
8et it $e assumed that an address in a
hyothetical machine is 54($its long. The addressing
of a $yte or !ord !ill# therefore# re*uire a 54($it
address. This suggests that a ointer =as ointers store
addresses> should $e caa$le of storing at least# a 54(
$it value irresective of !hether is an integer or a
character. This $rings in a *uestion. Why should
ointers have data tyes !hen their si-e is al!ays four
$ytes =in a 54($it machine> irresective of the target
they are ointing toO
7efore !e see !hy ointers should have data
tye# it !ould $e $eneficial to understand the
follo!ing oints a$out C.
It has data tyes of different si-e# i.e.# o$Vects of
different tyes !ill have different memory
re*uirements.
It suort uniformity of arithmetic oerations
across different =ointer> tyes.
It does not maintain data tye information in the
o$Vect or e'ecuta$le image.
When o$Vects of a given data tye are stored
consecutively in the memory =that is# an array>#
each o$Vect is laced at a certain offset from the
revious o$Vect# if any# deending on its si-e. ,
comiler that generates a code for a ointer# !hich
accesses these o$Vects using ointer arithmetic#
re*uires information on generating offset. The data
tye of the ointer rovides this information. This
e'lains the first oint.
The second oints is reasona$le enough to
suggest that ointers should have data tyes. Si-es of various
data tyes are $asically decided $y the machine architecture
andFor the imlementation. ,nd# if arithmetic oerators !ere
not uniform# then the resonsi$ility of generating roer
offset for accessing array elements !ould comletely rest on
the rogrammer. This has the follo!ing dra!$ac:s.
, rogrammer is li:ely to commit mista:es such as
tyograhical mista:es and roviding !rong
offsets.
)orting the code to other imlementations !ould
have re*uired changes# if data tye si-es differ.
This !ould lead to orta$ility issues.
Where is a ointer storedO
, ointer can $e stored in any location li:e any
other varia$le $ut is generally not stored on the hea.
It can $e defined and stored glo$ally# or it can $e
defined local to a function and stored on the stac:.
The si-e of the ointer deends on the imlementation
and for 54($it oerating systems# it generally re*uires
four $ytes of storage sace. This is# ho!ever# not a
re*uirement. , comiler !riter can use any num$er
of $ytes desired to store a ointer.
Yee in mind# as you go along# that a ointer is
li:e any other varia$le in the sense that it re*uires
storage sace some!here in the comuter/s memory#
$ut it is not li:e most varia$les $ecause it contains no
data# only an address. Since it is an address# it actually
contains a num$er referring to some memory location.
Dynamically allocated arrays can also $e e'anded
during the e'ecution of the rogram.
25.6.4 Initiali-ing )ointers
It should $e noted that# unli:e a simle varia$le
that stores a value# a ointer must $e initiali-ed !ith a
secified address rior to its use. One of the most
common causes of errors in rogramming $y novices
and rofessionals ali:e is uninitiali-ed ointers. These
errors can $e very difficult to de$ug $ecause the effect
of the errors is often delayed until later in the rogram
e'ecution.
Consider the follo!ing rogram.
Xinclude Astdio.hQ
void main = >
?
int G@ FG a ointer to an integer GF
rintf = 0Nd Dn1# G>@
E
This code conveys to the comiler to rint the
value that ointers to. "o!ever# has not $een
initiali-ed yet@ it contains the address B or some
random address. , ointer must not $e used until it is
assigned a meaningful address. To use a ointer that
has not $een initiali-ed roerly !ill cause
unredicta$le results. In most cases a segmentation
fault =or some other run(time error> results# !hich
means that the ointer varia$le used oints to an
invalid area of memory. Sometimes the rogram !ill
aear to run correctly $ut !hen the rogram
terminates# the message 0Null )ointer ,ssignment1
!ill $e dislayed. This message is roduced $y the
close %out routine of the rogram notifying the
rogrammer that the rogram is using an uninitiali-ed
ointer. In other cases# the use of an uninitiali-ed
ointer !ill result in a .$ut +rror/ or a &emory Fault/
run(time error. No matter !hat# the use of an
uninitali-ed ointer is e'tremely dangerous# esecially
on )C tye system# and difficult to trac: do!n.
No!# $ac: to the ne! varia$le declared
earlier. Suose stores the address of the integer
varia$le i that contains the value 5. To store the
address of .i/ in ./# the unary T address oerators is
to $e used. This is :no!n as follo!s;
H Ti@
The T oerator retrieves the lvalue =address> of
i# even though i is on the right % hand side of the
assignment oerator .H/# and coies that to the
contents of the ointer tr. No!# tr is said to .oint
to/ i. The T oerator alies only to o$Vects in
memory@ that is# varia$les and array elements. It
cannot $e alied to e'ressions# constants# or register
varia$les.
The follo!ing rogram sho!s ho! to use the
address oerator to assign the address of a varia$le to
a ointer. This rogram also demonstrates that the
value of a ointer is the same as the address to !hich
the ointer oints.
Xinclude Astdio.hQ
main = >
?
int num H J@
int Gtr H Tnum@
rintf = 0Dn The address of ' using Tnum
is N1# Tnum>@
rintf = 0Dn The address of ' using tr is
Nd1# tr>@
E
The outut =the follo!ing addresses might $e different
on different comuters> is
The address of ' using Tnum is BB24F+D6
The address of ' using tr is BB24F+D6
Figure 25.6 sho!s grahically ho! the oints to the
integer varia$le.
num
J BB24F+D6
BB24F+D6 BB24F++6
Fig 25.6 )ointer )ointing to an Integer Maria$le
,nother oint to $e remem$ered is that a
ointer varia$le is al!ays $ound to a secific data
tye =e'cet void ointer>. This means that the tye of
the ointer and the varia$le !hose address is
contained in the ointer must $e of same tye. The
follo!ing ointer initiali-ations are invalid.
int aH5# Gi@
float G@
char chH .,/@
H Ta@ IIIIIIIIINM,8ID
i H Tch@IIIIIIIINM,8ID
,ny num$er of ointers can oint to the same
address. For e'amle# !e could declare # *# and r as
integer ointers and set all of them to oint to i as
sho!n here.
int i H5@
int G# G*# Gr@
H Gi@
* H Ti@
r H @
Note that in this code# r oints to the same
address that oints to# !hich is the address of i. We
can assign ointers to one another# and the address is
coied from the right % hand side to the left % hand
side during the assignment. The ictorial
reresentation is given in Fig. 25.J.
i# G# G*# Gr
5 *
R

Fig 25.J Three )ointer to the Same
varia$le
The varia$le i no! has four names; i# G# G*#
and Gr. There is no limit on the num$er of ointers
that can hold# and therefore oint to# the same address.
)rinting ointer value
rintf =0i H Nud i H NdDn1# i# i>@
Note Nu can $e used in lace of Nud
This rints i as an unsigned decimal. This is
useful !hen the most significant $it is set =thus
causing negative signed num$ers>.
)rint ointers in he'adecimal;
)rintf =0i H o'N i H NdDn1# i# i>@
Note N l' can $e used in lace of N
+'amle outut;
i H B'a$cJB i H 6
Some imortant oints to $e notes are as
follo!s.
,ddress must al!ays $e rinted using Nu or N.
If N is used# the address is rinted in he'adecimal
form. If Nu is used# address is rinted in decimal
form =secific to DOS>.
Is it ossi$le to assign a constant to a ointer varia$leO
int Gi@
i H =intG> 2BBB@
Gi H J@
8ocation 2BBB might contain the rogram.
Since it is a read only# the OS !ill thro! u a
segmentation fault.
What a$out Gi H JO ,gain# it !ill most li:ely
cause a segmentation fault $ecause lo!er memory
addresses are tyically used for rogram code. This
area is read only. It should $e :no!n in advance
!here this constant is located in the memory. This
construction is useful !hen !riting an OS or device
driver that communicates !ith the device using
memory.
For e'amle# in order )Cs# the screen could $e
udated $y directly accessing an array in memory =the
address ro$a$ly started at B' 2BBBB>. The array !as
of integers that !ere t!o $ytes. The first $yte held the
,SCII character code and the second $yte stored the
character attri$utes. Once again# if one did not :no!
!hat one !ere doing# the comuter could crash.
25.6.5 Indirection Oerator and Dereferencing
The rimary use of a ointer is to access and# if
aroriate# change the value of the varia$le that
ointer is ointing to. The other ointer oerator
availa$le in C is .G/# called the .value at address
oerator/. It returns the value stored at a articular
address. The value at address oerator is also called
indirection oerator or deference oerator.
In the follo!ing rogram# the value of the
integer varia$le num is changed t!ice.
int = >
?
int num H J@
int Gitr H Tnum@
rintf = 0Dn The value of num is
Nd1# num>@
num H 2B@
rintf = 0Dn The value of num after
num H 2B is Nd1# num>@
Gitr H 2J@
rintf = 0Dn The value of num after
Gitr H 2J is Nd1# num>@
E
The resulting outut is
The value of num is J
The value of num after num H2B is 2B
The value of num after itr H 2J is 2J
The second change should $e familiar# $y the
direct assignment of a value to num# such as numH2B.
"o!ever# the third change is accomlished in a ne!
!ay# $y using the indirection oerator.
Gitr H 2J
The indirection oerator is an asteris:# the same
asteris: that is used to declared the ointer or to
erform multilication. "o!ever# in this statement the
asteris: is not $eing used in a declaration or to
erform multilication. Therefore# in this conte't it is
$eing used as an indirection oerator. O$serve the
follo!ing statements carefully.
int iHJ@
int G@
H Ti@
rintf = 0Dn value of i H Nd1# i>@
Outut ; J
)rintf = 0 DnMalue of i H Nd1# G=Ti> >@
Outut ;J
Note that rinting the value of G =Ti> is
same as rinting the value of i. G al!ays imlies value
at address. G =Ti> is identical to i. The unary oerators
T and G $ind more tightly than arithmetic oerators@
they associate right to left# hence GTi e*uals G =Ti>.
The lacement of the indirection oerator
$efore a ointer is said to dereference the ointer. The
value of a dereferenced ointer is not an address# $ut
rather the value at that address % that is# the value of
the varia$le that the ointer oints to.
For e'amle# in the receding rogram# itr/s
value is the address of num. "o!ever# the value of itr
dereferenced is the value of num. Thus# the follo!ing
t!o statements have the same effect# $oth changing
the value of num.
num H 4J@
Gitr H 4J@
Similarly# a dereferenced ointer can $e used in
arithmetic e'ressions in the same fashion as the
varia$le to !hich it oints. Thus# the follo!ing t!o
statements have the same effect.
num G H 4@
Gitr GH 4@
In these e'amle# changing a varia$le/s value
using the indirection oerator rather than through a
straightfor!ard assignment seems li:e an unnecessary
comlication. "o!ever# there are instances covered
later in this chater# such as looing through an array
using a ointer# or using dynamic memory allocation#
in !hich using the indirection oerator is helful or
even necessary.
,ddress of oerator =T> It is used as a varia$le
refi' and can $e translated as .address of. Thus#
Tvaria$le can $e read as .address of varia$le/.
Deference Oerator =G> It indicates that !hat
has to $e evaluated is the content ointed $y the
e'ression considered as an address. It can $e
translated $y .value ointed $y/ or .value at address/.
Gtr can $e read as .value ointed $y tr/.
The follo!ing e'amle sho!n ho! ointers can
$e used to add num$ers given $y the user through the
use of ointers !ithout using the varia$le directly.
Xinclude Astdio.hQ
main = >
?
int a# $# c@
int Ga# G$# Gc@
aHTa@
$HT$@
cHTc@
rintf = 0Dn +NT+R T"+ FIRST
NU&7+R;1>@
scanf =0Nd1# a>@
rintf = 0Dn +NT+R T"+ S+COND
NU&+7R;1>@
scanf = 0Nd1# $>@
GcHGaC$@
)rintf = 0Dn SU& IS Nd1# Gc>@
E
Out ut;
+NT+R T"+ FIRST NU&7+R J
+N+TR T"+ S+COND NU&7+R K
SU& IS 22
The follo!ing statements are also valid.
Gtr H Gtr C 2B@
increments Gtr $y 2B. The unary oerators G
and T $ind more tightly than arithmetic oerators# so
the assignment
y H Gtr C 2
ta:es !hatever tr oints at# adds 2# and assigns
the result to L# !hile
Gi CH2
Increments !hat tr oints to. , ointer
varia$le does not al!ays oints to a articular varia$le
throughout the rogram. It can oint to any varia$le@
the only recondition is that their tye must $e same
$ecause the ointer varia$le is $ound to secific data
tye. The follo!ing rogram illustrates this fact.
Xinclude Asdtio.hQ
main = >
?
int aHJ# $H2B@
int G@
H Ta@
rintf = 0DnaHNd $HNd GHNd1# a# $#
G>@
HT$@
rintf = 0DnnaHNd $HNd GHNd1# a# $#
G>@
E
Outut ;
aHJ $H2B GHJ
aH J $H2B GH2B
MOID )OINT+R
, void ointer is a secial tye of ointer.
It can oint to any data tye# from an integer value or
a float to a string of characters. Its sole limitation is
that the ointed data cannot $e referenced directly =the
asteris: G oerator cannot $e used on them> since its
length is al!ays undetermined. Therefore# tye
casting or assignment must $e used to turn the void
ointer to a ointer of a concrete data tye to !hich
!e can refer. Ta:e a loo: at the follo!ing e'amle.
Xinclude Astdio.hQ
main= >
?
int a H J#
dou$le $H5. 262J@
void Gv@
vHTa@
rintf = 0Dn aHNd1# G= =int G> v> >@
vHT$@
rintf = 0Dn aH Nd1# G= = dou$le G> v> >@
E
Outut
a H J
$ H 5. 262JBB
NU88 )OINT+R
Suose a varia$le# e.g.# a# is declared
!ithout initiali-ation.
int a@
If this is made outside of any function#
,NSI %comliant comilers !ill initiali-e it to -ero.
Similarly# an uninitiali-ed ointer varia$le is
initiali-ed to a value guaranteed in such a !ay that it
is certain not to oint to any C o$Vect or function. ,
ointer initiali-ed in this manner is called a null
ointer.
, null ointer is a secial ointer value that
ointer no!here. That is# no other valid ointer to any
other varia$le or array cell or anything else !ill ever
$e e*ual to a null ointer.
The most straightfor!ard !ay to get a null
ointer in the rogram is $y using the redefined
constant NU88# !hich is defined $y several standard
header files# including Astdio.hQ# Astdli$.hQ# and
Astring.hQ. To initiali-e a ointer to a null ointer#
code such as the follo!ing can $e used.
Xinclude Astdio.hQ
int Gi H NU88@
To test it for a null ointer $efore insecting the
value ointer to# code such as the follo!ing can $e
used.
if =i Z H NU88>
rintf = 0NdDn1# Gi>@
It is also ossi$le to refer to the null ointer
using a constant B# and to set null ointer $y simly
saying
int Gi H B@
If it is too early in the code to :no! !hich
address to assign to the ointer# then the ointer can
$e assigned to NU88# !hich is a constant !ith a
value of -ero defined in several standard li$raries#
including stdio.h. The follo!ing rogram does so.
Xinclude Astdio.hQ
main = >
?
int G@
H NU88@
rintf = 0Dn The value of is Nu1#
>@
E
The resulting outut is
The value of is B
On most oerating systems# rograms are not
ermitted to access memory at address B $ecause that
memory is reserved $y the oerating system. It is not
the case that the ointer oints to a memory address
that is reserved $y the oerating system. "o!ever# the
memory address B has secial significance@ it signals
that the ointer is not intended to oint to an
accessi$le memory location. Thus# if it is too early in
the code to :no! !hich address to assign to a ointer#
the ointer should first $e assigned to NU88# !hich
then ma:es it safe to access the value of a ointer
$efore it is assigned a .real/ value such as the address
of another varia$le or constant.
Furthermore# since the definition of .true/ in C
is a value that is not e*ual to B# the follo!ing
statement tests for non(null ointer !ith a$$reviated
code such as
if =i>
rintf = 0NdDn1# Gi>@
This has the same meaning as our revious
e'amle@ if = i > is e*uivalent to is =i Z H B > and to if
=i Z H NU88>. The value B can $e used to reresented
a null ointer in
assignment and initiali-ation
comarison
,ll of these uses are legal# although the use of
the constant NU88 is recommended for clarity.
US+ OF )OINT+RS
Call $y address
Once of the tyical alications of ointers is to
suort call $y reference. "o!ever# C does not
suort call $y reference as so other rogramming
languages such as ),SC,8 and FORTR,N.
Tyically a function call is made to communicate
some arguments to the function. C ma:es use of only
one mechanism to communicate arguments to a
function; call $y value. This means that !hen !e call
a function# a coy of the values of the arguments is
created and given to the function. For e'amle#
Xinclude Astdio.hQ
void s!a =int a# int $>
?
int tem@
tem H a@
aH $@
$Htem@
E
main = >
?
int 'HJ# yH2B@
void s!a =int # int>@
rintf =0Nd NdDn1# '# y>@
s!a ='# y>@
rintf = 0Nd NdDn1# '#y>@
E
Outut;
J 2B
J 2B
No s!aing ta:es lace. No! !hen the
function s!a is called# the system automatically
creates t!o ne! varia$les =called a and $ in this case>.
These !ill contain a coy of the values that are
secified in the function call =i.e.# the value of ' and
the value of y>. ,ll the oerations erformed $y the
function oerator on the coies of the values =a#$> and
!ill not affect the original values ='# y>.
Of course# in this articular e'amle# the
function !ill ro$a$ly not accomlish !hat is needed.
The function s!a is used to e'change the content of
t!o varia$les# $ut !hen the call is made# the function
!ill receive and oerate on the coies of the varia$les#
leaving the original varia$les ='# y> untouched. So at
the end of the function the effect of the changes done
$y s!a are lost =the coies created !hen the function
is called are destroyed !hen the function is
comleted>.
This is a common situation in C. +ach function
al!ays receives coies of values and the function does
not have any !ay of modifying the value of varia$les
that e'ist outside of the function =e.g.# '#y in the
e'amle>.
The !ay to o$tain the desired effect is call $y
reference. This means that !hen !e call the function#
!e do not create coies of values $ut !e allo!s the
function to access the original values. This also means
that if the function modifies such values# then the
modification !ill affect the original value and !ill
ersist once the function is finished.
Call $y reference does not e'ist in C# $ut it can
$e simulated through the use of ointers. To ma:e a
function $e a$le to modify a certain varia$le in
memory 3i.e.# its address>. If the function :no!s
!here the varia$le is in memory# it !ill $e a$le to
access that area of memory $y using ointers and
change its content. This is :no!n as call $y address.
The !ay to o$tain the desired effect is for the
calling rogram to ass ointers to the values to $e
changed.
S!a =T'# Ty>@
Since the oerator T roduces the address of a
varia$le# T' is a ointer to '. In s!a itself# this !ill
arrive to the function in the form of a ointer. That is#
the arameters are declared as ointers# and the
oerands are accessed indirectly through them. No!
the receding rogram is re!ritten using call $y
address.
Xinclude Astdio.hQ
void s!a =int Ga# int G$>
?
int tem@
tem H Ga@
Ga H R$@
G$ H tem@
E
main = >
?
int 'HJ# yH2B@
void s!a =int G# int G>@
rintf = 0Nd NdDn1# '#y>@
s!a =T'# Ty>@
rintf = 0Nd NdDn1# '# y>@
s!a =T'# Ty>@
rintf =0Nd NdDn1# '# y>@
E
Outut
J 2B
2B J
The values have $een e'changed $y the
function s!a= >. Within the main= > function# the T
oerator causes the address of arguments ' and y to $e
assed in the call to s!a= >. In the s!a = B function
header# the addresses $eing assed from the calling
function are received in ointer tye varia$les =int Ga#
int G$>. Within the s!a = > function $ody# the G
oerator is used to retrieve values held at the
addresses that !ere assed. The follo!ing e'amle
attemts to demonstrate ho! identifiers or varia$les
are assigned locations in memory and ho! values are
stored in those locations. ,ll addressing in the
follo!ing e'amle is assumed ar$itrarily.
Maria$le memory value
name address
int main= >
?
void s!a = int G# int G>@
int
' H J '
4BBB J
#y H 2B y
4BB4 2B
@
FG ass addresses GF
s!a = T'# Ty>@
return B@
E
void
s!a = int Ga# int G$> a
5BBB 4BBB
$
5BB4 4BB4
?
int tem@
tem 6BBB BFgar$age
tem H Ga@
tem 6BBB J
Ga H G$@ Ga
5BBB 2B
G$ H tem@ G$
5BB4 J
E
In the a$ove code# the addresses of ' and y are
assed to the function s!a= >. The arguments of the
s!a= > function# int Ga and int G$ are ointers to
integer tye data. These ointers receive the addresses
of ' and y resectively that are assed in the call to
s!a= >. Within the function s!a= >. a local varia$le
tem is declared. The ointer a is dereferenced#
meaning that the value at the address held in a is
retrieved. This value is stored into tem. Then the
value at the address held in $ is retrieved and assigned
to the value at the address held in a# thus e'changing
values. The final statement in the function comletes
the e'change of values. Notice that the function does
not return a value $ecause of the void return tye.
Figure 25.K resents this diagrammatically.
In main
In s!a
' y
a $
J 2B

Fig 25.K call $y ,ddress
Suose one accidentally forgets the T !hen
the s!a function is called# and that the s!a line
accidentally loo:s li:e this;
S!a ='# y>@
This causes a segmentation fault. When you
leave out the T# the value of a is assed instead of its
address. Therefore# a oints to an invalid location in
memory and the system crashes !hen Ga is used.
Returning more than one value from a function
Functions usually return only one value and
!hen arguments are assed $y value# the called
function cannot alter the values assed and have those
changes reflected in the calling function. )ointers
allo!s the rogrammer to .return/ more than one
value $y allo!ing the arguments to $e assed $y
address# !hich allo!s the function to alter the values
ointed to# and thus .return/ more than one value $y
allo!ing the arguments to $e assed $y address#
!hich allo!s the function to alter the values ointed
to# and thus .return/ more than one value from a
function.
+'amle 2;
Xinclude Astdio.hQ
main = >
?
float r# area# erimeter@
float comute =float# loast G>@
rintf = 0Dn enter the radius of the
circle ; 0>@
scanf = 0Nf1# Tr>@
area H comute =r# Terimeter>@
rintf = 0 Dn ,R+, H Nf1# area>@
rintf = 0 Dn )+RI&+T+R H Nf1#
erimeter>@
E
float comute =flaot r# flaot G>
?
float a@
aH=float> 5.26.2J G r G r@
G H =float> 5.262J G 4 G r@
return a@
E
"o! is the data returnedO
Returning data is not as easy to
define since the comiler !riter has a good deal of
lee!ay# $ut must follo! one rule.
The returned value must $e availa$le for use long
enough to ermit the rogrammer to store follo!
one rule.
The value returned# in this case the roduct of
the t!o values assed in# may $e returned on the stac:
or it may $e returned in a register# or any other !ay
that the comiler !riter desires. It is u to the
comiler !riter to rovide a means of storing the
returned value in the calling rogram in a manner that
corresonds !ith the means of returning it. It must $e
remem$ered that the system must someho! maintain
a coy of the returned value long enough for you to
store a local coy of it. It must :ee the value
availa$le until e'ecution reaches a se*uence oint#
!hich in this case means the end of the statement.
When !e notify the system to assign the value to area#
!e are saving a coy of it. Follo!ing that# the
comiler !riter may delete the memory used to return
the value. If it !as returned on the stac:# it is
imerative to remove it from the stac: in rearation
for the ne't oeration. 7ut that can $e done $ecause
the value is stored in area and can $e used in any !ay.
,RR,L ,ND )OINT+RS
)ointer and arrays are inseara$ly related# $ut
they are not synonymous.
One Dimensional ,rrays ,nd )ointers
,n array is a non(emty set of se*uentially
inde'ed elements having the same tye of data. +ach
element of an array has a uni*ue identifying inde'
num$er. Changes made to one element of an array
does not affect the other elements. ,n array occuies a
contiguous $loc: of memory. The array a is laid out in
memory as a contiguous $loc:# as sho!n
int a[\ H ?2B# 4B# 5B# 6B# JBE@
a[B\ a[2\ a[4\
a[5\ a[6\

2
B

4
B
5
B
6
B
J
B
426P6PR4PB 426P6PR4P6
426P6PR4PR 426P6PR4R4 426P6PR4RK
+lements of array are stored the successive
increasing locations of memory. For e'amle# if the
array starts at memory location 426P6PRPB
3considering a 54($it machine>. The !ith the assumed
si-e of an integer as four $ytes# the first element is
stored at location 426P6PRPB# the second element at
location 426P6PR4P6# and so on. "ere the locations
are ta:en as ar$itrary.
,rray notation is a form of ointer notation.
The name of an array is the $eginning address of the
array# called the $ase address of the array. That is# the
$ase address of an array is the address of the -eroth
element of the array. The array name is referred to as
an address constant. &entioning the name of the array
fetches its address. Consider the follo!ing rogram.
+'amle 4;
Xinclude Astdio.hQ
main = >
?
int array[\ H ?2B# 4B# 5B# 6B# JBE@
rintf = 0Nu Nu1# array# Tarray [B\
>@
E
Outut;
426P6PR4PB 426P6PR4PB
,gain# consider the follo!ing rogram.
Xinclude Astdio.hQ
main= >
?
int array[\ H ?2B# 4B# 5B# 6B# JBE@
rintf = 0Nu Ju1# array# Tarray>@
E
Outut ;
426P6PR4PB 426P6PR4PB
7oth array and Tarray !ould give the $ase
address of the array. Through $oth array and Tarray
give the same address# there is a small difference
$et!een them. Under ,NSIFISO standard C# Tarray
yields a ointer# of tye ointer(to(array(of(T# !here T
is the data tye to the entire array. Under re(,NSI C#
the T in Tarray generally elicited a !arning# and !as
generally ignored. Under all C comilers# an
unadorned reference to an array yields a ointer# of
tye ointer(to(T# to the array/s first element.
,n array can $e su$scrited to get to individual
cells of data. With the name of the array actually
$eing a constant that reresents a memory address# the
name of the array can $e used as a ointer and an
integer value can $e used to reresent an offset from
the $ase address. This alternate method can $e used to
get to individual cells of an array. ,n element of the
array a is addressed as a [i\ and the address of the i th
element of the array a is given $y Ta [i\ H a Ci G si-e
of the tye ointed to $y a.
The e'ression a C i =!ith integer i> means the
address of the i th element $eyond the one a oints to.
This is not measured in num$er of $ytes# $ut in
num$er of si-e of =tye> $ytes. This is :no!n as
scaling.
,s indirection oerator .G/ imlies value at
address# a [i\ is e*uivalent to G =aCi>. Consider the
follo!ing t!o versions of the same rogram.
+'amle 5@
Xinclude Astdio.hQ
main = >
?
int a[\ H ?2B# 4B# 5B# 6B# JBE@
int i@
for =iHB@ iAJ@ CCi>
rintf = 0Dn Nd1# a[i\ >@
E
Outut;
2B
4B
5B
6B
JB
=ii> Xinclude Astdio.hQ
main= >
?
int a [\ H ?2B# 4B# 5B# 6B# JBE@
int i@
for =iHB@ iAJ@CCi>
rintf = 0DnNd1# G=aCi> >@
E
Outut;
2B
4B
5B
6B
JB
The integer identifier i is added to the $ase
address of the array. The C comiler comutes the
resulting address that !ill $e accessed $y ta:ing the
value held in i multilied $y the si-e in $ytes of the
tye of array a and adds the roer offset to a to give
the correct memory address. Su$scrit notation is
converted $y the comiler into the ointer notation.
"ence#
)ointer notation !ould !or: faster since
conversion time can $e saved $y using it.
,ll the follo!ing four e'ressions are the
same !hen their addresses are considered.
a [i\
G = a C i >
G = i C a >
i [a\
In the e'ression a [i\# i must $e an integer. The
other may either $e an array name or a ointer. For
any one(dimensional array a and integer i# the
follo!ing relationshis are al!ays true.
2. Ta [B\ H H a
The address of the first element of the
array a is the value of a itself. In other
!ords# a is a ointer@ it oints to the first
element in the array
4. Ta [i\ H H a C i
The address of the ith element of a is the
value of a C i. This is one of the great truths =and a
defining characteristic> of C. The first relationshi is a
secial case of this more general relationshi.
5. a[i\ H H G = a C i>
This is $asically the same as the revious
relationshi $ut this relationshi still
holds if !e dereference $oth sides of the
e*uality
6. =Ta [i\ ( Ta [V\ > H H = i % V>
This relationshi defines the su$traction
of ointers. The su$traction of t!o
ointers of tye t is the num$er of
elements of tye t that !ould fit $et!een
them.
, ointer varia$le =of the aroriate
tye> can also $e used to initiali-e or oint to the
first element of the array. Then it can also $e used as
a$ove.
Xinclude Astdio.hQ
main = >
?
int a[\ H ?2B# 4B# 5B# 6B# JBE@
int i# G@
Ha@ FG it can also $e !ritten as HTa[B\@
GF
for =iHB@ iAJCCi>
rintf = 0 DnNd1# [i\ >@
rintf = 0 DnNd1# G=Ci> >@
OR
rintf = 0Dn Nd1# G=iC> >@
OR
rintf = 0DnNd1# i [\ >@
Outut;
2B
4B
5B
6B
JB
One can define a ointer of the same tye as the
elements of the array and can assign it the address of
any element of the array and use it to access the array
elements. In fact# one may add an integer value to it.
Such a statement in the rogram uses the formula
given earlier to do the assignment@ so it also adVusts
the count for the si-e of the element. )ointers and
array are so closely related that their notation can $e
interchanged such that the follo!ing terms are
identical if contains the value of a.
a [i\
G = a C i >
G = C i >
) [i\
!here iHB#2#4#S=N(2>. N is the si-e of the
array.
The similarities $et!een arrays and ointers
end u $eing useful# and in fact C $uilds on the
similarities# leading to !hat is called .the e*uivalence
of array and ointers in C/. When !e sea: of this
e*uivalence# !e do not mean that array and ointer
are the same =they are# in fact# *uite different> $ut that
they can $e used in related !ays# and that certain
oerations may $e used $et!een them. These
oeration are as follo!s.
The first such oeration is that it is ossi$le to
=aarently> assign an array to a ointer.
int a[2B\@
int G@
H a@
C defines the such result of this assignment to
$e that receives a ointer to the first element of a. In
other !ords.
H Ta [B\@
The second asect of the e*uivalence is that the
array su$scriting notation [i\ can $e alied on
ointers# too. [5\ can $e !ritten as G=) C 5>.
So a ointer that oints to an array or a art of
an array can $e treated .as if/ it !as an array# using the
convenient [i\ notation. In other !ords# at the
$eginning of this discussion# the e'ressions G#
G=C2># G=C4># and in general G=Ci># could have $een
!ritten as [B\# [2\# [4\# and [i\. This can $e *uite
useful =or at least convenientB.
The ointer to an array does not al!ays oint to
the first element of the array. It can oint to any
element of the array. For e'amle#
int a[\ H?2B#4B#5B#6B#JBE@
int G@
H a C 5@
can also $e !ritten as follo!s
H Ta [B\ C 5@
!hich# in turn# given the same result as
H Ta [5\@
Figure 25.P deicts the e*uivalence among
array notation and ointer notation.
a [B\ a[2\ a[4\
a[5\ a[6\

2
B
4
B
5
B
6
B
J
B
H a H a C
4 H a C 6
H Ta [B\ H Ta
[4\ H Ta [6\
Fig 25.P )ointer Notation of ,rray
+lements
Is it ossi$le to treat an .array/ as if it !ere a 2 %
$ased arrayO.
,lthough this techni*ue is attractive =and !as
used in old editions of the $oo: Numerical Recies in
C># it does not conform to the C standards. )ointer
arithmetic ism defined only as long as the ointer
oints !ithin the same allocated $loc: of memory# or
to the imaginary .terminating/ element one ast it@
other!ise# the $ehavior is undefined# even if the
ointer is not dereferenced. The receding code could
fail if# !hile su$tracting the offset# an illegal address
!ere generated =erhas $ecause the address tried to
.!ra around/ ast the $eginning of some memory
segment>. "ere is a neat tric:# the details of !hich !ill
$e discussed in Section 25.2R
int arr [2B\@
int Ta H Tarr [(2\@
),SSIN9 ,N ,RR,L TO , FUNCTION
,n array may $e assed to a function# and the
elements of that array modified !ithout having to
!orry a$out referencing and derererencing. Since
arrays may transform immediately into ointers# all
the difficult stuff gets done automatically. , function
that e'ects to $e assed an array can $e declare that
formal arameter in one of the t!o !ays.
int a [\ or int Ga
When assing an array name as argument to a
function# the address of the -eroth element of the array
is coied to the local ointer varia$le in the function.
The value of the elements are not coied. The
corresonding local varia$le is considered as a ointer
varia$le# having all the roerties of ointer arithmetic
and dereferencing. It is not an address constant. 8et us
illustrate this !ith an e'amle. The relevant function
calls in main= > and the corresonding function
headers are sho!n as follo!s for easy reference.
Xdefine &,] JB
main = >
?
int arr [&,]\# n@
S..
n H getdata =arr# &,]>@
sho! =arr# n>@
E
int getdata =int a[\# int n>
?
S..
E
void sho! =int a[\# int n>
?
S
E
When a formal arameter is declared in a
function header as an array# it is interreted as a
ointer varia$le# not an array. +ven if a si-e !ere
secifies in the formal arameter declaration# only a
ointer cell is allocated for the varia$le# not the entire
array. The tye of the ointer varia$le is the secified
tye. In the receding e'amle# the formal arameter#
s# is an integer ointer. It is initiali-ed to the ointer
value assed as an argument in the function call. The
value assed from main= > is arr# a ointer to the first
element of the array# arr[\.
Within the function# getdata= ># it is no!
ossi$le to access all the elements of the array
indirectly. Since the varia$le a in getdata = > ointer to
the first element of the array arr[\# it accesses the first
element of the array. In addition# a C 2 oints to the
ne't element of the array# so accesses the ne't
elements i.e.# arr[2\. In general# G =aCi> accesses the
element arr[i\. To access elements of the array# !e
can either !rite G =a C i> or a [i\# $ecause dereferenced
array ointers and inde'ed array elements are identical
!ays of !riting e'ression for array access.
The functions# getdata= > and sho! = > can $e
used to read o$Vects into any integer array and to rint
element values of any integer array# resectively. The
calling function must simly ass an aroriate array
ointer and ma'imum num$er of elements as
arguments. These functions may also $e !ritten
e'licitly in terms of indirect access.
+'amle 6;
Xinclude Astdio.hQ
Xdefine &,] JB
main = >
?
int arr [&,]\# n@
int getdata =int G# int>@
void sho! =int G# int>@
n H getdata =arr# &,]>@
sho! =arr# n>@
E
F G Function reads scores in an array. GF
int getdata =int Ga# int n>
?
int '# I H B@
rintf = 0 Dn +nter the array elements one
$y one Dn1>@
!hile =iAn>
?
scanf =0Nd1# T'>
G =aCi> H'@
iCC@
E
return i@
E
void sho! =int Ga# int n>
?
int i@
for =iHB@ iAn@CCi>
rintf = 0Dn Nd1# G=aCi> >@
E
Figure 25.R illustrates the connection $et!een
the calling function main = ># and the called functions.
main= >
?
int arr [&,]\# n@
S
aHarr@
n H getdata =arr# &,]>@
sho! =arr# n>@
E
a H arr@ int getdata =int
Ga# int n>
?
void sho! =int Ga# int n> S.
? E
S.
E
Fig 25.R )assing ,rray to a Function
)arts of an array# called a su$ % array# may also
$e assed to a function. , ointer to a su$(array is
also an array ointer@ it simly secifies the $ase of
the su$(array. Inn fact# as far as C is concerned# there
is no difference $et!een an entire array and any of its
su$(arrays. For e'amle# a function call can $e made
to rint a su$(array $y secifying the starting ointer
of the su$(array and its si-e. Suose !e need to rint
the su$(array starting at arr[5\ containing five
elements@ the e'ression# Tarr[5\ is a ointer to an
array starting at arr[5\. The function call is
sho! =Tarr[5\# J>@
,lternately# since arr C 5 oints to arr[5\# the
function call can $e
sho! =arr C 5# J>@
DIFF+R+NC+S 7+TW++N ,RR,L N,&+ ,ND
)OINT+R
From the a$ove discussion it seems that array
name and ointer# !hich oints to the $ase address of
the array# are e*uivalent. 7ut it is not true. There are a
several differences $et!een them. They are as
follo!s.
When memory is allocated for the array# the
starting address is fi'ed# i.e.# it cannot $e changes
during rogram e'ecution. Therefore# array name is an
address constant@ the value contained in it should not
$e changed. To ensure that this ointer is not changed#
in C# array names may not $e used as varia$les on the
left of an assignment statement# i.e.# they may not $e
used as an lvalue. Instead# if necessary# searate
ointer varia$les of the aroriate tye may $e
declared and used as lvalues. "ere is an e'amle of a
common error !hen an attemt to use an array as an
lvalue is made.
Xinclude Astdio.hQ
main = >
?
int i@
dou$le a [J\@
for =iHB@ iAJ@ iCC>
?
Ga H B.B@
a CC@ FG 7U9; aHaC2@ GF
E
E
In this e'amle# a is fi'ed and cannot $e used
as an lvalue@ the comiler !ill generate an error
starting that an lvalue is re*uired for the CC oerator.
"o!ever# a ointer varia$le can $e declared# !hich
can oint to the same tye as the tye of the array# and
initiali-e it !ith the case address of array. This ointer
varia$le can $e used as an lvalue and no error message
!ill $e dislayed. "ere is the difference.
Xinclude Astdio.hQ
main = >
?
int i@
float Gtr# a[J\@
tr H a@
for =iHB@ iAJ@ iCC>
?
Gtr HB.B@ FG Gtr accesses a[i\ GF
tr CC@
E
E
O$serve that the ointer varia$le# tr is tye
float G# $ecause the array is of tye float#. It is
initiali-ed to the value of the fi'ed ointer# a =i.e.# the
initial value of tr is set to the same as that of a#
namely# Ta[B\># and may su$se*uently $e modified in
the loo to traverse the array. The first time through
the loo# Gtr =a[B\> is set to -ero and tr is
incremented $y one so that it oints to the ne't
element in the array. The rocess reeats and each
element of the array is set to B.B.
Follo!ing the same concet# an array cannot $e
assigned to another. The follo!ing code
int a[J\ H?2# 4# 5# 6# JE@
int $ [J\@
$ H a@ FG WRON9 GF
is illegal. To coy a into $# something li:e the
follo!ing has to $e entered.
for =iHB@ iAJ@ iCC>
$[i\ Ha [i\@
Or# to ut it more succinctly#
for =iHB@ iAJ@ $[i\Ha# iCC>@
7ut t!o ointer varia$les can $e assigned.
int G2# G4@
int a[2B\ H?2# 4# 5# 6# JE@
2 H Ta [B\@
4 H 2@
)ointer assignment is straightfor!ard@ the
ointer on the left is simly made to oint !herever
the ointer on the right does. The statement 2H4
does not coy the data ointed to =there is still Vust one
coy in the same lace>@ it Vust ma:es t!o ointers
oint to the same location.
The T =address of> oerator normally returns
the address of the oerands. "o!ever# array are the
e'cetion. When alied to an array =!hich is an
address># it has the same value as the array reference
!ithout the oerator. This is not true of the e*uivalent
ointers# !hich have an indeendent address. The
follo!ing e'amle sho!n this.
+'amle J;
=2> Xinclude Astdio.hQ
main = >
?
int a[\ H ?2B# 4B# 5B# 6B# JBE@
rintf = 0Nu Nu Nu1# a# Ta [B\# Ta>@
E
Outut;
KJJBK KJJBK KJJBK
=ii> Xinclude Astdio.hQ
main = >
?
int a[\ H?2B# 4B# 5B# 6B# JBE@
int Gtr@
trHa@
rintf = 0Nu Nu1# Ta [B\# tr
Ttr>@
E
Outut;
KJJBK KJJBK KJJBK
The si-e of oerator returns the si-e of the
allocated sace for arrays. In case of a ointer# the
si-eof oerator returns t!o or four or more $ytes of
storage =machine deendent>.
+'amle K;
=i> Xinclude Astdio.hQ
main = >
?
int a [\ H ?2B# 4B# 5B# 6B# JBE@
rintf = 0Nd1# si-eof =a> >@
E
Outut ;
In Tur$o C
2B
In 9CC
4B
=ii> Xinclude Astdio.hQ
main = >
?
int a [\ H ?2B# 4B# 5B# 6B# JBE@
int Gtr@
trHa@
rintf = 0Nd1# si-e of =tr> >@
E
Outut@
In Tur$o C
4
In 9CC
6
,rray
)ointer
G ,rray allocates sace automatically. G
It is e'licitly assigned to oint to an allocated sace
G It cannot $e resi-ed. G
It can $e resi-ed using realloc= >.
G It cannot $e reassigned. G It can
$e reassigned.
G si-e of =array name> gives the num$er
Gsi-e of => returns the num$er of $ytes used to
store the of $ytes occuied $y the array
the ointer varia$le .
)OINT+R ,ND STRIN9
String are one(dimensional arrays of tye char.
7y convention# a string in C is terminated $y the end(
of(string sentinel DB# or null character. The null
character is a $yte !ith all $its off@ hence# its decimal
value is -ero. 7ecause dealing !ith string has its o!n
flavor# !e treat the toic searately. It is useful to
thin: of strings as having a varia$le length# delimited
$y Do# $ut !ith the ma'imum length determined $y the
si-e of the string. The si-e of a string must include the
storage needed for the end(of(string sentinel. ,s !ith
all arrays# it is the Vo$ of the rogrammer to ma:e sure
that string $ounds are not overrun.
String constants are !ritten $et!een dou$le
*uotes. For e'amle# 0a$c1 is a character array of
si-e6# !ith the last element $eing the null character DB.
Note that string constants are different from character
constants. For e'amle# 0a1 are not the same. The
array 0a1 has t!o elements# the first !ith value .a/ and
the second !ith value/ DB/.
, string constant# li:e an array name $y itself#
is treated $y the comiler as a ointer. Its value is the
$ase address of the string. 8i:e the numeric array#
individual character contained in a string can $e
rinted.
Xinclude Astdio.hQ
main = >
?
char s[\ H 0O'ford1@
for =iHB@ s[i\ Z H .DB/@ CCi>
utchar =s[i\ >@
E
Note , string in C is a ointer itself. The
follo!ing rogram roves the fact.
Xinclude Astdio.hQ
main = >
?
for =iHB@ G = 0I an a ointer1 C i> Z H .DB/@
CCi>
rintf = 0Nc1# G =I am a ointer1 C i> >@
E
Outut;
I am a ointer
7ut this is not true for a numeric array. The
follo!ing rogram given an error.
Xinclude Astdio.hQ
main = >
?
for =iHB@ G= ?2# 4# 5# 6# JE C i> Z H .DB/@C
Ci>
utchar = G = ?2# 4# 5# 6# JE C i> >@
E
Consider the follo!ing code.
char G H 0a$c1@
rintf = 0Ns Ns Dn1# # C2>@ FG a$c $c
is rinted GF
The varia$le is assigned the $ase address of
the character array .a$c/. When a ointer to char is
rinted in the format of a string# the ointed(at
character and successive character are rinted until the
end(of(string sentinel is reached. Thus# in the rintf= >
statement# the e'ression causes 0a$c1# causes $c to
$e rinted. 7ecause a string constant such as 0a$c1 is
treated as a ointer# e'ression such as
0a$c1[2\ and G =0a$c1C4>
,re ossi$le. Such e'ression are not used in
serious code# $ut they hel to emhasi-e that string
constants are treated as ointers. It should $e noted
that arrays and ointers have similar uses. They also
have differences. 8et us consider t!o declarations
char G H 0a$cde1@ and char s[\ H 0a$cde1@
In the first declaration# the comiler allocates
sace in the memory for # uts the string constant
0a$cde1 in memory some!here else# and initiali-es
!ith the $ase address of the string constant. We no!
thin: of as ointing to the string. The second
declaration is e*uivalent to
char s[\ H ?.a/# .$/# .c/# .d/# .e/# .DB/E@
7ecause the $rac:ets are emty# the comiler
allocates si' $ytes of memory for the array s. The first
$yte is initiali-ed !ith .a/# the second $yte is
initiali-ed !ith .$/# and so on. "ere is ho! !e thin:
of these o$Vects stored in memory.
)
s
a $ c d e DB
a $ c d e DB
, char is al!ays stored in one $yte# and on
most machines a ointer is stored in a !ord. Thus# on
our machine# is stored in four $ytes# and s is stored
in si' $ytes of storage. For technical reasons# it is
$etter not to rint null characters. "o!ever# the
rinting of null string is erfectly acceta$le.
One *uestion may arise % !hen am array is
assed# ho! does the function :no! ho! many
elements the array hasO
For a string# the num$er of elements it has need
not $e assed $ecause it has the terminating null
character. For other tyes of arrays# the num$er of
elements must $e assed as !ell.
)OINT+R ,RIT"&+TIC
If is declared as a ointer varia$le of any tye
and it has $een initiali-ed roerly# then# Vust li:e a
simle varia$le# any oeration can $e erformed !ith
G. 7ecause G imlies value at address# !or:ing !ith
G means !or:ing !ith the varia$le !hose address is
currently held $y . ,ny e'ression# !hether
relational# arithmetic# or logical can $e !ritten# !hich
is valid for a simle value varia$le. 7ut !ith only #
oerations are restricted as in each case address
arithmetic has to $e erformed. The only valid
oerations on ointers are as follo!s.
,ssignment of ointers to the same tye of
ointers; the assignment of ointers is done
sym$olically. "ence no integer constant e'cet B
can $e assigned to a ointer.
,dding or su$tracting a ointer and an integer.
Su$tracting or comaring t!o ointers =!ithin
array limits> that oint to the elements of an array.
Incrementing or decrementing the ointers =!ithin
array limits> that oint to the elements of an array.
When a ointer to an integer is incremented $y t!o
=as t!o $ytes are used for int>. Such scaling factors
necessary for the ointer arithmetic are ta:en care
of automatically $y the comiler.
,ssigning the value B to the ointer varia$le and
comaring B !ith the ointer. The ointer !ith
address B oints to no!here at all.
These valid address arithmetic are discussed
$elo! in detail. Do not attemt the follo!ing
arithmetic oerations on ointers. They !ill not !or:.
,ddition of t!o ointers
&ultilying a ointer !ith a num$er
Dividing a ointer !ith a num$er
,SSI9N&+NT
)ointers !ith the assignment oerators
can $e used if the follo!ing conditions are met.
The left(hand oerand is a ointer and the right(
hand oerand is a null ointer constant.
One oerand is a ointer to an o$Vect of
incomati$le tye and the other is a ointer to
void.
7oth the oerands are ointers to comati$le tyes.
Some of the ointer assignment statements !ere
discussed earlier. For the notion of incomati$le
tyes# including the use of void G# there are no! some
comlicated rules a$out ho! ointers can $e mi'ed
and !hat arithmetic !ith ointers really ermits.
)ointer to void can $e freely converted $ac:
and forth !ith ointers to any o$Vect or incomlete
tye. Converting a ointer to a ointer to an o$Vect or
an incomlete tye to void G and then $ac: given a
value !hich is e*ual to the original one.
+'amle P;
Xinclude Astdio.hQ
main= >
?
int i@
int Gi@
void Gv@
i H Ti@
v H i@
i H v@
if =i Z H Ti>
rintf = 0Dn Comiler error Dn1>@
else
rintf = 0Dn No Comiler error Dn1>
E
Outut;
No Comiler error
No!# consider the revised version of the
rogram in +'amleP.
Xinclude Astdio.hQ
main = >
?
int iHJ@
int Gi@
void Gv@
i H Ti@
v H i@
rintf = 0Dn Gv H Nd1# Gv>@
IIIIIIIIII+RROR
i H v@
rintf = 0Dn Gi H Nd1# Gi>@
E
This rogram given an error in the first rintf
statement starting .not an allo!ed tye/ $ecause no
tye is associated !ith a void ointer. The void
ointer can store the address of a varia$le of any tye.
7ut !hile using the void ointer# the right tye has to
$e secified through tye casting. The right version of
this rogram is as follo!s.
Xinclude Astdio.hQ
main = >
?
int iHJ@
int Gi@
void Gv@
i H Ti@
v H i@
rintf = 0Dn GvH Nd1# G= =int G> v> >@
i H v@
rintf = 0Dn Gi H Nd1# Gi>@
E
Outut
Gv H J
Gi H J
The redefined constant NU88# !hich is
defined $y several standard header files# including
Astdio.hQ# Astdio.hQ# and Astring.hQ can $e assigned.
int G@
H NU88@
It is also ossi$le to refer to the null ointer $y
using a constant B $y simly !riting
int Gi H B@
In fact# NU88 is a rerocessor macro that
tyically has the value# or relacement te't# B.
The only values that can $e assigned to ointers
aart from B are the value of other ointer s of the
same tye. "o!ever# one of the thing that :ames C a
useful relacement for assem$ly language is that it
allo!s one to do the sort things that most other
languages revent. Try this.
int Gi@
i H =int G>K@
Gi H o'FF@
What does that doO The ointer has $een
initiali-ed to the value of K =notice the cast to turn an
integer K into a ointer>. This is a highly machine %
secific oeration# and the $it attern that ends u in
the ointers is *uite ossi$ly nothing li:e the machine
the machine reresentation of K. ,fter the
initiali-ation# a he'adecimal FF is !ritten into
!herever the ointer is ointing. The int at location K
has had B'FF !ritten into it % su$Vect to !hatever
.location K/ means on this articular machine.
It may or not ma:e sense to do that sort of
thing@ C gives you the o!er to e'ress it# it is u to
you to get it right. ,s al!ays# it is ossi$le to do
things li:e this $y accident# too# and to $e very
surrised $y the results.
,ddition Or Su$traction !ith Integers
In a closely related iece of synta'# a .C/
$et!een a ointer and an integer does the same offset
comutation as e'lained earlier# $ut leaves the result
as a ointer. The s*uare $rac:et synta' given the nth
element !hile the .C/ synta' gives a ointer to the nth
element. So the e'ression =arrC5> is a ointer to the
integer arr [5\. =arr C5> is of tye =int G> !hile arra [5\
is of tye int. The t!o e'ression only differ in
!hether the ointer is dereferenced or not. So the
e'ression =arr C5> is e*uivalent to the e'ression =T
=arr [5\ > >. In fact those t!o ro$a$ly comile to
e'actly the same code. They $oth reresent a ointer
to the element at inde' 5. ,ny [\ e'ression can $e
!ritten !ith the C synta' instead. It Vust needs the
ointer dereference to $e added in. So arr [5\ is
e*uivalent to G=arr C 5>. For most urose# the [\
synta' is the easiest to use and the most reada$le as
!ell. +very once in a !hile the C is convenient if one
needs a ointer to the element instead of the element
itself.
Therefore# e'ressions can add 3or su$tract#
!hich is e*uivalent to adding negative values> integral
values to the value of a ointer to any o$Vect tye. The
result has the tye of the ointer and if n is added#
then the result oints n array elements a!ay from the
ointer. The most common use is reeatedly to add 2
to a ointer to ste it from the start to the end of an
array# $ut addition or su$traction of values other than
2 is ossi$le. Consider the follo!ing t!o versions of
same rogram.
+'amle R.
Xinclude Astdio.hQ
int main =void>
?
int a[\ H ? 2B# 24# K# P# 4E@
int i@
int sum H B@
for 3iHB@ iAJ@ iCC>
?
sum CHa [i\@
E
rintf = 0Nd Dn1# sum>@
return B@
E
Note that if the ointer resulting from the
addition oints in front of the array or ast the non(
e'istent element Vust after the last element of the
array# then it results in overflo! or underflo! and the
result is undefined.
This is a tyical string % rocessing function.
)ointer arithmetic and dereferencing are used to
search for various characters or atterns. Often a
character ointer is used to march along a string !hile
arsing it or interreting it in some !ay.
Declaration and initiali-ations
char s2 [ \ H 0India is a $eautiful
country1@
s4 [ \ H 0 C is sea1@
+'ression Malue
strlen 3a2> 4R
strlen =s4 C J
tatements What
gets rinted
rintf =0Ns1# s2 C2B>@ $eautiful
country
strcy =s2 C 2B# s4 H R>
strcat =s2# 0sZ1>@
rintf =0Ns1# s2>@ India is a
$eautiful country

If is a ointer to an element in an array# then
=C2> oints to the ne't element in the array. The
statements CC can $e used to ste a ointer over the
elements in array. The rogram in +'amle R can $e
re!ritten as follo!s.
Xinclude Astdio.hQ
int main =void>
?
int a [\ H ?2B# 24# K# P# 4E@
int i@
int sum HB@
int G@
H a@
for =iHB@ iAJ@ iCC>
?
sum CH G@
CC@
E
rintf = 0NdDn1# sum>@
return B@
E
Similarly# since CC and CC are $oth
e*uivalent to H C 2# incrementing a ointer using
the unary CC oerator# either re(or ost(# increments
the address it stores $y the amount si-eof =tye> !here
.tye/ is the tye of the o$Vect ointed to =i.e.# 6 for an
integer>.
+'amle 3 sho!s that ointers may $e
incremented and decremented. In either case# if the
original oints to an o$Vect of a secific tye# the ne!
ointer oints to the ne't or the revious o$Vect of the
same tye. That is# ointers are incremented or
decremented in stes of the o$Vect si-e that the ointer
oints to. Thus# it is ossi$le to traverse an array
starting from a ointer to any element in the array.
Consider the follo!ing rogram.
+'amle 3
Xinclude Astdio.hQ
Xdefine N J
main = >
?
float arr [N\# Gtr@
int Gitr# a[N\# i@
FG initiali-e GF
for =i H B@ iAN@ iCC>
?
arr[i\ H B.5@
a[i\ H 2@
E
FGinitiali-e tr to oint to element arr[5\ GF
)tr H Tarr[5\@
Gtr H2.@ FGarr[5\ H2. GF
G=tr % 2> H .3@ FG arr[4\ H .3 GF
G=tr C2> H 2.2@ FG arr[6\ H 2.2 GF
F G initiali-e itr in the same !ay GF
Itr H Ta [5\@
Gitr H B@
G=itr % 2> H (2@
G=itr C 2> H4@
for =i H B@ iAN@ iCC>
?
rintf = 0arr[Nd\ H Nf1# I# G=arr C2> >@
rintf = 0a [Nd\ H NdDn1# i# a[i\>@
E
E
The rogram is straightfor!ard. It declares a
float array of si-e J# and an integer array of the same
si-e. The float array elements are all initiali-ed to B.5#
and the integer array elements to 2. The rogram also
declares t!o ointer varia$les# one a float ointer and
the other an integer. +ach ointer varia$le is
initiali-ed to oint to the array element !ith inde' 5@
for e'amle# tr is initiali-ed to oint to the float array
element# arr [5\. Therefore# tr % 2oits to arr [4\# and
tr C2 oints to arr[6\. The value of Gtr is then
modified# as is the value of G=tr % 2> and G=tr C2>.
Similar changes are made in the integer array. Finally#
the arrays are rinted. "ere is the outut of the
rogram.
arr [B\ H B.5BBBBB a [B\ H 2
arr [2\ H B.5BBBBB a [2\ H 2
arr [4\ H B.3BBBBB a [4\ H (2
arr [5\ H 2.BBBBBB a [5\ H B
arr [6\ H 2.2BBBBB a [6\ H 4
Consider the follo!ing rogram.
int $[\ H ?2B# 4B# 5B# 6B# JB E@
int i# G@
HT$ [6\ % 6@
for =iHB@ AJ@ CCi>
rintf =0Nd1# G>@
CC@
E
The e'ression T$ [6\ gives the address of $
[6\. 8et the address of $ [6\ $e KJJ6B. Then the
e'ression may give either KJJ5K or KJJ54
=considering a 2K($it machine>. To e'lain this#
consider the follo!ing statements assuming the
revious array.
int G@
H T$ [6\
H % 6@
The statement (6 gives the address of KJJ54 as
(6 evaluates as (6G si-eof =int > i.e.# KJJ6B % R
=considering a 2K($it machine>. That is# is ointing
to the address of $ [B\ or T$ [B\. The rest of the code
is e'ecuted as usual.
Consider the follo!ing rogram !here the
elements of the array a are initiali-ed# and then all
elements in array a are coied into $# so that a and $
are identical
+'amle 2B.
Xdefine &,] 2B
void main = >
?
int a [&,]\@
int $ [&,]\@
int i@
for =iHB@ iA&,]@ iCC>
a [i\ H I@
$ H a@
E
If it is comiled# there !ill $e an error. ,rrays
in C are unusual in that varia$le a and $ are not#
technically# arrays themselves $ut ermanent ointers
to arrays. They hold the address of the actual arrays#
$ut since they are ermanent ointers# their addresses
cannot $e changed. The statement $Ha@ therefore# does
not !or:.
To coy array a into another array $# something
li:e the follo!ing has to $e entered.
for =iHB@ iA&,]@ iCC>
a[i\ H $ [i\@
Or# to ut is more succinctly#
for =iHB@ iA&,]@ a[i\ H $[i\# iCC>@
In the statement CC@ if is ointing to an
array# the comiler :no!n that oints to an integer.
So this statement increments $y the aroriate
num$er of $ytes to move it to the ne't element of the
array. The array a can $e coied into $ using ointers
as !ell. The follo!ing code can relace =for iHB@
iA&,]@ a[i\ H$[i\# iCC>@
Ha@
*H$@
for =iHB@ iA&,]@ iCC>
?
G* H G@
* CC@
CC@
E
This code can $e a$$reviated as follo!s.
Ha@
*H$@
for =iHB@ iA&,]@ iCC>
G*CC H GCC@
Further a$$reviation leads to
for =Ha# *H$# iHB@ iA&,]@ G*CC H GC
C# iCC>@
It is imortant to note that the unary oerators C
C and ( ( have the same riority as G. ,ll unary
oerators $ind form right to left. Therefore# CC G is
e*uivalent to CC =G>@
Notice the difference.
=Gi>CC@ +*uivalent@
int tem@
=tem H Gi# Gi H Gi C 2#
tem>
GiCC@ e*uivalent@
G =iCCB@
intG tem@
=tem H i# i H i C 2#
Gtem>
Since G and CC have the same recedence and
associate from right to left# this is e*uivalent to G =iC
C>@ the value of iCC is i# so this ointer !ill $e
dereferenced. ,fter that the ointer i is incremented
$y 2. 8i:e al!ays# it is recommended to use
arentheses = > in order to avoid une'ected results.
Since CC and ( ( are either refi' or ostfi' oerators#
other com$inations of Gand CC and ( ( occur# although
less fre*uently. For e'amle#
G( (
decrements $efore fetching the varia$le that
ointer to. +'amle 22 !ill clear these facts.
+'amle 22;
Xinclude Astdio.hQ
int main= >
?
int , [\ H ?2B# 4B# 5B# 6B# JBE@
int G# i@
H ,@
rintf = 0G ; NiDnDn1# G>@
i H G=CC>@
rintf = 0i is ; Ni Dn1# i>@
rintf =0G is ; Ni Dn Dn1# G>@
i H =G>CC@
rintf = 0i is ; NiDn1# i>@
rintf = 0G is ; NiDnDn1# G>@
i H G=CC>
rintf =0 i is ; Ni Dn1# i>@
rintf = 0G is ; NiDnDn1# G>@
i H CC =G>@
rintf = 0i is ; NiDn1# i>@
rintf = 0G is ; NiDnDn1# G>@
return B@
E
Outut;
G ; 2B
i is ; 2B
G is ; 4B
i is ; 4B
G is ; 42
i is ; 5B
G is ; 5B
i is ; 52
G is ; 52
,n integer can also $e su$tracted. This is
illustrated in +'amle 24.
+'amle 24;
Xinclude Astdio.hQ
int main = >
?
int a [\ H ?2B# 4B# 5B# 6B# JBE@
int I# G@
HaC6@
for =iH6@ iQHB@ i((>
rintf = 0NdDn1# G=(i> >@
return B@
E
Outut;
2B
4B
5B
6B
JB
The a$ove code may $e relaced $y the
follo!ing code.
Xinclude Astdio.hQ
int main =void>
?
int a[\ H ?2B# 24# K# P# 4E@
int i# G@
HaC6@
for =iH6@ iQHB@ i((>
rintf =0NdDn1# [(i\>@
return B@
E
) [(i\ is e*uivalent to G =(i>. Initially oints to
the last element. ,t the $eginning iH6# (I evaluates (
2Gsi-eof =int> H (2K =int a 54($it machine> or H (
R3int a 2K($it machine>. No! (I gives the address of
the first element of array. [(i\# !hich is e*uivalent to#
G =(i># rints the first element of the array. Then iH5#
so [(i\ rints the second element and so on. 8oo: at
fig 25.3.
a[B\ a[2\
a[4\ a[5\ a[6\
2
B
4
B
5
B
6
B
J
B
KJBB6 KJBBK
KJBBR KJB2B KJB24
Fig 25.3 Su$crited Notation Malue and
,ddress of +lements of an ,rray
"ere a 2K($it machine is assumed. Initially
HKJB24# iH6. Therefore#
)[(i\HG =(i> H value at address (I
Gsi-eof =int> % value at address =(R>
H value at address3KJB24(R> H value at
address KJBB6 H 2B.
When iH5# [(i\ HG 3(K> HG 3KJB24(K> H value
at address KJBB6 H 4B and so on. If i iterates from B to
6# then this code !ill rint the elements of array in
reverse order.
+'amle 25;
Xinclude Astdio.hQ
int main = void>
?
int a[\ H ?2B# 24# K# P# 4E@
int i# G@
HaC6@
for =iHB@ iAJ@ iCC>
rintf = 0NdDn1# [(2\>@
return B@
E
Outut
JB
6B
5B
4B
2B
The reason is very simle. ,ly the same
calculation as $efore. The study of string is useful to
further tie in the relationshi $et!een ointers and
array. This discussion is also alica$le to strigna as
string are nothing $ut an array of characters. Consider
the follo!ing rogram that uses a ointer to thift to
the ne't character of the string.
+'amle 26;
Xinclude Astdio.hQ
main = >
?
char a [2J\ H 0test string1@
char Ga@
a Ha@
!hile =Ga>
?
utchar =Ga>@
aCC@
E
)rintf =0Dn1>@
E
Outut
test string
The !hile loo is e*uivalent to !hile =Ga H H
.DB/>. &ore asects of ointers and string are
illustrated here $y studying versions of some useful
functions adated from the standard li$rary string.h.
The first function is strcy =t# s ># !hich coies the
string s to the string t. It !ould $e nice Vust to !rite t H
s $ut this coies the ointer# not the character. To coy
the characters# a loo is needed. The array version is
as follo!s.
+'amle2J;
Xinclude Astdio.hQ
void main= >
?
char a[JB\
void scoy =char G# char G>@
rintf = 0Dn +nter the string;1>@
gets =a>@
scoy =$#a>@
rintf = 0Dn Ns1# $>@
E
F G scoy ; coy s to t@ array su$scrit version GF
void scoy =char Gt# char Gs>
?
int i@
iHB@
!hile =s[i\ ZH .DB/>
?
t [i\ H s [i\@
iCC@
E
t[i\ H .DB/@
E
,n e*uivalent version of scoy = > is given an
follo!s.
vid scoy =char Gt# char Gs>
?
Int i@
iHB@
!hile = =t [i\ H s[i\> Z H .DB/>
iCC@
E
For contrast# here is a version of strcy !ith
ointers.
FG scoy; coy s to t@ ointer version GF
void scoy =char Gt# char Gs>
?
int i@
iHB@
!hile = =Gt H Gs> Z H .DB/>
?
sCC@
tCC@
E
E
7ecause arguments are assed $y value# scoy
can use the arameters $ and c. "ere they are
conveniently initiali-ed ointers# machining along the
arrays one character at a time# until the .DB/ that
terminates s has $een coied into t. +'erienced C
rogrammers !ould refer the follo!ing version.
FG scoy ; coy s to t@ ointer version 4 GF
void scoy =char Gs# char Gt>
?
While G= = tCC H GsCC> Z H .DB/>@
E
This moves the increment of s and t into the test
art of the loo. The value of GsCC is the character
that s ointed to $efore t !as incremented@ the ostfi'
CC does not change s until after this character has
$een fetched. In the same !ay# the character is stored
into the old t osition $efore the loo. The net effect is
that characters are coied from s to t# u and including
the terminating .DB/.
The strcy in the standard li$rary =Astdio.hQ>
returns the target string as its function value. It might
loo: li:e
char Gstrcoy =char Gdestination# char Gsource>
?
char G H destination@
!hile =Gsource Z H .DB/
?
GCC H GsourceCC@
E
G H .DB/@
return destination@
E
The follo!ing is the array su$scrit version of
the strlen li$rary function.
int strlen =char s[\>
?
int '@
'HB@
!hile =s['\ Z H .DB/>
'H'C2@
return ='>@
E
Using a ointer % $ased aroach# this function
can $e re!ritten as follo!s.
int strlen =char Gs>
?
int cHB@
!hile =Gs Z H .DB/>
?
cCC@
sCC@
E
return =c>@
E
This code can $e a$$reviated as follo!s.
int strlen =char Gs>
?
int cHB@
!hile =GsCC>
cCC@
return ='>@
E
No! e'amine strcm =s# t># !hich
comares the character strings s and t# and returns
negative# -ero# or ositive if s is le'icograhically less
than# e*ual to# or greater than t. The value is o$tained
$y su$tracting the characters at the first osition
!here s and t disagree.
int stcm 3char Rs# char Gt>
?
int i@
for =>i H B@ s[i\ H H t[i\@ iCC>
if =s [i\ H H .DB/>
return B@
return s[i\ % t[i\@
E
The ointer version of stcm
int stcm =char Gs# char Gt>
?
for = @ Gs H H Gt@ sCC# tCCB
if =Gs H H .DB/>
return B@
return Gs ( Gt@
E
To illustrate string rocessing# a function is
!ritten that counts the num$er of !ords in a string. It
is assumed that !ords in the string are searated $y
!hite sace. "ere function !ill use the macro issace
= B# !hich is defined in the standard header file cte.h.
This macro is used to test !hether a character is a
$lan:# ta$# ne!# line# or some other !hite(sace
character. If the argument is a !hite(sace character#
then a non(-ero =true> value is returned@ other!ise#
-ero =false> is returned.
+'amle 2K;
FG count the num$er of !ords in a string. GF
Xinclude Astdio.hQ
Xinclude Actye.hQ
int !ordIcnt =char Rs>
?
int cnt H B@
!hile =Gs Z H .DB/> ?
!hile =issace =Gs> > FGs:i !hite
sace GF
CC s@
if =Gs Z H .DB/> ? FG found a !ord
GF
CC cnt@
!hile =Zissace =Gs> TT Gs Z H .DB/> FG
s:i the !ord GF
CCs@
E
E
return cnt@
E
main = >
?
char str [RB\
rintf = 0Dn +NT+R T"+
S+NT++NC+1>@
scanf =0N [0Dn\1# str>@
rintf = 0Dn NO OF WORDS H N d1#
!ordIent =str> >@
E
,s an e'amle# let us try to !rite a function that
loo:s for one string !ithin another# returning a ointer
to the string if it can# or a null ointer if it cannot.
"ere is the function =using the o$vious $rute(force
algorithm>; at every character of the inut string# the
code chec:s for a match to the attern string.
+'amle 2P;
Xinclude Astdio.hQ
Xinclude Astdio.hQ
void main = >
?
char a [JB\# $[5\@
char Gmyststr the string; 0>@
gets =a>@
rintf = 0Dn +nter the su$string to
search;1>@
gets =$>@
if =myststr =a#$> H HNU88>
rintf =0NOT FOUNDDn1>@
else
rintf = 0FOUNDDn1>@
E
char Gmystrtr =char Ginut# char Gat>
?
char Gstart# T2# G4@
for =start H Tinut [B\@ Gstart ZH
.DBD startCC>
?
FG for each osition in inut string
S.GF
2 H at@ FG reare to chec: for
attern string there GF
4 H start@
!hile =G2 Z H .DB/>
?
if =G2 Z H G4> FG characters
differ GF
$rea:@
2CC@
4CC@
E
if =G2 H H .DB/> FG match foundGF
return start@
E
return NU88@
E
The start ointer stes over each character
osition in the inut string. ,t each character# the
inner loo chec:s for a match there$y using 2 to ste
over the attern string =at> and 4 ste over the inut
string =starting at start>. We comare successive
characters until either !e reach the end of the attern
string =G2 H H .DB/># or !e find t!o characters !hich
differ. When !e are done !ith the inner loo# if !e
have reached the end of the attern string. =G2H H
.DB/># it means that all receding characters matched
and !e found a comete match for the attern starting
at start# so !e return start. Other!ise# !e go around
the outer loo again# to try another starting osition. If
!e run out of those =if Gstart H H .DB/># !ithout finding
a match# !e return a null ointer. Notice that the
function is declared as returning =and does in fact
return> a ointer( to( char.
mystrstr =or its standard li$rary counterart
strstr> can $e used to determine !hether one string
contains another. "ence# the code is
if =mystrstr3a#$> H H NU88>
rintf = 0NOT FOUNDDn1>@
else rintf = 0FOUND Dn1>@
In general# C does not initiali-e ointers to
NU88# and it never tests ointers to see if they are
null $efore using them# an e'cellent convention to use
is to set it to a null ointer !hen it does not oint to
any valid location# and test to see if it is a null ointer
$efore using it. 7ut an e'licit code must $e used to
set it to NU88# and to test it against NU88. =In other
!ords# Vust setting an unused ointer varia$le to
NU88 does not guarantee safely@ one also has to
chec: for the null value $efore using the ointer.> on
the other hand# if it is :no!n that a articular ointer
varia$le is al!ays valid# it does not have to insert a
aranoid test against NU88 using it.
SU7TR,CTION OF )OINT+RS
,s has $een seen# an integer can $e added to a
ointer to get a ne! ointer# ointing some!here
$eyond the original =as long as it is in the same array>.
For e'amle# one might !rite
4 H 2 C 5@
,lying a little alge$ra#
4 % 2 H 5

"ere $oth 2 and 4 are ointers ointing to the
elements of the same array. From this it can $e
concluded that the t!o ointers are su$tracted# as long
as they oint into the same array. The result is the
num$er of elements searating them. One may also
as: =again# as long as they oint into the same array>
!hether one ointer is greater or less than another@
one ointer is .greater than/ another if it oints $eyond
!here the other one oints.
Therefore# ointer su$traction is also valid; if
and * elements of the same array# and A*# then *(C2
is the num$er of elements from to *# inclusive of *.
Therefore# *( returns the num$er of elements
$et!een * and . The follo!ing code illustrates this.
Xinclude Astdio.hQ
main = >
?
dou$le a [4\# G# R*@
Ha@
*HC2@
rintf = 0NdDn1# * % >@
E
Outut
To rint the num$er of $ytes resulting from *(#
each ointer may $e tyecast.
Xinclude Astdio.hQ
main = >
?
dou$le a[4\# G*# G@
Ha@
*HC2@
rintf = 0NdDn1# =int> *(=int> >@
E
Outut
R
It has $een seen that t!o ointers to comati$le
tyes may $e su$tracted. ,ctually# the result is stored
in the varia$le tye trdiffIt# !hich is defined in the
header file Astdio.hQ. 7oth ointers must into the
same array# or one ast the end of the array# other!ise
the $ehavior is undefined. The value of the result is
the num$er of array elements that searate the t!o
ointers.
+'amle 2R;
Xinclude Astdio.hQ
void main = >
?
int ' [2BB\@
int Gi# Gci H T' [33\@ FG ci oints to the last
element of ' GF
i H '@
if = =ci % i> Z H33>
rintf =0+rror Dn1>@
i H ci@
iCC@ FG increment ast end of ' GF
if = = i % ci> Z H 2>
rintf =0+rror Dn1>@
E
The e'ecution of the a$ove rogram rints
nothing. Consider another version of the standard
li$rary function strlen.
int strlen =char Gs>
?
char G H s@
!hile =G ZH/DB/>
CC@
return % s@
E
In its declaration# is initiali-ed to s# that is# to
oint to the first character of the string. In the !hile
loo# each character in turn is e'amined until the .DB/
at the end is seen. 7ecause oints to characters# CC
advances to the ne't character each time# and (s
gives the num$er of character advanced over# that is#
the string length. The num$er of characters in the
string could $e too large to store in an int. The header
Astdio.hQ defines a varia$le tye trdiffIt that is large
enough to hold the signed difference of t!o ointer
values. If !e !ere $eing cautious# ho!ever# !e !ould
use si-eIt for the return value of strlen to match the
standard li$rary version. Si-eIt is the unsigned integer
tye returned $y the si-eof oerator.
Note The CH and (H oerators can involve
ointers as long as the left % hand side is a ointer to
an o$Vect and the right % hand side is an integral
e'ression.
CO&),RIN9 )OINT+RS
C allo!s ointers to $e comared !ith
each other. If t!o ointers comare e*ual to each
other# then they oint to the same thing# !hether it is
an o$Vect or the non(e'istent element of the end of an
array=see arithmetic a$ove>. If t!o ointers oint to
the same thing# then they comare e*ual to each other.
The relational oeratorsQ# AH# and so on give the
result that !ould $e e'ected if the ointers oint to
the same array; if one ointer comares less than
another# then it oints nearer to the front of the array.
Consider the follo!ing rogram.
+'amle 23;
Xinclude Astdio.hQ
int main = >
?
int a [\ H ?2B# 4B# 5B# 6B# JBE@
int i# G@
for =Ha@ #HaC6@ CC>
rintf = 0NdDn1# G>@
return B@
E
Outut
2B
4B
5B
6B
JB
"ere each time is comared !ith the address
of the array.
One common use of ointer comarisons is for
coying arrays ointers. "ere is a code fragment
!hich coies 2B elements from array2 to array4# using
ointers. It uses an end ointer# e# to :ee trac: of
!hen it should sto coying.
int array2 [2B\# array4 [2B\@
int Gi2# Gi4 H Tarray4 [B\@
int Ge H Tarray2 [2B\@
for =i2 H Tarray[B\@ i2 Ae@ i2CC>
Gi4CC H Gi2@
,s mentioned earlier# there is no element array4
[2B\# $ut it is legal to comare a ointer to this =non(
e'istent> element as long as it is only used in ointer
comarisons li:e this =that is# it is legal as long as no
attemt is made to fetch or store the value that it
oints to>.
The follo!ing rogram !ill rint the line in
reverse order. The rogram uses t!o ointers ointing
to elements of the same array# illustrating the ointer
comarison.
+'amle 4B;
Xinclude Astdio.hQ
Xincldue Astring.hQ
main = >
?
Char a[JB\@
void reverse =char G>@
rintf = 0Dn +nter the string;1>@
gets =a>@
reverse =a>@
rintf = 0Dn ,fter reversing the string
is ; Dn1>@
uts =a>@
E
void reverse =char Gstring>
?
char G2 H string@ FG left ointer GF
char Gr H Tstring [strlen =string> (2\@ FG
right ointer GF
char tm@
!hile =2 Ar>
?
tm H Gl@
Gl H Gr@
Gr H tm@
lCC@
r((@
E
E
Outut;
+nter the string ; manas
,fter reversing the string is;
sanam
, null ointer constant can $e assigned to a
ointer@ that ointer !ill then comare e*ual to the
null ointer constant. , null ointer constant or a null
ointer !ill not comare e*ual to a ointer that
ointer to anything !hich actually e'ists. This has
already $een discussed and illustrated earlier. ,
ointer arithmetic summary is given in Ta$le 25.6
Ta$le 25.6 )ointer ,rithmetic Summary
Oeration Condition +'amle
Result
,ssignment )ointers must int G# G*
oints to !hatever
of same . . .
* oints to
H *@
,ddition of an int :# G@
,ddress of the :th o$Vect after the
integer . . .
one oints to
C :
Su$traction of int :# G@
,ddress of the :th o$Vect $efore the
integer . . .
one oints to
% :
Comarison of )ointers ointing int G#
G*@ Returns TRU+ =2> if * oints to an
ointers to the mem$ers . . .
earlier
of the same array * A
element of the array than does. Return
tye is int
Su$traction of )ointers to mem( int G#
G*@ Num$er of elements
ointers $ers of the array . . .
$et!een T *@
and
* A ( *
)OINT+R TO )OINT+R
So far in the discussion ointer have $een
ointing directly to data. C allo!s the use of ointers
that oint to ointers# and these# in turn# oint to data.
For ointers to do that# !e only need to add an
asteris: =G> for each level of reference. Consider the
follo!ing declaration.
int aHJ@
int G@ ointer to an integer
int GG*@ ointer to a ointer to an integer
HTa@
*HT@
To refer to a using ointer # dereference it once#
that is# G.
To refer to a using *# dereference it t!ice $ecause
there are t!o levels of indirection involved.
If * is dereferenced once# actually is referenced
!hich is a ointer to an integer. It may $e
reresented diagrammatically as follo!s.
*
J
So# G and GG* rint J if they are rinted !ith a
rintf statement.
Xinclude Astdio.hQ
void main = >
?
int aHJ@
int G# GG*@
HTa@
*HT@
rintf =0Dn GHNd1# G>@
rintf = 0Dn GG* H Nd1# GG*>@
E
Outut;
GHJ
GG*HJ
a
*
J KJJ6B
KJJJB
KJJ6B KJJJB
KJJJR
In the receding figure# the cells contain the
content of the varia$le and its location is given $elo!
the cells. In this e'amle# varia$le *# can $e descri$ed
in three different !ays@ each one of them !ould
corresond to a different value.
* is a varia$le of tye =int GG> !ith a value of
KJJJB
G * is a varia$le of tye =int G> !ith a value of
KJJ6B
GG * is a varia$le of tye =int> !ith a value of J
Consider the follo!ing declarations.
int a@ FGointer to integer GF
int G@ FGointer to ointer to integer GF
int GG*@ FGointer to ointer to integer GF
a H J@ FG assign value to aGF
a H Ta@ FGaddress of a is stored in a GF
*a H Ta @ FG address of a is stored in *a
GF
&emory icture
Maria$le ,ddress Malue
a KJJ6B J
KJJJB KJJ6B
* KJJJR KJJJB
Consider introducing the follo!ing e'ression
in the receding memory icture.
G H P@
Maria$le ,ddress
Malue
a KJJ6B
J P
KJJJB
KJJ6B
* KJJJR
KJJJB
,s is the address of int a# G changes the
value of a to P. No! consider introducing the
follo!ing e'ression in the same e'amle.
GG* H 2B@
Maria$le ,ddress
Malue
a KJJ6B
J P 2B
KJJJB
KJJ6B
* KJJJB
KJJJB
No! GG* also refers to int a@ it changes value of
a to 2B. We can also change the value of using *
$ecause * oints to . Consider the follo!ing ta$le.
Maria$le ,ddress
Malue
a KJJ6B
2B
KJJJB
KJJ6B
* KJJJR
KJJJB
$ KJJ24
No! G* H T$ modifies the lace !here * is
ointing i.e.# . So !e get the follo!ing ta$le.
Maria$le ,ddress
Malue
a KJJ6B 2B
KJJJB KJJ24
* KJJJR KJJJB
$ KJJ24
The follo!ing rogram e'lores ho! ointer to
a ointer to an integer and ointer to ointer to ointer
can $e used to read the value of the same varia$le.
+'amle 42;
Xinclude Astdio.hQ
main = >
?
int a@
int G@
int GGd@
int GGGt@
HTa@
dHT@
tHTd@
rintf = 0Dn +NT+R T"+ M,RI,78+ OF
a1>@
scanf = 0Nd1# Ta>@
rintf = 0Dn aHNd1# a>@
rintf = 0Dn +NT+R T"+ M,RI,78+ OF
a1>@
scanf =0Nd1# >@
rintf = 0Dn aHNd1# a>@
rintf = 0Dn +NT+R T"+ M,RI,78+ OF
a1>@
scanf = 0Nd1# Gd>@
rintf = 0Dn aHNd1# a>@
rintf = 0Dn +NT+R T"+ M,RI,78+ OF
a1>@
scanf = 0Nd1# GGt>@
rintf = 0Dn aHNd1# a>@
E
Outut
+NT+R T"+ M,8U+ OF a J
a H J
+NT+R T"+ M,8U+ OF a 2B
a H 2B
+NT+R T"+ M,8U+ OF a 4B
a H 4B
+NT+R T"+ M,8U+ OF a 4J
a H 5J
No! the *uestion is ho! many levels of
indirection can $e used in a single declarationO
The ans!er is at least 24.
int i H B
int GiB2 H T i@
int GGiB4 H T iB2@
int GGGiB5 H T io4@
int GGGGiB6 H T iB5@
int GGGGiBJ H T iB6@
int GGGGGiBK H T iBJ@
int GGGGGGiBP H T iBK@
int GGGGGGGiBR H T iBP@
int GGGGGGGGiB3 H T iBR@
int GGGGGGGGGi2B H T iB3@
int GGGGGGGGGGi22 H T i2B@
int GGGGGGGGGGGi24 H T i22@
GGGGGGGGGGGGi24 H 2@ FG i H 2 GF
,ccording to ,NSI C standard# all comilers
must handle at least 24 levels. ,ctually# it deends on
the comiler. Some comilers might suort more.
,RR,L ,ND )OINT+RS
,n array of ointers can $e declared very
easily. It is done thus.
int G) [2B\@
This declares an array of 2B ointers#
each of !hich oints to an integer. The first ointer is
called [2B\# the second is [2\# and so on u to [3\.
These start off as uninitiali-ed % they oints to some
un:no!n oint in memory. We could ma:e them oint
to integer varia$les in memory thus.
intG [2B\
int a H 2B# $ H 4B# c H 5B#
[B\ H Ta@
[2\ H T$@
[4\ H Tc@

2B 4B 5B

It can $e seen from the diagram that there is no
!ay of :no!ing in advance !here the comiler is
doing to ut these num$ers in memory. They may not
even $e stored in order. "o!ever# as long as !e have
ointers to them# !e can still :ee trac: of them.
The o$vious thing to do is to sort the num$ers
in memory in memory# not $y moving the num$ers
themselves around $ut $y altering the order of the
ointers to them.
+'amle 44;
Xinclude Astdio.hQ
FG the array of ointer is declared here so that
the function GF
FG dislay can access them GF
int G [2B\@
void silay= >
? int I@
FG Dislaying !hat each ointer in the array
ointer to H. GF
for =i H B@ iA2B@ iCC>
rintf = 0Nd Dn1# G [i\>@
E
void main= >
? int a H 6K# $ H 2B3# c H J2# d H KK# eHR4# f H
6P# gH 6B# h H 5K# : H PB# 2 H P3@
intG tem@
intG tem@
int i# V@
[B\ HTa@
[2\ H T$@
[4\ H Tc@
[5\ H Td@
[6\ H Te@
[J\ H Tf@
[K\ H Tg@
[P\ H Th@
[R\ H T:@
[3\ H Tl@
Dislay = >@ FG Dislaying the values $efore
sorting GF
for =i H B@ iA2B@ iCC>
for =V H B@ VA3@ VCC>
if =G [V\ Q G[VC2\>
? tem H [V\@
) [V\ H [V\@
) [VC2\ H tem@
E
Dislay= >@ FG Dislaying after sorting GF
E
This rogram is very clumsy. It can $e
re!ritten. In the follo!ing rogram# an array of
ointers contains the $ase address of three one(
dimensional arrays.
?
int a[\ H ?2# 4# 5# 6# JE@
int $[\ H ?2B# 4B# 5B# 6B# JBE@
int c[\ H ?2BB# 4BB# 5BB# 6BB# JBBE@
int Ga [5\ H ?a# $# cE@
int i@
for = i HB@ iA5@ CCi>
rintf =0Nd1# Ga[i\>@
E
In the for loo# rintf = B rints the values at the
addresses stored in a [B\# a [2\# and a [4\# !hich
are 2# 2B# and 2BB.
The a$ove for loo can also $e relaced $y the
follo!ing to get the same outut.
?
.
.
.
.
int G@ Ha@
for =iHB@ iA5@ CCi>
?
rintf = 0Nd1# GG>@
CC@
E
E
,nother illustration is as follo!s.
main = >
?
int a[5\ [5\ H ?2# 4# 5# 6# J# K# P# R# 3E@
int Gtr [5\ H ?a[B\# a[2\# a[4\E@
int i@
for =iHB@ iA5@ CCi>
rintf =0Nd1# Gtr[i\>@
rintf = 0Dn1>@
for = i HB@ iA5@ CCi>
rintf = 0Nd1# Ga[i\>@
E
Outut
2 6 P
2 6 P
In the second for loo# the values of the $ase
address stored in the array a[\ are ointer# !hich are
again 2 6 P.
Rotate ,rray +'amle
)ointer arithmetic allo!s us to erform
oerations on the array !ithout actually moving the
data around. Instead# adVustments are made to
ointers. This is e'tremely useful for large data
structures and large systems !here system
erformance is critical.
In this e'amle# an array of five integers is
created. ,nother array of ointers to the integer is also
created to store the addresses of the elements of the
first array. The element addresses are stored in the
array of integer ointers in the order of n C 2@ n $eing
the inde' value sits in the original array and nC2 $eing
the inde' of the second array. ,fter the rotation# the
first reference address is aended to the end array of
ointers.
int array[J\ H ?2# 4# 5# 6# JE@ FG initiali-e array
of int values GF
int Garray [J\@ FG create an array of ointers to
int value GF
int Gointer H array@ FG store the ointer to the
first element of the array of int values GF
for =int iHB@ iA J@ iCC>
?
,rray4 [6\ H array@ FG aend the address
of first element to end of array of addresses GF
The outut of this first rotation vould $e
,rray; ?2# 4# 5# 6# JE
Deference ,rray4; ?4# 5# 6# J# 2E
This first iteration rotates the array $y one !hile
initiali-ing the second array of ointers only.
Rotations after this first initiali-ation !ould $e done
solely to the array of ointers.
)ointer H array4 [B\@ FG store the value of the
first element of this GF
FG array of ointers to .int s
GF
for =int t H @ t A 6@ tCC>
?
,rray4[t\ H array4[tC2\@ FG Cycle through and
shift the GF
FG addresses to!ards
-ero GF
E
,rray [6\ H ointer@ FG aend the first address
to the end of GF
FG the array of ointer GF
Note +ven after t!o rotations# the original array
still has its values in the original order "o!ever# after
t!o rotations# the array of ointers is t!o stes ahead
of the original array. If the values of the first array
!ere dumed# they !ould $e in the order of ?2# 4# 5#
6# JE. If the ointers !ere dereferenced in the array of
ointers# the values !ould $e in the order of ?5# 6# J#
2# 4E.
,n array of character ointers that is ointed to
the string is declared as follo!s.
char Gnametr [&,]\@
The array# nametr[\# is an array of si-e &,]#
and each element of the array is a character ointer. It
is then ossi$le to assign character ointer values to
the elements of the array. For e'amle#
nametr [i\ H 0B'ford1@
The string 0B'ford1 is laced some!here in
memory $y the comiler and the ointer to the string
constant is then assigned to nametr [i\. It is also
ossi$le to assign the value of any string ointer to
nametr [i\. For e'amle# if s is a string# then it is
ossi$le to assign the ointer value s to nametr [i\.
nametr [i\ H s@
,gain# for e'amle#
char Gname [\ H ?0&anas1# 0)radi1# 0,ltaf1E@
FG Creates and initiali-es an array of 5 strings
name [B\ is &anas# name [2\ is )radi and
name[4\ is ,ltaf GF
7eginning are often confused a$out the
difference $et!een this e'amle and a
multidimensional array.
char name [5\ [2B\ H ?0&anas1#
0)radi1# 0,ltaf1E@
7oth of these !ill $ehave the same !ay in most
circumstances. The difference can only $e seen if !e
loo: at the memory locations.
name [B\ & a n a
s DB
name [2\ ) r a d
I DB
name [4\ , l t a
f DB

This figure sho!s the first declaration char
Gname [\@ name contains an array of three ointers to
char. The ointers to char are initiali-ed to oint to
locations !hich may $e any!here in memory
containing the strings 0&anas1# 0)radi1 and 0,ltaf1
3all correctly DB terminated>.
& a n a s DB O ) r a d i DB O , l t a f DB O O O O O O O O O
This reresents the second case % the DB
character terminate the strings. The O reresent
memory locations !hich are not initiali-ed. char Ga [\
reresents an array of ointers to char. This can $e
used to contain a num$er of strings.
8oo: at follo!ing rogram# !hich uses an array
of ointers.
+'amle 45;
char Grain$o![\ H ?0red1# 0orange1# 0yello!1#
0green1# 0$lue1# 0indigo1# 0violet1>@
main= >
?
int color@
for =color H B@ color AH K@ colorCC>
?
rintf = 0Ns1# raindo! [color\>@
E
rintf = 0Dn1>@
E
The outut of !hich is =not surrisingly>
red
orange
yello!
green
$lue
indigo
violet
The follo!ing rogram !ould clear the a$ove
facts.
+'amle46;
Xinclude Astdio.hQ
char Ggetday=int>@
void main= >
?
int iday @
char Gdayof!ee:@
rintf = 0+NT+R a num$er from 2 to P
for the day of the !ee:;1>@
scanf = 0Nd1# Tiday>@
dayof!ee:Hgetday=iday>@
if=dayof!ee: Z H NU88>
rintf = 0Dn Dn That day of the !ee: is
Ns1# dayof!ee:>@
else
rintf = 0Invalid entry for day Z1>@
E
char Ggetday =int iNo>
?
char Gday [P\@
days[B\ H 0Sunday1@
days[2\ H 0&onday1@
days[4\ H 0Tuesday1@
days[5\ H 0Wednesday1@
days[6\ H 0Thursday1@
days[J\ H 0Friday1@
days[K\ H 0Saturday1@
if =iNo QH2 T T iNoAHP>
return days [iNo(2\@
else
return NU88@
E
In general# an array of ointers can $e used to
oint to an array of data items# !ith each element of
the ointer array ointing to an element of the data
array. Data items can $e accessed either directly in the
data array# or indirectly $y dereferencing the elements
of the ointer array. The advantage of a ointer array
is that the ointers can $e reordered so that the
successive elements of the ointer array oint to data
items in a sorted order !ithout moving the data items.
Reordering ointers is relatively fast comared to
reordering large data items such as data records or
strings. This aroach saves a lot of item# !ith the
additional advantage that the data items remain
availa$le in the original order. 8et us see ho! such a
scheme might $e imlemented.
Sorting an array of strings re*uires s!aing
the strings that can re*uire coying a lot of data. For
the sa:e of efficiency# it is $etter to avoid actual
s!aing of data !henever a data item is large# such
as a string or an entire data$ase record. In addition#
arrays may $e needed in more than one order@ for
e'amle# an e'am scores array sorted $y ID num$ers
and $y !eighted scores@ or strings may $e needed in
$oth an unsorted from and a sorted form. In either of
these cases# either t!o coies of the data# each sorted
differently# must $e :et# or a more efficient !ay to
store the data structure must $e found. The solution is
to use ointers to elements of the array and s!a
ointers. Consider some e'amles.
int data2# data4# Gtr2# Gtr4# Gsava@
data2 H 2BB@ data4 H 4BB@
tr2 H Tdata2@ tr4 H Tdata4@
The values of the data can $e s!aed and the
s!aed values stored in data2 and data4. Or the
values of the ointers can $e e'changed.
save H tr2@
tr2 H tr4@
tr4 H save@
"ere# the values in data2 and data4 have not
changed@ $ut tr2 no! accesses data4 and tr4 access
data2. The ointer values have $een s!aed so they
oint to o$Vects in a different order. The same idea can
$e alied to strings.
char name2[\ H .B'ford/@
char name4 [\ H 0University1@
char G2# G4@
2 H name2@
4 H name4@
)ointer 2 and 4 oint to strings name2 and
name4. No! the ointer values can $e s!aed so
that 2 and 4 oint to name4 and name2#
resectively. 9iven an array of strings# the follo!ing
rogram uses ointers to order the strings in a sorted
form# leaving the array unchanged.
+'amle 4J@
Xinclude Astdio.hQ
Xinclude Astdio.hQ
Xinclude Astring.hQ
Xdefine CO8S JB
void sortI!ords =char Ga [\# int n>
?
int i# V@
char Gtem@
for =iHB@ iAn(2@CCi>
for =VHiC2@ VAn@CCV>
if =strcmi =a[i\# a [V\> QB>
?
tem Ha [i\@
a[i\Ha[V\@
a[V\ H tem@
E
E
main = >
?
char ! [2B\ [CO8S\@
char G!dtr [2B\@
int i@
for =iHB@ iA2B@ CCi>
?
gets =! [i\ >@
!dtr [i\ H ![i\@
E
rintf = 0Dn 7efore sorting the string are
SS..Dn1>@
for =iHB@ iA2B@ CCi>
uts =! [i\ >@
sortI!ords =!dtr# 2B>@
rintf = 0Dn ,fter sorting the strings are SS.
Dn1B@
for =iHB@ iA2B@ CCi>
uts =!dtr [i\ >@
E
Note When an array of ointers to strings is
used# the strings can $e initiali-ed at the oint !here
the array is declared# $ut the string entered $y the user
cannot $e received using
scanf= >. Consider the follo!ing rogram.
main = >
?
char Gname[J\@
int I@
for =iHB@ iAJ@ CCi>
?
rintf = 0Dn +NT+R N,&+1>@
scanf = 0N [ Dn1# name[i\>@
E
E
The rogram may not !or: $ecause !hen an
array is declared it contains gar$age value# and it
!ould $e !rong to send the gar$age value to scanf = >
as address !here the string received from the :ey!ord
should $e :et.
)OINT+R TO ,N ,RR,L
Suose !e have an array of unsigned long
values called v. We can declare a ointer to a simle
integer value and ma:e it oint to the array as is done
normally.
int v[J\ H ?2BB6# 44B2# 5BBB# 654# JBB?@
int G H v@
rintf = 0Nd Dn1# G>@
This iece of code dislay the num$er# !hich
the ointer oints# to that is the first num$er in the
array# namely 2BB6.
2BB6 v[B\
44B2 v[2\
5BBB v[4\
654 v[5\
JBB v[6\
C tends to treat arrays almost as through they
!ere ointers# !hich is !hy !e can set a ointer to an
array straight rather than using the address of oerator.
The instruction H v ma:es the ointer oint to the
address of the array. The num$er at this address is the
first element of the array@ so that is the value roduced
!hen !e access G.
CC gives some e'tra arithmetic instructions
that lets us use the ointer to the array more fle'i$ly.
CC
This instruction increases the ointer so that it
oints to the ne't element of the array. If it is follo!ed
$y the instruction rintf = 0Nd Dn1# G>@ then it !ould
dislay the num$er 44B2# !hich is the content of
element v[2\ =i.e.# the second element>.
Similarly# !e can use instructions such as
CHand (H to refer to different elements in the array.
2BB6 v [B\

44B2 v [2\
CH4@ 5BBB v [4\
654 v [5\
JBB v [6\
2BB6 v [B\

44B2 v[2\
((@ 5BBB v [4\
654 v [5\
JBB v [6\
Reference can $e made to the different array
elements !ithout having to alter the value of . We
have already used G to refer to the first element of
the array =or su$se*uent elements if has $een
udating !ith C H or ( H># $ut G=C2> can $e used to
refer to the ne't element after G# G=C4> to refer to
the one after that. +tc.
G =(2> 2BB6 v[(\

4BB2 v[2\
G =C2> 5BBB v[4\
G=C4> 654 v [5\
G=C5> JBB v [6\
No! it is time to turn to the ro$lem of the t!o(
dimensional array. ,s stated in the last chater# C
interrets a t!o(dimensional array as an array of one(
dimensional arrays. That $eing the case# the first
element of a t!o(dimensional array of integers is a
one(dimensional array integers. ,nd a ointer to a
t!o(dimensional array of integers must $e a ointer to
that data tye. One !ay of accomlishing this is
through the use of the :ey!ord .tyedef/. tyedef
assign a ne! name to a secified data tye. For
e'amle#
tyedef unsigned char $yte@
causes the name $yte to mean tye unsigned
char. "ence#
$yte $ [2B\@
!ould $e an array of unsigned characters.
Note that in the tyedef declaration# the !ord
$yte has relaced !hat !ould normally $e the name
of unsigned char. That is# the rule for using tyedef is
that the ne! name for the data tye is the name used
in the definition of the data tye. Thus in
Tyedef int ,rray [2B\@
,rray $ecause a data tye for an array of 2B
integers. That is# ,rray myIarr@ declares myIarr as an
array of 2B integers and ,rray arr4d [J\@ ma:es arr4d
an array of five arrays of 2B integer each.
,lso note that ,rray Gtr4arr@ ma:es tr4arr a
ointer to an array of 2B integers. 7ecause Gtr4arr
oints to the same tye as arr4d# assigning the address
of the t!o(dimensional array arr4d to tr4arr# the
ointer to a one(dimensional array of 2B integers is
acceta$le. That is# tr4arr H Tarr[B\@ or tr4arr H
arr4d@ are $oth correct.
Since the data tye !e use for our ointer is an
array of 2B integers !e !ould e'ect that
incrementing tr4arr $y one !ould change its value $y
2B Gsi-e of 3int># !hich it does. That is# si-eof
=Gtr4arr> is 4B. We can rove this $y !riting and
running a simle short rogram.
No!# !hile using tyedef ma:es things clearer
for the reader and easier on the rogrammer# it is not
really necessary. What !e need is a !ay of declaring
a ointer such as tr4arr !ithout using the tyedef
:ey!ord. It turns out that can $e done and that
int =Gtr4arr> [2B\@
is the roer declaration# i.e.# tr4arr here is a
ointer to an array of 2B integers Vust as it !as under
the declaration using the array tye. Note that this is
different from
int Gtr4arr [2B\@
!hich !ould ma:e tr4arr the name of an array
of 2B ointers to tye int.
The elements of a t!o(dimensional array can $e
rinted using a ointer to an array. The follo!ing
rogram illustrates this.
+'amle 4K;
main= >
?
int a[4\ [5\ H ? ?5# 6# JE# ?K# P# RE E@
int i@ int =Ga> [5\@
a H a@
for =iHB@ iA5@ CCi>
rintf = 0Nd Dt1# =Ga> [i\ >@
rintf = 0Dn1>@
aCC@
for =iHB@ iA5@ CCi>
rintf = 0Nd Dt1# =Ga> [i\>@
E
Outut
5 6 J
K P R
Ta$le 25.J summari-es the differences $et!een
array of ointer and ointer to an array.
Ta$le 25.J Difference $et!een an ,rray of
ointers and ointer to an ,rray
,rray of )ointer ointer to
an ,rray
Declaration
Declaration
dataItye GarrayIname[SIU+\@ data(tye
=GarrayIname> [SIU+\@
Si-e reresents the num$er of Si-e
reresents the num$er of columns
ro!s
The sace for columns may $e The
sace for ro!s may $e dynamically allotted
dynamically allotted

TWO DI&+NSION,8 ,RR,LS ,ND )OINT+RS
, t!o(dimensional array in C is treated as a
one(dimensional array !hose elements are one(
dimensional arrays =the ro!s>. For e'amle# a 6'5
array of T =!here .T/ is any data tye suorted $y C>
may $e declared $y .T a [6\ [5\/# and descri$ed $y the
follo!ing scheme.
a [B\ a[B\ [B\
a[B\ [2\ a[B\[4\
a [2\ a[2\ [B\
a[2\ [2\ a[2\[4\
a [4\ a[4\ [B\
a[4\ [2\ a[4\[4\
a [5\ a[5\[B\
a[5\[2\ a[5\[4\
Fig 25.2B 8ogical Reresentation of a
T!o(Dimensional ,rray
Figure 25.2B is the logical layout of a t!o(
dimensional array in memory $ut it does not give a
good icture of !hat is haening internally. The
.internal seudo(memory ma/ !or:s Vust to dislay
!hat the t!o(dimensional array loo:s li:e !ithin the
system# and can $e used to illustrate ho! it is actually
imlemented. Figure 25.22 is the grahical
reresentation of a t!o(dimensional array. Yee in
mind that this may not $e an accurate icture of !hat
is actually stored in memory# $ut it is accurate in terms
of the concet of a t!o(dimensional array.
The first thing to $e noticed is that there is still
a single ointer that is the name of the entire array# $ut
in this case it is a constant ointer to a constant
ointer. It oints to an array of ointers# each of !hich
oints some!here inside of the array. Finally# there is
the actual storage for the elements of the array.
,ccording to the definition of C# all elements of the
array must $e contiguous. The elements are dra!n in
the manner sho!n to emhasi-e this fact. One may
guess# and roerly so# that none of the ointers are
necessarily real ointers# $ut are someho! $ound u
in the addressing logic of the code# or they may $e
stored in registers. On the other hand# they could
actually all $e ointers if the imlementers decided to
do so. There are no assumtions made a$out the
underlying imlementation.
a[B\ [B\ a[B\[2\ a[B\[4\ a[2\[B\ a[2\[2\ a[2\[4\ a[4\
[B\ a[4\[2\ a[4\[4\ a[5\[B\ a[5\[2\ a[5\[4\
a[B\ a[2\ a[4\ a[5\
a
Fig 25.22 )hysical Reresentation of a T!o %
Dimensional ,rray
The address arithmetic for the a[n\ array of
ointers can $e used as done earlier# $ut it is a slightly
different case this time. The follo!ing formula is used
!ith si-e $eing the num$er of $ytes used to store a
ointer.
$yteIaddress H a C i G si-e
It !ill# ho!ever# $e correct to thin: of these
ointers e'isting some!here in memory concetually
in order to understand ho! a t!o(dimensional array is
stored in the comuter memory.
)ointer arithmetic can $e erformed !ithin each
ro! as is done !ith the one(dimensional array. The
constant ointer named a[B\ can $e considered to $e a
constant ointer to the first element in the first ro!
and the formula mentioned earlier can $e used for
ointer arithmetic Vust as if it !ere referring to a one(
dimensional array. Therefore# the follo!ing t!o
e'ressions#
G =a [B\ C 5>
and
a [B\ [5\
are identical as far as the comiler is concerned.
It is ossi$le to :ee the first array inde' set to
-ero and vary the second array inde' from -ero to
eleven# there$y accessing all t!elve elements $y
varying a single su$scrit. This is considered $ad
ractice in some rogramming circles and its use is
not encouraged# $ut it does illustrate ho! the elements
are actually stored.
for = iHB@ iA24@ iCC>
a[B\ [i\ H i@
This tric: is ossi$le $ecause C does not do
run(time range chec:ing of array su$scrits.
The follo!ing code is also valid for the t!o(
dimensional array a[6\ [5\ of integer tye
for =iHB@ iA24@ HHi>
scanf = 0Jd1# Ta[B\ [i\>@
Readers may have noticed that in C the
rightmost su$scrit of a t!o(dimensional array varies
faster than the leftmost =in fact# there are no
multidimensional arrays in C# $ut array of arrays>.
This fact suggests that the array is stored in a .ro!
maVor addressing/ format. So the array e*uation for
element .a [m\ [n\/ of tye T is
,ddress of =a [i\ [V\ H address of a [B\ [B\
C =i G n C V>
The array e*uation is imortant. In C# it is
hidden from the rogrammer@ the comiler
automatically comutes the necessary code !henever
an array reference is made. The o$vious advantage is
that the num$er of ro!s is not re*uired in the array
e*uation# the address of an element does not have to
$e comuted. That is !hy it is not al!ays necessary to
secify the first dimension in a function that is $eing
assed a t!o(dimensional array.
7ut for higher(dimensional arrays# the e*uation
gets more and more comlicated.
YTR tried to create a unified treatment of
arrays and ointers# one that !ould e'ose rather than
hide the array e*uation in the comiler/s code. It has
$een already discussed that a[i\ H G = aCi >. Therefore
a[i\ [V\ H G = a [i\ C V > H = G =a C i> > [V\ H G
=G =a C i > C V>
The array e*uation discussed a$ove is a
conse*uence of the aforesaid notations in the case of a
t!o(dimensional array. The follo!ing rogram
illustrates the facts Vust discussed.
+'amle 4P;
Xinclude Astdio.hQ
main = >
?
int a [4\ [5\ H ?2B# 4B# 5B# 5B# JB# KBE@
int i# V@
for =i H B@ iA4@ CCi>
?
rintf = 0Dn1>@
for = VHB@ VA5@ CCV>
rintf = 0NdDt1# G=G =aCi> CV> >@
E
E
Outut
2B 4B 5B
6B 6B KB
The same outut !ill result if the
statement
rintf = 0Nd Dt1# G =G =aCi> CV> >@
is relaced $y the follo!ing e*uivalent
statements.
rintf = 0Nd Dt1# G =a [i\ CV> >@
rintf = 0Nd Dt1# =G =aCi> > [V\ >@
rintf = 0Nd Dt1# G =Ta[B\ [B\
CiG5CV> >@
Thus# to evaluate either e'ression# a total of
five values must $e :no!n.
The address of the first element of the array# !hich
is returned $y the e'ression a# i.e.# the name of the
array
The si-e of the tye of the elements of the array# in
this case si-eof =int>
The second dimension of the array
The secific inde' value for the first dimension#
ro! in this case
The secific inde' value for the second dimension#
col in this case
),SSIN9 TWO DI&+NSION,8 ,RR,L TO ,
FUNCTION
The follo!ing are several alternative !ays in C
to handle an array assed to a function
They differ in the formal arameter. For
illustration# the follo!ing C statements are considered.
Xdefine &,]IROWS2B
Xdefine &,]ICO8S2B
int , [&,]IROWS\ [&,](CO8S\@
When data is accessed in our matri' using the
notation
, [i\ [V\
The location for this data is comuted using
T, [B\ [B\ C &,]ICO8S G iCV
Some interesting information a$out a t!o(
dimensional array , [2B\ [2B\ is as follo!s.
T, [B\ [B\ is the $ase address
, [B\ is the $ase address
, is the $ase address
T, [B\ is the $ase address
7ut these are not interchangea$le. For instance#
T, [B\ [B\ C2 oints to , [B\ [2\
, [B\ C 2 oints to , [B\ [2\
, C2 oints to , [2\ [B\ =,C2 is
the same as ,[2\ and oints to ro! l >
T, [B\ C 2 oints to , [2\ [B\
That is# C stores a matri' linearly in ro!s. The
values for the matri' elements are referenced as
, [i\ [V\ H = G =,Ci>> [V\ H G = = G =,Ci> >
CV> H G =, [i\ CV>
Therefore#
, [B\ [B\ H = G =,> > [B\ H G= =G,> CB> H
G=,[B\CB>
, [B\ [4\ H = G =,> > [4\ H G= =G,> C4 H
G=,[B\ C4>
, [2\ [4\ H = G =,C2> > [4\ H G = = G =,H2>
> C4> H G=,[2\C4>
T, [i\ [V\ H =,Ci> [V\ H G =,Ci> CV H , [i\
CV
So#
T, [B\ [B\ H =,> [B\ H G,CB H , [B\ CB
T, [B\ [4\ H =,> [4\ H G,C4 H , [4\ C4
T, [2\ [4\ H =,C2> [4\ H =G,C2> C4 H ,
[2\ C 4
The follo!ing rogram illustrates the a$ove
facts.
Xinclude Astdio.hQ
main = >
?
int , [4\ [5\ H ? ?2# 4# 5E# ?6# J# KE
E@
rintf = 0DnThe value of element ,
[B\ [B\ is Dn1>@
rintf = 0Nd Nd Nd Nd Dn1# , [B\
[B\# =G=,CB>> [B\# G==G,>CB># G=,[B\CB>>@
rintf = 0Dn The address of element
, [B\ [B\ is Dn1>@
rintf = 0N' N' N' N' Dn1# T,
[B\ [B\# =,> [B\# =G,CB># =,[B\CB>>@
E
Traditional method !hich uses array notation as
a formal arameter % an array !ith an emty first
dimension
Xinclude Astdio.hQ
main= >
?
int a[4\ [5\ H ?2B# 4B# 5B# 6B# JB# KBE@
void sho! =int [\ [5\>@
sho! =a>@
E
void sho! =int $ [\ [5\ >
?
int i# V@
for =iHB@ iA4@ CCi>
?
rintf = 0Dn1>@
for =VHB@ VA5@ CCV>
rintf = 0d Dt1# G =G =$Ci> C V > >@
E
E
)OINT+R TO ,N ,RR,L ,S , FOR&,8
),R,&+T+R
"ere the second dimension is e'licitly
secified. , ointer to the array of 2B integers can $e
declared as follo!s.
Xinclude Astdio.hQ
main = >
?
int a [4\ [5\ H ?2B# 4B# 5B# 6B# JB#
KBE@
void sho! =int =G> [5\>@
sho! =a>@
E
void sho! =int =G$> [5\>
?
int i# V@
for =iHB@ iA4@ CCi>
?
rintf = 0Dn1>@
for =VHB@ VA5 CCV>
rintf = 0Nd Dt1# G =G =$Ci> CV > >@
E
E
DOU78+ )OINT+R ,S , ),R,&+T+R % USIN9
,N ,USII8,RL ,RR,L OF )OINT+RS
With this method you can create general %
urose functions# if .inde'/ is allocated at run(time.
,dd the dimensions to the formal argument list.
Xinclude Astdio.hQ
main = >
?
int a [4\ [5\ H ?2B# 4B# 5B# 6B# JB# KBE@
void sho! =int GG$>
sho!=a>@
?
int I# V Gaa[5\@
for 3iB@ iA4@ CCi>
aa[i\ H =int G> $ C5Gi@
for =iHB@ iA4@ CCi>
?
rintf = 0Dn1>@
for =V HB@ iA5@ CCV>
rintf = 0Nd Dt1# aa[i\ [V\>>@
E
E
, dou$le ointer cannot $e used directly as a
formal arameter for a t!o(dimensional array.
Consider the follo!ing rogram.
+'amle 4R;
Xinclude Astdio.hQ
main= >
?
int a [4\ [5\ H ?2B# 4B# 5B# 6B# JB# KBE@
void sho! =int GG$>
?
int i# V@
clrscr= >@
for =iHB@ iA4@ CCi>
?
rintf = 0Dn1>@
for =VHB@ VA5@ CCV>
rintf =0Nd Dt1# $ [i\ [V\>@
E
E
It gives the !rong outut instead of rinting 2B#
4B# 5B# 6B# JB# KB. The reason is as follo!s.
,lthough the comiler may not comlain# it is
!rong to declare int GG$ and then use $ as a t!o(
dimensional array. These are t!o very different data
tyes and $y using them you access different locations
in memory.
The array decays into ointer !hen it is assed
to a function. The famous decay convention is that an
array is treated as a ointer that oints to the first
element of the array. This mista:e is common $ecause
it is easy to forget that the decay convention must not
$e alied recursively =more than once> to the same
array# so a t!o(dimensional array is not e*uivalent to
a dou$le ointer. , .ointer to ointer of T/ cannot
serve as .t!o(dimensional array of T/. The t!o(
dimensional array is e*uivalent to a .ointer to ro! of
T/# and this is very different from .ointer to ointer
of T/.
When a dou$le ointer that oints to the first
element of an array is used !ith su$scrit notation .tr
[B\ [B\/# it is fully dereferenced t!o(times. ,fter t!o
full dereferencings# the resulting o$Vect !ill have an
address e*ual to !hatever value !as found inside the
first element of the array. Since the first element
contains the data# !e !ould have !ild memory
accesses.
The e'tra dereferencing could $e ta:en care of
$y having an intermediary .ointer to T/.
tye a[m\ [n\# Gtr2# GGtr4@
tr4 H Ttr2@
tr2 H =tye G> a@
7ut that !ould not !or: either@ the information
on the array .!idth/ =n> is lost. , ossi$le solution to
ma:e a dou$le ointer !or: !ith a t!o(dimensional
array notation is to have an au'iliary array of ointers#
each of them ointing to a ro! of the original t!o(
dimensional array.
tye a[m\ [n\# Gau'[m\# GGtr4@
tr4 H =tye GG> au'@
for =iHB@ iAm iCC>
au' [i\ H =tye G> a C i G n@
Of course# the au'iliary array could $e
dynamic.
+'amle 43;
Xinclude Astdio.hQ
Xinclude Astdio.hQ
main = >
?
long mat [J\ [J\# GGtr@
mat [B\ [B\ H 5@
tr H =long GG> mat@
rintf = 0mat N Dn1# mat>@
rintf = 0tr N Dn1# tr>@
rintf = 0mat [B\ [B\ Nd Dn1# mat [B\ [B\ >@
rintf = 0Tmat [B\ [B\ N Dn1# Tmat [B\
[B\ >@
rintf = 0Ttr [B\ [B\ N Dn1# Ttr[B\
[B\ >@
E
Outut@
mat FF34
tr FF34
mat [B\ [B\ 5
Tmat [B\ [B\ FF34
Ttr [B\ [B\ BBB5
It is seen mat [B\ [B\ and tr [B\ [B\ are different
o$Vects =they have different addresses> although mat
and tr have the same value.
,RR,L OF )OINT+RS ,S FOR&,8
),R,&+T+R
Since ointers are varia$les# they can $e stored
in arrays. The declaration of an array of ointers !ill#
for instance# $e int Ra [J\@ [\ has higher recedence
than G. This means a is an array of five elements# !ith
each element $eing a ointer to an integer.
a[i\ is a ointer.
Ga [i\ is the integer it oints to# the first
element of the ith ro!.
Xinclude Astdio.hQ
main = >
?
int a [4\ [5\ H ?2B# 4B# 5B# 6B# JB# KBE@
void sho! =int G [\>@
sho! =a>@
E
void sho! =int G$[\>
?
int i# V Gaa [5\@
for =iHB@ iA4@ CHi>
aa[i\ H =int G> $ C 5Gi@
for =iHB@ iA4@ CCi>
?
rintf = 0n1>@
for =VHB@ VA5@ CCV>
rintf = 0Nd Dt1# aa[i\ [V\ > >@
E
E
,SIN98+ )OINT+R ,S , FOR&,8
),R,&+T+R
With this method general % urose
functions can $e created. The dimensions do not
aear in any declaration# so they can $e added to the
formal argument list. The manual array inde'ing !ill
ro$a$ly sho! do!n the e'ecution.
Xinclude Astdio.hQ
main= >
?
int a [4\ [5\ H ?2B# 4B# 5B# 6B# JB# KBE@
void sho! =int G>@
Can $e relaced $y
sho! =Ta [B\ [B\ >@
sho! =Ga>@
E
void sho! =int G$>
?
int I#V@
for =iHB@ iA4@ CCi>
?
rintf = 0Dn1>@
for =VHB@ VA5@ CCV>
rintf = 0NJ.4d1# G=$ C5Gi CV > >@
E
E
)assing matrices to a function can $e tric:y.
For more clarity here are some e'amle of assing a
5'6 matri' to functions. Notice each and every
rogram carefully.
+'amle 5B;
Xinclude Astdio.hQ
Xdefine ROWS 5
Xdefine CO8S 6
main = >
?
int i# V@
int mat [ROWS\ [CO8S\@
int Gtr@
void sho! =int [\ [CO8S\# int# int>@
rintf = 0Dn The original values using
array indices Dn1>@
for =iHB@ iAROWS@ iCC>
?
rintf = 0N1# mat [i\>@
for =VHB@ VACO8S@ VCC>
?
mat [i\ [V\ H iCV@
rintf =0Nd1# mat [i\ [V\>@
E
rintf =0Dn1>@
E
rintf = 0Dn The first call to sho! Dn1>@
sho! =mat# ROWS# CO8S>@
rintf = 0Dn The second call to sho! Dn1>@
sho! =Tmat [B\# ROWS# cols>@
rintf = 0Dn The original values using a
ointer. Dn1>@
tr H Tmat [B\ [B\@
for =iHB@ iAROWS@ iCC>
?
rintf =0Nd1# tr>@
for =VHB@ VACO8S@ VCC>
?
Gtr H iCV@
rintf = 0d1# G=trCC> >@
E
rintf =0Dn1>@
?
rintf =0Dn The first call to sho! Dn1>@
sho! =mat# ROWS# CO8S>@
rintf = 0n The second call to sho! Dn1>@
sho! =Tmat [B\# ROWS# CO8S>@
E
void sho! =int array [\ [CO8S\# int ro!s# int
cols>
?
int i# V@
for =iHB@ iAro!s@ iCC>
?
rintf = 0N1# array[i\>@
for =VHB@ VAcols@ VCC>
rintf =0Nd1# array [i\ [V\ >@
rintf = 0Dn1>@
E
E
Outut;
The matri' is 5 ' 6
The original values suing array indices
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The first call to sho!
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to sho!
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The original values using a ointer
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The first call to sho!
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to sho!
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
In the first call to sho! = > function# the $ase
address is assed imlicitly in function. In the second
call# the $ase address of the element in the first ro! is
assed e'licitly. This !ill run faster $ecause there is
no need to comute the location using Tmat [B\ [B\ C
6 Gi C V. , t!o(dimensional array is actually a one(
dimensional array that mas to the storage ma for
mat@ that is !hy !e do not need the first inde' si-e.
In the follo!ing illustration# the function
dislay= > ta:es ointer to array of four integers. "ere
a ointer to an array of integers is used and only one
inde' is used.
+'amle 52;
Xinclude Astdio.hQ
Xdefine ROWS 5
Xdefine CO8S 6
main= >
?
int i# V@
int mat [ROWS\ CO8S\@
int Gtr@
void dislay =int =G> [CO8S\# int#
int>@
rintf = 0DnThe matri' is Nd '
Nd Dn1# ROWS# CO8S>@
rintf =0The original values for mat
and dislay Dn1>@
for =iHB@ iAROWS@ iCC>
?
rintf = 0N1# mat [i\>@
for =VHB@ V A CO8S@ VCC>@
?
mat [i\ [V\ H iCV@
rintf =0Nd1# mat [i\ [V\ >@
E
rintf = 0Dn1>@
E
rintf = 0Dn The first call to
dislayDn1>@
dislay =mat# ROWS# CO8S>@
rintf = 0Dn The second call to
dislay Dn1>@
dislay = 0Tmat [B\# ROWS#
CO8S>@
rintf = 0n The original values
using a ointer. Dn1>@
tr H Tmat [B\ [B\@
for =iHB@ iAROWS@ iCC>
?
rintf = 0N1A tr>@
for =VHB@ VACO8S@ VCC>
?
Gtr H iCV@
rintf = 0Nd1# G=trCC> >@
E
rintf = 0Dn1>@
E
rintf = 0Dn The first call to
dislay Dn1>@
dislay =mat# ROWS# CO8S>@
rintf = 0Dn The second call to
dislayDn1>@
dislay =Tmat [B\# ROWS#
CO8S>@
E
void dislay =int =Garray> [CO8S\# int
ro!s# int cols>
?
int I# V@
for =iHB@ iAro!s@ iCC>
?
rintf = 0N1# array>@
for = VHB@ #&cols@ VCC>
rintf = 0Nd1# =Garray> [V\ >@
arrayCC@
rintf =0Dn1>@
E
E
Outut
Out matri' is 5 ' 6
The original values for mat and dislay
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The first call to dislay
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to dislay
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The original values using a ointer
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The first call to dislay
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to dislay
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
No! let us ass these values to rintImat = >
function. This !ill run faster than sho! and dislay.
)t(array is a ointer that oints to the elements in the
matri'. This is convenient $ecause C stores t!o(
dimensional arrays in ro!s.
+'amle 54;
Xinclude Astdio.hQ
Xdefine ROWS 5
Xdefine CO8S 6
main = B
?
int i# V@
int mat [ROWS\ CO8S\@
int tr@
void rintImat =int G# int# int >@ F F
rintf = 0Dn The matri' is Nd ' Nd Dn1#
ROWS# CO8S>@
rintf = 0The original values for the
matri' Dn1>@
for =iHB@ iAROWS@ iCC>
?
rintf = 0N1# maty [i\>@
for 3VHB@ VACO8S@ VCC>
?
mat [i\ [V\ H iCV@
rintf = 0Nd1# mat [i\ [V\ >@
E
rintf =0Dn1>@
E
rintf = 0Dn The first call to rintImat
Dn1>@
rintfImat =mat [B\# ROWS# CO8S>@
rintf = 0Dn The second call to
rintImat Dn1>@
rintfImat =Tmat [B\ [B\# ROWS#
CO8S>@
rintf = 0Dn The# third call to rintImat
Dn1>@
rintfImat =Gmat# ROWS# CO8S>@ DG
This !ill run faster as !ill rintImat. GF
rintf = 0Dn The original values for
rintImat Dn1>;
tr H Tmat [B\ [B\@
for =iHB@ iAROWS@ iCC>
?
rintf = 0N1# tr>@
for =VHB@ VACO8S@ VCC>
?
Gtr H iHV@
rintf = Nd1# G=trCC> >@
E
rintf = 0Dn1>@
E
F F rintImat
rintf = 0n The first call to rintImat Dn1>@
rintImat =mat [B\# ROWS# CO8S>@
rintf =0Dn The second call to rintImat
Dn1>@
rintImat =Tmat [B\ [B\# ROWS# CO8S>@
rintf = 0Dn The third call to rintImat
Dn1>@
rintImat =Gmat# ROWS# CO8S>@
E
void rintImat =int GtIarray# int ro!s# int cols>
?
int i# V
for =iHB@ iAro!s@ iCC>
?
rintf = 0N1# tIarray>@
for =VHB@ VAcols@ VCC>
rintf = 0Nd1# G=tIarrayCC>
>@
rintf = 0Dn1>@
E
E
Outut
The matri' is 5 ' 6
The original values for the matri'
FFDC B 2 4 5
FF+6 2 4 5 6
++FC 4 5 6 J
The first call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The third call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The original call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The first call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The second call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
The third call to rintImat
FFDC B 2 4 5
FF+6 2 4 5 6
FF+C 4 5 6 J
In the a$ove illustrations# the address of the
corresonding ro!s is ointed on the first column.
Consider the ro$lem of date conversion# form
day of the month to day of the year and vice versa.
For e'amle# &arch 2
st
is the KB
th
day of a non(lea
year# and the K2
st
day of a lea year. 8et us define t!o
functions to do the conversions.
dayIofIyear converts the month and day into
the day of the year and monthIdat converts the day of
the year into the month and day. Since this latter
function comutes t!o values# the month and day
arguments !ill $e ointers.
monthIday =23RR# KB# Tm# Td> sets m to
4 and d to 43 =Fe$ruary 43
th
>.
7oth these functions need the same
information# a ta$le of the num$er of days in each
month. Since the num$er of days er month differs for
lea years and non(lea years# it is easier to searate
into t!o ro!s of a t!o(dimensional array than to :ee
trac: of !hat haens to Fe$ruary during
comutation. The array and the functions for
erforming the transformations are as follo!s.
static char dayta$ [4\ [25\ H ?
?B# 52# 4R# 52# 5B# 52# 52# 5B# 52# 5B# 52E#
?B# 52# 43# 52# 5B# 52# 5B# 52# 52# 5B# 52# 5B#
52E
E
FG dayIofIyear; set day of year from month T
day GF
int dayIof(year =int year# int month# int day>
?
int i# lea
lea H yearN6 H H B TT yearN2BB Z H B
^ ^ yearN6BBH HB@
for =iH2@ iAmonth@ iCC>
day CH dayta$ [lea\ [i\@
return day@
E
FG monthIday; set month# day from day of year
GF
void monthIday =int year# int yearday# int
Gmonth# int Gday>
?
int i# lea@
lea H yearN6 H H B T T year N2BB Z H
B ^ ^ year N6BB H H B@
for =iH2@ yearday Q dayta$ [lea\ [i\@ iCC>
yearday (H dayta$ [lea\ [i\@
Gmonth H i@
Gday H yearday@
E
Recall that the arithmetic value of a logical
e'ression# such as the one for lea# is either -ero
=false> or one =true># so it can $e used as a su$scrit of
the array dayta$. The array dayta$ has to $e e'ternal
to $oth dayIofIyear and monthIday# so they can $oth
use it. It is made as char to illustrate a legitimate use
of char for storing small non(character integers.
In C# a t!o(dimensional array is really a one(
dimensional array# each of !hose elements is an array.
"ence# su$scrits are !ritten as
dayta$ [i\ [V\ FG [ro!\ [col\ GF
and elements are stored $y ro!s. So the
rightmost su$scrit# or column# varia$les fastest as
elements are accessed in storage order.
"ere the array dayta$ is started !ith a column
of -ero so that month num$ers can run from the
natural 2 to 24 instead of B to 22. Since sace is not at
a remium here# this is clearer than adVusting the
indices.
R,99+D ,RR,LS
We !ant to contrast a t!o(dimensional
array of tye char !ith a one(dimensional array of
ointers to char. Similarities and differences e'ist
$et!een these t!o constructs.
+'amle 55;
Xinclude Astdio.hQ
int main= void>
?
char a [4\ [2J\ H ?0a$c;1# 0a is for
ale1E@
char G) [4\ H ?0a$c;1# 0a is for ale1E@
rintf = 0Nc Nc Nc Ns Ns Dn1# a [B\ [B\#
a [B\ [2\# 2[B\ [4\# a [B\# a[2\>@
rintf = 0Nc Nc Nc Ns Ns Dn1# [B\ [B\#
[B\ [2\# [B\ [4\# [B\# [2\>@
return B@
E
Outut
a$c a$c; a is for ale
a$c a$c; a is for ale
The rogram and its outut illustrate similarities
in ho! t!o constructs are used. 8et us consider the
rogram in some detail. The identifier a is a t!o(
dimensional array# and its declaration causes 5B chars
to $e allocated. The t!o(dimensional initiali-er is
e*uivalent to
? ? .a/# .$/# .c/# .;/# .DB/E# ?.a/# ./# .i/# .s/#
SE E
The identifier a is an array# each of !hose
elements is an array of 2J chars. Thus# a [B\ and a [2\
are arrays of 2J chars. 7ecause arrays of characters
are strings# a [B\ and a[2\ are strings. The array a[B\ is
initiali-ed to
? .a/# .$/# .c/# .;/# .DB/E
and $ecause only five elements are secified#
the rest are initiali-ed to -ero =the null character>.
+ven through not all elements are used in this
rogram# sace has $een allocated for them. The
comiler uses a storage maing function to access a
[i\ [V\. +ach access re*uires one multilication and one
addition.
The identifier is a one(dimensional array of
ointers to char. Its declaration causes sace for t!o
ointers to $e allocated =four $ytes for each ointer on
the 54($it machine>. The element [B\ is initiali-ed to
oints at 0a$c;/# a string that re*uires sace for five
chars. The element [2\ is initiali-ed to oint at 0a is
S1# a string that re*uires sace for 2J chars#
including the null character DB at the end of the string.
Thus# does its !or: in less sace than a. &oreover#
the comiler does not generate code for a storage
maing function to access [i\ [V\# !hich means that
does its !or: faster than a. Note that a [B\ [26\
overruns the $ounds of the string ointed to $y [B\.
Of course# a [B\ [26\ overruns the string currently
stored in a [B\# $ut it does not overrun the array a [B\.
"ence# the e'ression a [B\ [26\ is acceta$le.
,nother difference is that the strings ointed to
$y [B\ and [2\ are constant strings# and# hence#
cannot $e changed. In contrast to this# the strings
ointed to $y a [B\ and a[2\
,n array of ointers !hose elements are used to
oint to arrays of varying si-es is called a ragged
array. 7ecause# in the receding rogram# the ro!s of
have different lengths# it is an e'amle of a ragged
array. If !e thin: of the elements [i\ [V\ arranged as a
.rectangular/ collection of elements in ro!s and
columns# the disarate ro! lengths give the .rectangle/
a ragged loo:. "ence# the name ragged array.
The follo!ing is a deiction of a ragged array.
a $ c D
B

a i s f o u
r a l e DB

T"R++ DI&+NSION,8 ,RR,L
,rrays of dimension higher than t!o
!or: in a similar fashion. 8et us descri$e ho! three(
dimensional arrays !or:. If !e declare
int a[P\ [3\ [4\
then a comiler such as a [i\ [V\ [:\ is used in a
rogram. The comiler uses the storage(maing
function to generate the o$Vect code to access the
correct array element in memory.
Initiali-ation If !e are !illing to ut in all the
$races# then !e do not have to secify all the -eros.
Consider the follo!ing initiali-ation.
int a[4\ [4\ [5\ H ?
? ? 2# 2# BE# ?4# B# BE E
? ? 5# B# BE# ?6# 6# BE E
E@
C uses t!o imlementations of arrays#
deending on the declaration. They are the same for
one dimension# $ut different for more dimensions. For
e'amle# if an array is declared as
int array [2B\ [4B\ [5\@
then there are e'actly KBBB ints of storage
allocated# and a reference of the form array [i\ [V\ [:\
!ill $e translated to
G =array C iG4BG5B C VG5B C:>
Which calculates the correct offset from the
ointer .array/# and then does an indirection on it. To
ass an array of this tye to a function# the arameter
must $e declared as
int arg[\ [4B\ [5B\@
"ere is a function that !ill sum the elements of
the array. Note carefully that all the si-es e'cet the
first must $e secified.
int sum =int a [ \ [3\ [4\>
?
int I# V# :# sum H B@
for =iHB@ iAP@ CCi>
for =VHB@ VA3@ CCV>
for =:HB@ :A4@ CC:>
sum C H a[i\ [V\ [:\@
return sum@
E
In the header of the function definition# the
follo!ing three declarations are e*uivalent.
int a[ \ [3\ [4\ int a [P\ [3\ [4\ int =Ga> [3\
[4\
In the second declaration# the constant P acts as
a reminder to human readers of the code# $ut the
comiler disregards it. The other t!o constants are
needed $y the comiler to generate the correct
storage(maing function.
Caution These three declarations are e*uivalent
only in a header to a function definition.
If a three(dimensional array is declared
as
int GGGarray@
=and it is assumed for the moment that it has
$een allocated sace for a 2BG4BG5B array># then there
is an array of 2B ointers to ointers to ints# 2B arrays
of 4B ointers to ints# and KBBB ints. The 4BB elements
of the 2B arrays each oint to a $loc: of 5B ints# and
the 2B elements of the one array each oint to one of
the *B arrays. The array varia$le oints to the head of
the array !ith 2B elements.
In short# array oints to a ointer to a ointer to
an integer# Garray oints to a ointer to an integer#
.GGarray/ oints to an integer# and .GGGarray/ is an
integer.
In this case# an access of the form array [i\ [V\
[:\ result in an access of the form
G = G = G =array Ci> CV> > C :>
This means ta:e a ointer to the main array# add
i to offset to the ointer to the correct second
dimension array# and indirect to it. No! !e have a
ointer to one of the arrays of 4B ointers# and !e add
V to get the offset to the ne't dimension# and !e do an
indirection on that. We no! have a ointer to an array
of 5B integers# so !e add : to get a ointer to the
desired integer# do an indirection# !e have the integer.
)OINT+RS TO FUNCTIONS
One of the o!er features of C is to
define ointers to functions. Function ointers are
ointers# i.e.# varia$les# !hich oint to the address of a
function. , running rogram is allocated a certain
sace in the main memory. The e'ecuta$le comiled
rogram code has an address. 8i:e other ointer
varia$les# function ointers can $e declared# assigned
values# and then used to access the functions they
oint to.
D+C8,R,TION OF , )OINT+R TO , FUNCTION
Function ointers are declared as follo!s;
ReturnItye =GfunctionIointerIname>
=argumentItye2# argumentItye4#S>@
In the follo!ing e'amle# a function ointer
named f is declared. It oints to functions that ta:e
one float and t!o char and return as int.
int =Gf> =float# char# char>@
Some e'amle include the follo!ing.
int =Gf> = >@
dou$le =Gftr> = >@
"ere# f is declared as a ointer to a function
that returns int tye# and ftr is a ointer to a function
that return dou$le. The interretation is as follo!s for
the first declaration; the dereferenced value of f# i.e.#
=Gf> follo!ed $y= > indicates a function that returns
integer tye. The arentheses are essential in the
declarations. The declaration !ithout the arentheses
int Gf= >@
declares a function f that returns an integer
ointer.
INITI,8IU,TION OF FUNCTION )OINT+RS
8i:e other ointer varia$les# function ointers
must $e initiali-ed rior to use. It is *uite easy to
assign the address of a function to a function ointer.
One simly uses the name of a function. It is otional
to use the address oerator T in front of the function/s
name. For e'amle# if add = > and su$ = > are declared
as follo!s
int add =int# int>@
and
int su$ =int# int>@
the names of these functions# add and sum# are
ointers to those functions. These can $e assigned to
ointer varia$les.
fointer H add
fointer H su$@
C,88IN9 , FUNCTION USIN9 , FUNCTION
)OINT+R
In C there are t!o !ays of calling a function
using a function ointer; use the name of the function
ointer instead of the name of the function or
e'licitly dereference it.
result2 H fointer = 6# J>@
result4 H fointer = K# 4>@
The follo!ing rogram illustrates the a$ove
facts.
+'amle 56;
int =Gfointer> =int# int>@ FG Define a ointer to a
function GF
int add =int# int>@ FG Define a fe! functions.
int su$ =int# int>@
main = >
?
fointer H add@ FR ut the address of .add/
in .fointer/ GF
rintf =0Nd Dn1# fointer =6# J> >@ FG
+'ecute for .su$/ GF
fointer H su$@ FG Reeat for .su$/ GF
rintf = 0Nd Dn1# fointer =K# 4 > >@
E
int add =int a# int $>
?
return =a C $>@
E
int su$ =int a# int $>
?
return =a % $>@
E
),SSIN9 , FUCNTION TO ,NOT"+R
FUNCTION
, function ointer can $e assed as a
function/s calling argument. The follo!ing code
sho!s ho! to ass a ointer to a function# !hich
returns a dou$le and ta:es t!o dou$le arguments.
Suose# a comutation can $e erformed !ith
different functions. Consider
n
_f =Y>
:Hm
!here in one instance f=Y> H '
:
FYZ and in
another instance f =Y> H 2 F ]
:
.
f =Y> H '
:
F YZ can $e imlemented as
follo!s.
dou$le e'Iterm =dou$le $# dou$le '>
?
return =o! ='# $> F fact =$> >@
E
dou$le fact =dou$le a>
?
dou$le fH2. B@
for = @aQB@ a((>
fGHa@
return f@
E
f =Y> H 2 F '
:
can $e imlemented as
follo!s.
dou$le $yIterm=dou$le $# dou$le
'>
?
return =2 Fo!='#$> >@
E
No!# the summation function can $e
imlemented as follo!s.
dou$le sum =dou$le f =dou$le# dou$le> #
int m# int n>
?
int Y@
dou$le s H B. B@
dou$le '@
rintf = 0Dn +NT+R T"+ M,8U+
OF '1>@
scanf = 0N2f1# T'>@
for =YHm@ YAHn@ CCY>
sCHf =Y#'>@
return s@
E
When a function aears as an argument# the
comiler interrets it as a ointer. The follo!ing is an
e*uivalent header to the function.
dou$le sum =dou$le =Gf> =dou$le># int m#
int n>
?
S same as a$ove
E
"ere# dou$le =Gf> =dou$le> is a ointer to a
function that ta:es an argument of tye dou$le and
returns a value of tye dou$le.
)arentheses is very imortant as = > $inds more
tightly than G. If the argument is !ritten as dou$le f
=dou$le> instead of dou$le =f> =dou$le> then it imlies
that f is a function that ta:es an argument of tye
dou$le and returns a ointer to a dou$le.
In the $ody of the sum function# the
statement
s C H f=Y> can $e relaced $y
sC H =Gf> =Y> !here the ointer to
the function is e'licitly dereferenced.
"ere#
f imlies the ointer to a function
G f imlies the function itself
=Gf> =Y> the call to the function
Figure 25.24 deicts the meaning of each art
in a function ointer notation.
the ointer to a function
= G f >
=Y> call to the function
The function itself


Fig. 25.24 &eaning of
Function ointer Notation
No!# !hat should $e the rototye of the
functionsO The rototyes of the corresonding
functions used here are given $y
dou$le $yIterm =dou$le>@
dou$le e'Iterm =dou$le>@
dou$le fact =dou$le>@
dou$le sum =dou$le =Gf> =dou$le>#
int# int>@
There are several e*uivalent rototye
declarations for the function rototye =iv> that sho! a
function as a formal arameter.
dou$le sum =dou$le =G> =dou$le>#
int# int>
dou$le sum =dou$lef =dou$le># int#
int>@
dou$le sum =dou$lef =dou$le '>#
int m# int n>@
No!# let us come to the calling statement of the
function that follo!s.
void main= >
?
rintf =0Dn SU& OF
CO&)UT,TION 2; N2f;1# sum =e'Iterm# B# 5 > >@
rintf = 0Dn SU& OF
CO&)UT,TION 4; N2f1# sum=$yIterm# B# 6 > >@
E
sum =e'Iterm# o# 6#> comutes the sum
of the follo!ing series.
s H '
B
C '
2
C '
4
C '
5
C '
6
BZ 2Z 4Z 5Z 6Z
H 2 C ' C '
4
C '
5
C '
6
4Z 5Z 6Z
sum =$yIterm# B# 6> comutes the sum of the
follo!ing series.
s H 2 C 2C 2C 2 C 2
'
B
'
2
'
4
'
5
'
6
H 2 C 2 C 2C 2 C 2
' '
4
'
5
'
6
The follo!ing is the comete rogram.
+'amle 5J;
Xinclude Astdio.hQ
Xinclude Amath.hQ
dou$le fact =dou$le a>
?
dou$le f H 2. B@
for =@ aQB@ a( (>
fG H a@
return f@
E
dou$le e'Iterm =dou$le $# dou$le
'>
?
return =o! ='#$> F fact =$> >@
E
dou$le $yIterm =dou$le $# dou$le
'>
?
return =2Fo!='#$> >@
E
dou$le sum =dou$le f =dou$le#
dou$le># int m# int n>
?
int Y@
dou$le s H B. B@
dou$le '@
rintf = 0Dn +NT+R T"+ M,8U+
OF '1>@
scanf = 0N2f1# T'>@
for =YHm@ YAHn@ CCY>
sCHf =Y# '>@
return s@
E
void main = >
?
rintf = 0Dn SU& OF
CO&)UT,TION 2; N2f;1# sum =e'Iterm# B# 5> >@
rintf = 0Dn SU& OF
CO&)UT,TION 4; N2f1# sum =$yIterm# B# 6> >@
E
Outut;
+NT+R T"+ M,8U+ OF ' 4
SU& OF CO&)UT,TION 2; K. 555555
+NT+R T"+ M,8U+ OF ' 4
SU& OF CO&)UT,TION 4; 2. 35PJBB
"OW TO R+TURN , FUNCTION )OINT+R
It is a little $it tric: $ut a function ointer
can $e a function/s return value. In the follo!ing
e'amle there are t!o solutions of ho! to return a
ointer to a function that ta:es t!o float arguments
and returns a float. If anyone !ants to return a ointer
to a function all that needs to $e done is to change th e
definitionsFdeclarations of all function ointers.
float ,dd float a# float $> ?return aC$@E
float su$ =float a# float $> ?return a($@ E
,dd and su$ have $een defined. They return a
float and ta:e t!o float values. The function ta:es a
char and returns a ointer to a function that ta:es t!o
float and returns a float. AoCodeQ secifies !hich
function to return.
float =G9ertr2 =char oCode> > =float#
float>
?
if =oCode H H .C/> return T,dd@
if =oCode H H .(.> return T su$@
E
, solution using a tyedef defines a ointer to
a function that ta:es t!o float values and return a
float.
tyedef float =Gtr4Func> =float# float>
The function ta:es a char and returns a function
ointer that is defined as a tye a$ove. AoCodeQ
secifies !hich function to return.
tr4Func 9ettr4 =char oCode>
?
if =oCode H H .C/> return T,dd@
if =oCode H H .(. > return TSu$@
E
void ReturnI,IFunctionI)ointer= >
?
rintf = 0+'ecuting
ReturnI,IFunctionI)ointer Dn1>@
float =Gftr> =float# float>@ FG define a
function ointerGF
ftrH9ettr2 =.C/I@ FG get function
ointer from function .9et)tr2/ GF
rintf = 0Nf Dn1# ftr =4# 6> >@ FG call
function using the ointer GF
ftrH9et)tr4 =.(.I@ FGget function ointer
from function .9et)tr4/ GF
rintf = 0Nf Dn1# ftr =4# 6> >@ FG call
function using the ointer GF
E
,RR,LS OF FUNCTION )OINT+RS
,s has $een seen# there are arrays of
ointers to an int# float# string# and structure.
Similarly# an array of ointers to a function can also
$e used. Oerating !ith arrays of function ointers is
very interesting. It offers the ossi$ility of selecting a
function using an inde'. It is illustrated in the
follo!ing rogram.
+'amle 5K;
main = >
?
void =G [5\ > =int# float>@
int i@
void ,dd =int# int>@
void Su$ =int# int>@
void &ul =int# int>@
[B\ H ,dd@
[2\ H Su$@
[4\ H &ul@
for =iHB@ iAH4@ iCC>
=G[i\> = 2B# J>@
E
void ,dd =int a# int $>
?
)rintf = 0Dn Result of ,ddition H
Nd1# aC$>@
E
void Su$ =int a# int $>
?
rintf = 0Dn Result of Su$traction H
Nd1# a($>@
E
void &ul =int a# int $>
?
rintf = 0Dn Result of &ultilication H
Nd1# aG$>@
E
DLN,&IC &+&ORL ,88OC,TION
, ro$lem !ith many simle rograms
such as those !ritten so far is that they tend to use
fi'ed(si-e arrays# !hich may or may not $e $ig
enough. There are more ro$lems of using arrasy.
Firstly# there is the ossi$ility of overflo! since C
does not chec: array $ounds. Secondly# there is
!astage of sace % if an array of 2BB elements is
declared and a fe! are used# it leads to !astage of
memory sace.
"o! can the restrions of fi'ed(si-e arrays
$e avoidedO The ans!er is dynamic memory
allocation. It is the re*uired memory that is allocated
at run(time 3at the time of e'ecution>. Where fi'ed
arrasy are used# static memory allocated# or memory
allocated at comile time# is used. Dynamic memory
allocation is a !ay to defer the decision of ho! much
memory is necessary until the rogram is actually
running# or give $ac: memoery that the rogram no
longer needs.
The area from !here the alication gets
dynamic memory is called hea. The hea starts at the
end of the data segment and gro!s against the $ottom
of the stac:. If $oth meet# the rogram is in trou$le
and !ill $e terminated $y the oerating system. Thus#
C gives rogrammers the standard sort of facilities to
allocate and de(allocate dynamic hea memory. These
!ill $e discussed here.
ST,TIC &+&ORL ,88OC,TION
The comiler allocates the reuired
memory sace for a declared varia$le. 7y using the
address of oerator# the reserved address is o$tained
that may $e assigned to a ointer varia$le. Since most
declared varia$le have static memor# this !ay of
assigning ointer value to a ointer varia$le is :no!n
as static memory allocation.
DLN,&IC &+&ORL ,88OC,TION
, dynamic memory allocation uses
functions such as malloc= > or calloc= > to get memory
dynamically. If these fucnitons are used to get
memory dynamically anf the values retuned $y these
functions are assigned to ointer varia$les# such
assignments are :no!n as dynamic memory
allocation. &emory is assigned during run(time.
C rovides access to the hea features through
li$rary fucnitons that any C code can call. The
rototayes for these functions are in the file
Astali$.hQ. So any code !hich !ants to call these
must Xinclude that header file. The four fucnitons of
interest are as follo!s;
voidG malloc =si-eIt si-e>; Re*uast a contigous
$loc: of memory of the given si-e in the hea. &alloc
= > returns a ointer to the hea $loc: or NU88 if the
re*uest is not satified. The tye si-eIt is essentially an
unsigned long that indicates ho! large a cloc: the
caller !ould li:e measured in $ytes. 7ecause the
$loc: ointer returned $y malloc= > is void G =i.e.# it
ma:es no claim a$out the tye of its ointee># a cast
!ill ro$a$ly $e re*uired !hen storing the void
ointer into a regular tyed ointer.
calloc = >; !or:s li:e malloc# $ut initiali-es the
memory to -ero if ossi$le. The rototye is
void G calloc =si-eIt count# si-eIt eltsi-e>
The fucniton allocates a $loc: long enough to
contain an array of count elements# each of si-e elsi-e.
Its contents are cleared to -ero $efore calloc returns.
Moid free =voidG $loc:>; free = > ta:es a ointer
to a hea $loc: earlier allocated $y malloc = > and
returns that $loc: to the hea for reuse. ,fter the free =
># the client should not access any art of the $loc: or
assume that the $loc: is valid memory. The $loc:
should not $e freed a second time.
MoidG realloc =voidG $loc:# si-eIt si-e> ; Ta:e
an e'isting hea $loc: and try to reallocate it to a hea
$loc: of the given !hich may $e larger or smaller
than the original si-e of the $loc:. It returns a ointer
to the ne! $loc:# or NU88 if the reallocate !as
unsuccessful. Remem$er to catch and e'amine the
return value of realloc= >. It is a common error to
continue to use the old $loc: ointer. Realloc = > ta:es
care of moving the$ytes from the old $loc: to the ne!
$loc:. Realloc = >e'ists $ecause it can $e imlemented
using lo!(level features that ma:e it more efficient
than the C code a rogrammer could !rite.
The use these fucnitons# either stdli$.
"oralloc.h must $e included as these fucnitons are
declared in these header files.
Note
,ll of a rogram/s memory is de(
allocated automatically !hen it e'its. So a rogram
only needs to use free= > during e'ecution if it is
imortant for the rogram to recycle its memory !hile
it runs# tyically $ecause it uses a lot of memory or
$ecause it tuns for a long time. The ointer assed to
free = > must $e the same ointer that !as originally
returned $y malloc = > or realloc=># not Vust a ointer
into some!here !ithin the hea $loc:.
8et us discuss the fucnitons and their use in
detail. Note that if sufficient memory is not availa$le#
the calloc returns a NU88. 7ecause malloc can return
NU88 instead of a usa$le ointer# the code should
al!ays chec: the return value of malloc to see
!hether it !as successful. If it !as not# and the
rogram dereferences the resulting NU88 ointer# the
rogram !ill crash. , call malloc to malloc# !ith an
error chec:# tyeically loo:s something li:e this.
int Gi@
Gi H =int G> malloc =si-e of =int> >@
if =i HHNU88>
?
rintf =0out of memoryDn1>@
e'it =B>@ FG .return/ may $e usedGF
E
,7OUT +]IT= >
In the revious e'amle there !as a case
in !hich !e could not allocate memory. In such cases
it is often $est to !rite an error message# and e'it the
rogram. The e'it= > function !ill sto the rogram#
clean any memory used# and !ill close nay files that
!ere at the time.
Xinclude Astdli$.hQ
Moid e'it =int status>@
Note that !e need to include stdli$.h to find this
fucniton.
Whne memory is allocated# the allocating
function =such as malloc= > and calloc = > > returns a
ointer. The tye of this ointer deends on !hether
one using an older YTR comiler or the ne!er ,NSI
tye comiler. With the older comiler# the tye of the
returned oionter is char@ !ith the ,NSI comiler it is
void.
&alloc= > returns a void ointer =$ecause it does
not matter to malloc !hat tye this memory !ill $e
used for> that needs to $e cast to one of the
aroriate tyes. The e'ression =int G> in front of
malloc is called a .cast e'ression/. The follo!ing
rogram illustrates malloc in action.
+'amle 2.
Xinclude Astdli$.hQ
Xinclude Astdio.hQ
main = >
?
int G i@
dou$le T d@
float G f2@
float G f4@
i H =int G> malloc =si-e of
=int> >@
if =i HH NU88> ?rintf
=0out of memoryDn1>@ e'it =(2>@ E
d H =dou$le G> malloc =si-e
of =dou$le> >@
if G =d HH NU88> ? rintf
=0out of memory Dn1>@ e'it = ( 2 >@ E
f2 H =float G> malloc =si-e
of =float> >@
if =f2 HH NU88> ?rintf
=0out of memoryDn1>@ e'it =(2>@ E
f4 H =float G> malloc =si-e
of =float> >@
if =f4 HH NU88> ?rintf
=0out of memoryDn1>@ ei't =(2>@ E
Gi H 64@
Gd H 5.262J34K@
Gf2 H (2.4@
Gf4 H B.56@
rintf = 0i; address Nd@
contents NdDn1# =int> i# Gi>@
rintf = 0d; address Nd@
contrents NfDn1# =int> d# Gd>@
rintf = 0f2; address Nd@
contents NfDn1# =int> f2# Gf2>@
rintf = 0f4; arress Nd@
contents NfDn1# =int> f4# Gf4>@
E
OUT)UT;
i ; address 255P34@ contents 64
d ; address 255RBR@ contents
5.262J35
f2; address 255R46@ contents
(2.4BBBBB
f4; address 255R6B@ contents
B.56BBBB
This rogram declares a num$er of ointer
varia$les# calls malloc to allocate memory for their
contents# stores values into tehm# and then rints out
the addresses that !ere allocated and the values that
!ere stored there. The si-e of the memory to $e
allocated must $e secified in $ytes as an argument to
malloc= >. Sicne the memory re*uired for different
o$Vects is imlementation(deendent# the $est !ay to
secify the si-e is to use the si-e of oerator. Recall
that the si-eof oerator returns the si-e of the oerand
in $ytes.
The e'amle a$ove is useless $ecause in each
case enough memory is allocated for e'actly one
o$Vect !ith each call to malloc = >. Dynamic memory
allocation is really needed !hen the amount of
memory to $e allocated !ic: not $e :no!n until the
rrgam is run. For e'amle# it !ill $e determined on
the $asic of resonses from a user fo the rogram.
DLN,&IC ,88OC,TION OF ,RR,LS
To allocate a one(dimensionla array of
length N of some articular tye !here N is given $y
the user# simly use malloc = > to allocate enough
memory to hold N elements of the articular tye# and
then use resulting ointer as if it !ere an array. The
follo!ing rogram !ill create an array of N elements#
!here the value of N is given $y the user# and then
rint the sum of all elements of the array.
+'amle 4.
Xinclude Astdio.hQ
Xinclude Astdli$.hQ
mian = >
?
int N# Ga# i# sHB@
rintf = 0Dn enter the num$er
of elements of the array;1>@
scanf =0Nd1# TN>@
a H =int G> malloc = NG si-e
of =int > >@
if =aH H NU88>
?
rintf =0Dn memory
allocation unsuccessful. . .1>@
e'it =B>@
E
srintf = 0Dn enter the array
element statement scanf =0Nd1# =aCi>>@ GF
sCHa[i\@
E
rintf = 0Dn sum is Nd1# s>@
E
Note "ere is a fucniton that allocates memory
and then rints out the values that haen to $e stored
there !ithout initiali-ing them. No! let us see !hat
haens.
void sho! = >
?
float Gf@
int i@
f H =float G> malloc =2B G si-e of
=float> >@
if =f HH NU88>
?
rintf = 0Dnout of
memoryDn1>@
e'it =B>@
E
for =iHB@ iA2B@ iCC>
rintf =NfDn1# f[i\>@
E
Uon $eing run# this rogram gives different
results at different times deending on !ho else is
using the comuter and ho! much memory they are
using. Usually it Vust rintf out all -eros# $ut every
once in a !hile it rintd something li:e the follo!ing.
65524RJ46RP623PR362KRJPK.BBBBBB
B.BBBBBB
2R63JJPR4443JB46J33B6.BBBBBB
2PRR4JKK632PPJ3PP4J6JJ5K632J4.BBBBBB
PKR455PK36J4356P62JK4J2R44KRK4BR.BBBBBB
PJPPR25KJRJ24RRKJ54KK366.BBBBBB
P5JK5RP22JB66RJ2B3PJ6B3B5B3JJBBR.BBBBBB
PJKJ5J233R2532255B3J4R6K4K2PK.BBBBBB
P244BPBJ53362RR5RB5J2KK53K62K.BBBBBB
64JRJK3JBR44KPPR3K53B46K6.BBBBBB
What haened !as that there !ere non(-ero
values in the memory that !ere allocated# and the
rintf fucniton tried to interret those values as
floating oint num$ers. &ay$e they !ere floating
oint num$ers# $ut they could have $een characters#
integers# ointers# or anything else.
It is a good idea to initiali-e the memory
returned $y malloc= >. The reason is that the memory
may not $e .claen/ % it may have $een recently used
$ysome other rogram# and the values stored there
might or might not ma:e sense if interreted as the
tye of o$Vect !e e'ect to $e there =in this case# as
floating oint num$ers>. Sometimes there !ill $e
-eros. Sometimes# odd values. Sometimes# the values
!ill $e so !eird that the rocessor !ill detect !hat is
called a .$us error/# and !ill dum core. If the
memory is initiali-ed to contain legitimate values of
the aroriate tye# this !ill not haen.
"ere is a useful rogram that creates an
array that can hold floating oint num$ers.
flaot G ma:eIflaotIarray =int si-e>
?
int i@
flaot Gfa@
fa H =float G> malloc =si-e G si-eof
=float> >@
if =fa HH NU88>
?
rintf =0out of memoryDn/>@
e'it =B>@
E
for =iHB@ iAsi-e@ iCC>
fa [i\ H B.B@
return =fa>@
E
,nother !ay is to use calloc = > that allocates
memory and clears it to sero. It is declared in stdli$.h.
Moid G calloc =si-eIt count# si-e(t eltsi-e>
This fucniton allocates a $loc: long enough to
contain a vector of count elements# each of si-e
eltsi-e. Its contents are cleared to -ero $efore calloc
returns. The sum of all N elements of an array that
uses dynamic memory allocation through malloc= >
fucniton can $e eritten as follo!s.
+'amle 5.
Xinclude Astdio.hQ
Xinclude Astdli$.hQ
main = >
?
rintf = 0Dn enter the num$er of
elements of the array;1>@
scanf = 0Nd1# TN>@
a H =int G> calloc =N# si-e of =int> > @
if =aHHNU88>
?
rintf = 0Dn memory
allocation unsuccessful. . .1>@
e'it= B>@
E
rintf = 0Dn enter the array elements
one $y one1>@
for =iHB@ iAN@ CCi>
?
scanf =0Nd1# =aCi> >@
sCHa [i\@
E
rintf =0Dn sum is Nd1# s>@
E
calloc = > can $e defined using malloc= >
as follo!s.
void G calloc =si-eIt count# si-eIt
eltsi-e>
?
si-eIt si-e H count G eltsi-e@
void Gvalue H malloc =si-e>@
if =value Z H B>
memset =value# B# si-e>@
return value@
E
7ut in general# it is not necessary that
calloc = > calls malloc internally. &emset sets n $ytes
of s to $yte c !here its rototye is given $y
Moid Gmemset =void Gs# int c# si-eIt n>@
&emset also sets the first n $ytes of the
array s to the character c. the follo!ing rogram
illustrates the use of the memset function.
+'male 6.
Xinclude Astring. "Q
Xinclude Astdio.hQ
Xinlcude Amen.hQ
int main =void>
?
char $[\ H 0"ello !ordsDn/@
rintf = 0$ $efore memset
=$>; NDn1# $>@
memset =$# .G/# strlen;
NsDn1# $>@
return B@
E
Outut
$ $efore memset; "ello !ords/
$ after memset; GGGGGGGGGGGG
The maloc = > function has oen otantion

You might also like