Understanding Pointers in C
Transcript of Understanding Pointers in C
iElrrrElrrytsaIEEffi{r,G6E-@G'E
-Y,,^t f"ttti
l-.:.
.I'PB PUBLICATIONS
Table of Contents
Aclotowledgments
2. Pointers atrd Arrryr ...
Jntrcduc|ion Io Second Edhiot
IDtroductio[ To Poitrters,,,,,....,..;...............,.......-.......1The & and , Operctors, 2Poifier Explessions, 4The Jargon of Pointers, 9char, int andfloat Poihters, 9Passing Addrcsses to Functiohs, 12Fuictions Retuming Pointers, 15Solyed Problems, 17Exercise, 30
Pointers and Stings, 142The const Qualifier, 143Retumirrg eonst Yaluef, 146Two Dirtensional A|ray ofCharacters, 147Array ofPoi\rers to Strings, 149Lirnitario4 ofArray ofPointers to Strings, I 52Solved Problems, 154F,xerclse. 184. ttv,'4. PolnterrandStructures ......,..........------------.,.........189An Array of gructures, 191
Mole about Structures, 192
Structure Poi ters, I94Offsers ofstructufe Elemehts, 196Linked Lists, 200Stacl$ and Queuet, 220Doubly Lhked Lisk, 2iiSolved Prcblens, 243Etercise,270
5. Pohters rlrd Dats Structurcs ...,......,.,..........,,,,.....,,,...,....279Mergirrg dLinked Lists, 280
t-
llhat are Arrays, 38Passing Atay Elernents to a Function.Poihters and Atays, 43Pqssing a4 E ttirc Affoy to a Function,TheRealThing,5lMorc Thqn One Di ension, 52Poinlers arrd Tfuo Dimetsional Arrays,Poi tetto sn Atay, 58Pdssing 2-D Arroy to a Function, 59Three Dimensiondl Arrays, 62Passing 3-D Array to a Functiok, 66Retuming Aftayfrorn Fuictiot , 69Relumifig 3-D Aftay from a Function,Array of Poi ters, 82Dyuhtic Memory Allocation, 84Solved Problems, 87Erercise, 130
Pointers and Stiitrgs ,.....................133Wat are Slrings, 1j3
* Li ked Lists and Polynonials, 285
Sotting a Lin*ed List, 297Circalar Linhed List, 323Trees, 326Binary Tre*, j28
41
50
3.
Stqhdard Library String Funcrions, I38
vt
Traversal d a Binary Tree, 33 1
Deletionlrom a Binary Tree, 336Threaded Binary Tree, 344Graphs,356Solved Problems, i69Exercise. 389
6. PointersMisceIlrtry..,,,.....................................................391File Poi rets, 391
Pointers to Functions, 394
typedef with Furrction Potuters, 397srgc and srgv - Arguments to mairt( ), 398
Poin ers afid Ydriable Nurnber of Argunen s' 399
rcor,lat and huge Poinlers, 40iWhich Poi en to Use?, 408Physicol ,4ddrcss to Segne :qsel 4 I IThe Darcing Dolls, 412Caps Locked!, 413How Much Memory Do You Have?, 415
Exercise,4l7
7. Appllcrdorr of Pohters '..,....--........................................423Exploting the Dith 423Dictioiary, 434Manoging Database, 439The Keybod Queue, 459InJix to Postfa, 462Evaluation of Postfa Exprcssion, 467
Locatw Duplicote Filelanes, 469Eoshing 474 i
Function Calls and Stqck. 480Solved Probtens, V85
I
tnrex | 493
Preface to Third Edition
In all walks of life anythiDg can be done better the next limearound. I realised this more emphatically when I completed lhethird edition oftlds book. Ihus, Ore so-cJlled ,perfect'
c'hapters ofthe second edition had to be redone for more clarity and simplicity.
For quite some time now I have beeo getting requests fiomreaders that the chapter on .pointers and Oata Structures, bemade more elaborate and exhaustivg. I have completelyoverhaule.d this chapter. Now it also includes binary treis anigraphs,
While reading the fust draft ofthis edition I felt that somethingis missin-gin this book. It was only when I was ttuougtr *ittr rtr!final draft I.realisgd that the missing link (poinrer) wa-s a chapteron applications of pointers in real-world programming. Afterall, no amount of theory is useful unless you cun poi it intopractice. So the final draft became semifinai since I decided toadd this chapter to the book. And now I am presenting you theedition which I feel is complete in all respects, lili I "-pmying tlat I won't be required to wrire aflother editiol of thisbook, Any author would testiS/ that writing a new edition isalways more palD in the neck than writing a fresh title.
tt
Poihten ca be tuade to work ifyou frddle ,a,ith them lo ge ough. Ifyou Jiddle with anything long enough you wilt uttimately
fiess it
An IntrotuctiontoQointrs
f f Tbich featue of C do beginners find most difficulr toVV understand? The answer is easy: pointers. Otherv V languages have pointeE but few use tbem so freely, with
such abandon, as C does. Aod why rct? Ir is C,s clever use ofpointeN that mak€s it the excellent language it is.
The difficulty begiDners have with pointers has much to do withC's pointe, terminology than lhe actual concept. For instance.when a C progmmmer says that a cedain variable is a . pointer..,what does that mean? It is hard to s€€ how a variable can poinr tosomething, or in a certain direction.
2 Understanding Pointers In C Chapter 1: An Introduction to Pointers 3
It is difficult to get a grip on poioters just by listening toprogrammer's jargon, In our discussion of C pointers, therefore,
we will try to avoid this difliculty by explaining them in terms ofsimple programming concepts. The fi$t thing vi,e want to do ise\plain the rationale ofC's pointer notalion.
We oan print this address through 1Le
/- Program 1 */
main0
{inti=3;
following program:
The& and * Operators
Consider the declamtion,
This declaration tells the C oompiler to:
(a) Reserve space in memory to hold the integer value.(b) Associate the name i with this memory location.(c) Srore the value I ar this location.
We may rcpresent i's looation irl the memory by the followingmemory map:
i-__}
El--*6485+
Location Dnme
I-ocation no. (Ad&ess)
Figure l.l
We see that the computer has selected memory Iocation 6485 as
the place to store the value 3. This location number 6485 is not anumber to be relied upon, because some other time drc computer
ultr\,
may ohoose a different location for storing th€ value 3.
impofiant point is, l's address in memory is a number.
printf ( "\nAddress of i= %u^,prlntf('hvalue of i = %u", i)
)
l'he output ofthe above program would be:
Addrcss ot i= 6485Value of i= 3
&i) ;
inti=3;
l,ook at the fi$t printf( ) statement carefully. The .&, opeBtor[sod in this statement is C's 'address of operator. The expression&i retums the address ofthe vagi4llglwhich in this case happenslo be 6485
pointer operator avaikble in C is '*'. called 'value aterator. It retums the vaiiE stored at a particdlalEddfess.
also called an 'indirection'at address' operator is
l,hlene carefully the output olthe following programj
/' Program 2 '/nrain0
I
inti=3;printf ( "\nAddress of i = %u', &i) ;
%d-, i) ;
%d",.(&i));printf ( \nvalue ofr =
otheress o
e'valueorator.
printi ("\nvalue of i=)
Ttre
IJnderstanding Poinlers In C Chapter I : An Introduction to pointers4 5
The output ofthe above prog€m would be:
Addressoli=6485Valueofi=3Value oli = 3
Note that pdnting the value of *( &i ) isofi.
As you can see, i,s value is 3 andj,s value is i,s address.
"l:1^1"]! ". :an'r use j jn a program wilhout dectaring it. And8rn.e j rs a \arjable. which conlains lhe addre., of i, it is-aeilurea-0r.
lnl 'j ;
'lltis declaralion tells the compiler that I will be used lo store therddress ofan integer value _ in o*re. *Jro.; poino ,o _ iri"g;;Ilow do wejustify tlie usage of * in the declaiation,
lnt'j;
1;d ,t g:-Py the meaning of +. It stands for ,value at address,,I hus,.irt *J would mean, the value at the addre*
""","rn"ji, ij,
same as printing the value
Pointer Expressions
Let us now see what are pointers and how they can be used in
various expresJions. We hav9 seen in the previous section that the
expression &i retums the address ofi. If we so desire, thig address
can be collected in a variable by saying,
But rcmembcr that J is not an ordinary variable like any other
int€ger variable. lt is a variable, which contains the address of
llcre is a program that dcmonshates the relationships we havet ccn discussing.
another variable (t in this case)
Since J is a variable the compiler must provide it space in mernory'
Once again, the following mcmory map would illusts?te the
contents of I and J.
E'.-l6485 3276
Figure 1.2
j=&i;
I Program 3./maino(
inl i= 3;int 'j ;
j=&i;pdntt ( '\nAddE$ of i = %u', di ) :printf ('\nAddEss of i = %u'. i ) :Printf ( '\nAddress ofj =
o/ou', ai) ;pdntt("\nvalueotj=%d'. i ) :'pdntf ( 'hvatue of i = %d", i i :pdntf ( 'hvalue of j =
o/od,. .{ &i ) I .
Printf ('\nvalueof i = %d' l) "'
6 (Jnderstanding Pointers In C Chapter 1 : An Introdaction to pointers 7
The output ofthc above program would be:
AddEssoli=6485Addressofi=6485AddEssofl=3276Value ofl = 6485
Valu6 ofl = 3Valueoli=3Valu6 of i= 3
Wo* thrcugh thc above program caretulln taking hclp of the
memory locations of t and J shom ea isr. This program
summarires everything we have discusscd so far. If you don'tunderstand thc'program's output, or the meoning of ihe
oxpregsions &1, &J, rl ard *( &l ), re'read the last few pages.
Evcidring wc say about poilters ftom hcr€ onwards will dcpcNd
on your understanding ofthcse exprcssions thoroughly.
Look at the following dcctarations,
lnt'alpha;ohar 'ch ;
lloat 's :
Hcrc, rlphr, ch and I ale declarcd as pointer variablel, i.c'variableicapable of holding addtesses. RfiIember that, addrgsses
(location nos,) ar€ always going to be whole oumbe!$, thorcfore
pointers ahvays contain whole numbers. Now we call put these twoiacts togethir and say-poiotels are variables that contain
since addrcsses ai;;lwaysE;G;mBEiies!waywould always co!!Bi!
concept of pointer caD be further extended. pointer we know is avadable, which contairc address of another variaUte, Niw thiivariable itself could be another pointer. Thus, we now have apointer., whicb.contains another pointer.s address. The followingexample should make this point clear.
f Prcgram 4'lmaino{
iiqt i= 3;int'j:lnt nt;
j= &;k=&j;
pinf ('bAddr€ssof I = %u., & ) ;Ptinu ( trAddcss oti= oi6u', j ):pdntf ( lnAddEss of i = %u., ik
) :Pdntf ( '\nAddrsss ofj = %u', &j i ;pdnf ( lnAddrEss ofj= %u', k ):prinf ( tAddrBss ofl( = %u', &k ) ;
prinf ( lnhvdus ofj = %u', j);pdnf ( Walus of k r %u', k );printf ( '\nvalue oti = %d', t)jpdntf( lnvaluo ofi =/od',.(&j))jpdnf (hvalue of i = %d", J );pdnf( lnvalueofi = %d',,* );
The declaration llgat *Ejqes not mean lhat s is going [o cooBln a
fl oati-ng-point valqq. @--aterisi-oIa'hoating-point value. Similarly, char *ch means that
ch is going to oontiin the address of a char value. Or irr other
words, the value at ad&ess stored in ch is going to be a ch'r' The
The output ofthe above program would be:
Addressoti=6485Addre6sori=6485AddEssofi=6485AddEssofj=3276'
8 Understanding Pointers In C
Address ofj= 3276
Addressolk=7234
Value ofj= 6485
Valueofk=3276Valueoli=3Valueofi=3Value of i= 3
Valu6ofi=3
The following memory tDop would help you ir tmcing out how the
prcgram prints dle above outpul.
Figurc 1.3
Obs€rvc how the variables l, J and k have been declarcd,
inti;lnl
-l i
int -k i
this, one mrely requires tojust in case...
extend the definition of a Pointer' But
H€re, I is an ordinary ldt, I is a pointer to ar lnt, whsreas k is a
poiflrer to a pointer. ln pdnciple, there could bG a pointer to a
;ointer to a pointer, or a pointer to a pointer to a pointer to apointer. There is no limit on how far can we go on extending this
a€finition. Possibly, titl the point we can csrFehetrd it' And that
point of oomprehensiotr is usually a pointe, to a pointer. Beyotd
char, int zad.Jlod, PointersConsidei the followiog program:
f P@gran 5'/main( ){
charc,'cc;int i, 'ii;
I
3
J
6485
k
3216
6485 3276 1234
The Jargon of PointersConsider the following program segment:
inta=35;inl 'b :
b=&a;
Now can you guess which ofthe follo.\f,ing statemenis are coneotl
(a) b contains address ofan ht.(b) Value at address contained in b is an lnt.(c) b is an ltrl pointer.(d) b points to an t!t.(e) b ig a pointer which points in the dileotion ofan lnt,
well, all these starements arc corect. That,s poinrgr jargon foryou. All the statemenls are fying to establish t:he srfle fact: tlBlsince b oontains address ofanint-it's an int Dointer, ,ikewise, hao
b contained an address of a flort it would have beoome a flolrpointer. with the same argument if we have three Doiflter variableg
first containing addrcss oian array, second contai;ing ad&ess ol,astructure and third containing address of a fuflction then It woulobe appropliate to call these ai an array pointer, a structure poinlerand a fiinction pointe! respectively.
float a,'aa;
c = 'A I ascii value of A gets stored in c t/
i=54;a= 3.14;
ii= &i i
aar&aipdntfplintfpdnttp ntfpdntfprintf
)
And herc is the output, , ,
Address conhined in cc = 1004
Addr€ss contain€d ln il = 2008
Address c.ntalned in aa = 7006
Vslue ofc = AValui of i: 54Valueofa=3.140000
Note that in the prltrtf( )s the addresses of chrr, lnt ard lhe no'tall have been prioted using the fomat specifier 7ou, Sometimes
the address miy tum out to be a number smaller than 32767. lnsuch a case we may use the fomat specifier 7"d to pritrt the
address. Also observe that though the integer va able i occupies
two brtes in mernory the stalement ii = &l stores only the addEss
ofthe first blte, 2008 itr il (refer Figurc 1.4). Similarly, " = &astores only the address of the flrst byte (7006) out'of forE bytes
occupied by the float variable a.
Chapter 1: An Introductia to Pointers t1
Figue 1.4
Thc address of first byte is ofton known as thc base addrcss.Though ll and rt contain ody the base addrcsses, the e*ftdssions*ll and *aa allow access !o all the bytes occupied by the intcger Iand a rcspectively. This is because il and a& haye been dcclarcd asitrt and llort pointers respectively. Since il is an itrt pointer, *llmust fetch ar lrt. Similally, since aa is a flort pointer *ar mustfetch a lloat.
Do you &ink the following program would work? And if it doeswhat would be its puttr ui?
\Address contained in cc = %u", cc ) i
'\nAddr€ss conbined in ii = %u", ii ) ;
'\nAddl8ss ontained in aa = %u', aa ) i
"ivalue of c = %c', 'cc ) ;
lnvalue of i = %d', 'ii ) ;
'Vrvaluo of a = o/ol, "aa ) ;
f ftogram 6'/main( ){
inli=54;float a = 3.,l4;char'ii, 'aa ;
ii= ( char . )&i;aa=(char.)Aa;pdntf ( lnAddress conhined in ij = %u', ii ) i
prinf ( lnAddrcss onhined in aa = %u', aa ) ;
pdntf ( lnvalue at fre address conhined in ii = o/od', 'ii ) :
EI1004
lE;;l:;7l2009
iim8l
7602
7006 7007 7008 7009
@1962
3.14
,13
12 Understanding Pointers In C Chapter l: An Introduction to Pointers 13
p ntf ( "hvalue at lhe addrcss contained in aa = %d', 'aa ) ;
)
Note that here ll and aa have been declared as chsr poioters. Stillrhe statemenrs ll = &i and ra = &a worElqnce again tbe ad&esses
2008 and 700d (refer Figure 1.4) get stored in ll and m which are
printed through the first two prtntf( )'s. However, the prcgram
falte$ at the next two prttrtf( )'s. This is so since ll is a characterpointsr *ll gives value at .d&ess 2008 ard not lhe one presetrt at2008 ad 2009. Similarly, *ra gives the value at 7006 and not the
one contained in 7006, 7007, 7008 and 7009.
Moral is, ifyou vdsh to acoess an integer value stored in a variableusing its addr€6s, it's rccessary that the ad&€ss be stoEd in an
integer poiater. Likewise, ifyou wish io acoess a float value stored
in a variable using its addrcss, it's necassary to storc the address ina float pointer.
Passing .dddresses to FunctionsAryu.ments arc generally passcd to fulctions in one of the twowaysr
G) Bending the values of the argumentssending the addresses ofthe arguments(b)
In the first method the 'value' of each 4crzal atgumetf in the
calling functiol is oopied into aonespondirg forr al argumcnt ofthe called function. With this method, ohanges rnade to tlre fotmalargume[ts irr the called function have no effect oo the values ofthesqtual argum€nts in the calling function.
following Eogram illustrates the 'Call by value'
r p.J,l,ff z r
(
inta=10iirt b = 20;
swapv(a,b);pdntf(tla=%d",a);printf('bb=%d',b);
)
swapv ( int x, inl y ){
pdntf(\u=%d",x)iPrintf (\y = %d", y )'
)
The output ofthe above program will be:
x=20v= 10a=10b=20
inlt;t=x;x=y;y=t;
Note that values of s and b remain unchanged even afterexchanging the values of x and y.
In the secold method (call by reference) the addresses of actualarguments in the calling futlction are copied into fonnal argumentsofthe called function. This means that using the fomal argumefltsin the called funotion, we can make changes in thJ actualarguments of the calling function. The following programillushates this fact.
14 Understanding Pointers In C Chapter 1: An Introduclion to Pointers 15
areaperi (radius, &area, &perimeter ) i
printf ( 'Area = %f, area ) ;
printf ( '\nPerimeter = %f', pedmeier)j
areapei ( int r, ioat 'a, float *p )
'a = 3.14'r'r;'p = 2'*3.14' r;
And here is the output...
Enter radius of a circle 5
Area = 78.500000Perimeter = 31.400000
Here, we are making a mixed call, in the sense, we are passing thevalue of radius but addresses of area and perimeter. And siDcewe are passing the addresses, any change that we make in valuesstored at addresses oontained in the variables a and p, would makothe chaflge effective even in main( ). That is why when the conholretums fiom the function areaperi( ) we are able to ourpul thevaluos ofiare! and perimeter.
Thus, we have been able to rctumfirnction. This helps us to overcome
f Progtam 8 ./
main( )
{inta=intb=
swapr (&a, &b ) ;
pdntf ( "\na = o/od"
printf('\nb=%d"
iswapr ( int *x, int
-y )
{inlt;
t=-li
)
10;20l
,a);,b);
The output ofthe above program would be:
a=20b=10
retum more than one value at a time, _which is not possibleordinarily. This is shown in the program given below. lime
statement, which can rctum only one value ftom a function at a
Using 'call by reference' intelligently we can make a function
/. Program 9'/main( ){
int radius i
float area, perimeter j
printf("\nEnter radius ofa circle " )jscanf ("%d", &radius ) ;
Functions Returning Pointers
The way functions retum an int. a float. a double or any other.lalatlpe, it can even retum a pointer. Howevei, to make a funcrionretum a pointer it has to be explicitly mentioned in the callingfunction as well as in th€ function definition. The followingprogram illustrates this.
two valuos from a calledthe limitation of the return
16 Understanding Pointers In C Chapler L An Introdu( tiott to Pointers 17
/* Program
main0
{
u",p);d",-p);
int'p;int -fun0
;
P=fun0;printf ( '\n%printf ( "\n%
10-t
/" prototype declaration */
*iun( ) /- function defnilion */
inti=20;relurn(&i);
Solved Problems
lAl What will be the output oflhc following programs:
(1) main0
tint i= -5, j= -2;junk (i, &j);printf ( '\ni = %d j= %d", i,l
junk ( int i, int tj )(
l- I li)
);
int
t
)
This progmm shows how a pointer can be rctumed from afunotion. Note that the prototlpe declaration tetls the compiler thatfun( ) is a function which receives nothing but returns an integerpointer. The first prlntf( ) would output the address contained in p(address of l). Can you guess what the second prlntf( ) wouldoutput? No, it won't p nt 20. This is because, when the controlcomes back from fun( ), I dies. So sven if we have its ad&ess in pwe can't access I since it is aheady dead. If you want I to surviveand *p to give 20 then make sure that you deolare i as stafic asshown below:
static int i = 20 ;
-5j
variable names in differcnt functions? Yes, by all means,without absolutely any conflict. Thus, the two sets of i and Jare two totally different sets of variables. While calling thefunction junk( ) the value ofl and the address ofj are passedto it. Natumlly, in ju*( ) i is declared as an ordinary int,whereas. j is declared as a pointer to an int.
Even though the value of i is changed to 25 in junk( ), thisohange will not be refl€cted back in main( ). As against this,since j's address is being passed to junk( ),Jutrk( ) gets reflected back in maitr( ). Henceevaluates to 4 is reflected back in main( ).
any-J-
change in*j, which
Output
Explanation
One doubt immediately oom€q to the mind----can we use same
18 Understanding Pointers In C
(2) #include "stdio.h'main( ){
int a, b =5;a=b+NULL;printf('%d',a);
)
Output
5
Explanatioa
NULL has beea defined in ',stdio.h,' as follows:
#define NULL 0
Heroe, duiing peprocessiog NUff *,in be rrplacedresulting into 5 getting stored irr r.
(3) #include 'stdio.h'maioo(
- printf ( '%d %d', sizeof ( NULI- ), !*zeof(.. ) ) ;)
Output
21
Explanotiot
Chapler 1: An Introiluction to Pahtters
While fiading out size of NULL, we are truly sDeakinefindiog out size of 0. This is an htieger, hence- its'size iircported as 2 bytes.
Even though the string -' is empty it still contains thecharacter, '\0'. Hence its size arrrrs out to be I bvte,
(4) main0
{floata=7.999999;float'b,'c;b=&alc=b;printf ( tu%u %u %u', &a, b, c ) ;
. printf (tl%d %d 96d 96d., a.( Aa ),.b,'c );I
Output
4200 42N4N00 24576.318115
Explaaatioa
b oontains the addrcss ofvariable r. Since a is a floaq b mustbe a lloat pointer. The same address is then assigtred to c.Therefore c has also been declared as a f,oat pointe.. The fiIstprtntf( ) prirfs the address of a in three differcnt ways. Noproblem therc. What is supdsing is the output of the secondprintf( ). Through this pritrtf( ) we are attempting to print7.999999 by. applying pohler operalors on a, b and c. a,*(&a), *b, *c all yield 7-999999 but when'they are prinredusing yod, printf( ) blows it up as the ouq,ut above wouldjustiry.
19
bv o,
20 Understanding Pointers In C
So always remember to use 9/"f to print floating point values.Don't rely on printf( ) to truncate a float value to an integerdu ng pinting by using a yod. Vice versa also it is t[ue. Thefollowing statements wouid not print 7.000000. Don't be
suryrised ifyou get some odd value. In that sense y"d and ohf
are a Iittle unreliable.
inti=7;printf("%f',i):
(s) mainO(
, int.c;c=check(10,20);printf("hc=%u',c);
)
check ( int i, intj)(
int.p, rq ;
p=&i;q=&j;if(i>=45)
retum (p );else
retum (q ) ;
)
Output
Enor message: Non ponaue pointer assignment in main
E)tpltiafion
The rcason for the eror is simple. The integers being passed
to check( ) arc collected in i and j, and then their addresses
Chapter l: An Introduction to pointers 2l
are assigred to p aDd q. The[ in the next statement theconditional operato$ test the value of i against 4j, anJ ;;tu;either the adtlress stored in p or the adjress ,t""J iil. f"tappeaE that this address would be collected in c in maijt tand then would be printed out. Ard tb"* li". ;";;;;. A';lirnction check( ) is not capable of retumins an inteserpololer. All that it ca! reEm is an ordinary intefer. Thus j"ustdeclaring c as an iDteger pointer is qot sufficient. We mustmake the following modificaaioru in the progmm to make itwork properly.
main0(
int 'c jinl 'check ( in! int ) ;c = check (10, m );pdntf(tuc=%u.,c);
)int 'che6k ( int i, int j )
)
(6) main( )t
tloat.jamboee ( fod.);float P = 23.5, 'O ,q=&p;pdntf ( tlq bebre cdt = 96u', q ) ;q=jamborBe(&p);printf ( \q afler ca[ = %u., q ) ;
tloal 'jamboree ( foat t )
t=t+1:
Unders tatding Point ers W Chapter l: An Innoduction to pointers 23
rBtum ( r) ;
)
OutPut
q bebtB call = silg8q aier call = 5502
Explatation '
[Bl ANwer tb€ folowing:
Explatatioa
( tpb )++
ln mrtd ). q has be€a d€clarEd as a trott pointer' lt means q
;; ;-G;il capable of holding the addtess of a florirrt-rnf, o = Cr'm
"aat""" of p' a ltoal is stored ia q and
,fr*,i"fu "ri,t-"gl th" p"iotf( ) This is the value of q
il.i.,{'i"i-urt-*t li"Erle<I.'whetr-irmboree( ) i8 called the
ffi;:Jir;i" "X; i, -a i" *u""t.a i" '' At this^juncture
r contains 5498 lwhen $'e ratr the progmm it was 54vui wnen
,a" "*a"a"
*" paga- this may tum our to be somc olher
lia*""1. Wr,* t i.ircremented it would become 5502 whv
.-"t* #+i S*""* . is a tro.t pointer aDd on incrmentiflg ili"'iii*.rfa poin r. {re nert ll'oat which would be F€sent 4
iL*. rt"oo. il*. cvery Oo.t is 4 bytes lotrg The return
"tat"rnent tl"o rett^" lhis adrlress 5502 back to EalD( \
Since a llo.t poiott is bsitrg retume4 a deElaration-.lloat*lembore. ( flort') is necessary in main( ), whrch tolls me
clmoiler rbat dowtr the li.oe therc exiss a fitnction called
i".LiC I *rti"l *itt r€ceiv€ a tlo't poiDter and will retum
a llort poirtcl.
(2) !r th€ followinS gogrm add a stat€.ri€ot in the fi[roiionfu( ) such tllat ad&ess oft gels stored h l.L
main0
{int'jlroidtun(i -);tun(&j);
)void tun ( int -k )t
inl a ='10;I add staEment he,E *,/
)
Explatation
'k=&a;
the pofut€r and oot the value pointediacrements tle value befug pointed to
( I ) Can you write anoth€r exEessioo which does the same Job as
.-1'pE9
9) Are the expEssiotrs ipff+ aod #rph saDe?
Explanation
No. *Ptr+ inorcmentsby it, whereas, +rphby ptr.
(4) Where can poit*€rs ie used?
Explarration
{Jnderstanding Pointers In C Chapler l: An lntroductian to Pointers 25
At lot ofplaoes, some ofwhich are:
- Accesshg array or s&ing elements
- Dynamic memorY allocation
- Call by refereace
- Implemeding lioked lists, tre€s, $aPhs and many other
data structures
Eiplanation
No. An efior would be .eported i[ the statement k+arithmetic on void pointeE is Dot permitted unless the
slncevoid
(5) Would the followingwaming? <Yes/No>
main0(
ioat i = 10,1;bid'k;k=&i;j= k;pdntl(ln%f,l);
)
Erylaaation
Eogram grYe a comPilatioo enor or
pointer is appropdately typ€casted.
(7) Would the following prograrncompilatioo?
#include 'stdio-h'main0(
int'p1, i= 25;void .p2
;p1 =&;p2=&i;p1 = p2:p2=p1;
)
Expla ariqn
No
(8) Would the following programcompilatioa?
.
#include 'stdio.h'main0
{float
-p'1, i= 25.50;chat *p2,,
pl=&i;p2=&i;
)
Explaaatiott
give any wamiug on
give atry waming on
No. Here no tipecastirg is required while assiguing thc value
t -*Jto. I L""ugrao*lsioq" ,"t" uopl&d-gU@or'"ntlv
*teo ooo po-i"ter types are assigned to atrd fiom vold ''
(6) Would thc followiag Pmgr& contpile?
main( )
{int a = 10,1;\sid'k;i=k=&a;j++ ;
k+;printf ( \lyou %u', i, k ) :
Unders land inE P ointers In Chapter 1: An Introduction to Pointers 27
(
Yes. The wamfug wonld be "Suspicious pointer conversion itr
firnction maitr( )".
9) What is a oull point€d
Explanation
For each pointer typ€ 0ike say a char pointer) C defines a
speoial pointer value that is guara eed trot to point to any
object oi fiuctiotr of that type. Usually, the null pointer
consta used for rcprcse itrg a dull pointer is the integer 0.
Ud WUf" fi" Aff"r.o"" between a null pointer. a NULL macro.- the ASCII NUL character and trullstring?
Explanatiot
A null pointer is a pointer, which doesd't point a[ywherc'
A NULL nla ro is us€d to represeot the trull pointet in source
code. It has . value 0 associat€d wilh it. l
The ASCtr NUL character has all its bits as 0 but doesn'thave any relationship with lhe null pofuter.
The trull string isjusr atrolher oame for aD empty string "".
(l l) In which header file is the NULL rnacro defined.
Explanotioa
, In files "stdio.h" and "stddef.h".
(12)Is the NULL poirti:r same as<Ye$No>
Explakation
No
an uoitritialised pointer?
Ellvironltre set twoof,tlE data segnent and(13) above for details).
(l3)What does the error ..I{ull pointer Assignment, mean andwhat causes this e.rofl
Explanation
The Null pointer Assignment eEor is generated only ia smallard medium memory models. This error occurs in programs,which attempt to cbange the bottom ofthe data ,"gJ;t..-----'In Borland,s C oi C+ compilers, Borland places four zerobltes at the bottom of the data segmetrt, followed bv theBorland copyright ootice ..Borlaod C++ - C"pv"gf,ii;iBodand Intl.". In the small and medium -".ot;;"i;;;null pohter points to DS:0000. Thus assignhg u ;ulu; ;;;memory refer_enced by this pofuter wilt ov;rwri-t" tte nrsi ."ioD,,le In fie data segnent. At progmtD terEination, the fourzercs and rhe copydght bamer arE ch€cked. Ifeithei has beenmo.di fie4 then rhe Null poiDter Assigftretrt error is generated.Note that the oointer may not truly be Du[, bur maibe a wildpolnter that rcferences these key arcas in the data sigrnent.
( I4 ) How do we d€bug a Null poifter Assignment erlor?
Explanation
In the lrtegrated Developmentwatohes- -olre pohting to the bottoEanother pointing to the banne. (refer
1e Undennnding Pointen In C
These wat hes, ed what they should display in the watchwindow, are:
'(char J4,42MS 'Borland C+r - Copydght 19gl Bodand lntl.,(ch ')0 NU|I
Of course, the copyright bamer shown above will varydepending otr your ve$iotr ofthe Borland CyC+ compiler.
You can t)?e the following program and step through yourprogam using F8 or F7 and modtor ihese values in thi witchwindow. At the point wheir one of thern chaages, you havejust executed a statemerf that uses a pointer thai has-not beenprope y initialized.
#inclds 'dos.hi#include 'stdio.h'#nclude 'stirE.h'
main( )(
char 'ptr, 'banner ;
pr: ( char') MK_FP (_DS, 0 ) :banner = ( char' ) MK_FP ( _DS, 4 ) ;
sfEpy ( pt, rhi' ) ;
s[cpy ( banner, 'hello') ;pdttf ( lncood iloming' ) ;
)
Nole that a Null poiDter Assigtrmetrt ermr is trot generaled inall models. Il the compact, hrge atrd huge memory models,frr pointgrs are us€d for data (Refq C-nupte" O fo, -o."mfonytion about m€mory models and far pointers).Therefore, a null poiater will reference 0000:0000, oi tle taseofsystem memory, atrd using it will trot cause a comrption of
Chapter l: An Introduction to pointers 29
the key values at the base of tbe data segment. Modifuing thebase ol systern memory usually causes a system crash,however. Allhough it would be possible that a vrild pointerwould overwrite the key values, it would Dot indicale a nullpojnter. It the tiny memory model, DS = CS = SS. fterefore,using a null pohter will overwrite tb€ beginning of the codesegment.
( I 5) Can anlthing else generate a Null pofuter Assignoent error?
Expla atiot
Yes. using a wild pointer that hsppeDs to reference lhe basearea of the data segment may cause the same error since thiswould change lhe zeros or the copyright bauner Since datacorruption oa staok comrption could cause an otherwise-validpoi[ter to be corupted and point to the base of the datasegment, emy memory corruptioD could resull in this errorberng generated- If the poitfer used itr tfie progmrn slatementthal corrupts_ tbe key values upp""r. to frur"-b""n p-p".iylnitr:lize4 elac€ a- watgh on lat poirter- Srep througn yourFogram again and watch for its value laddressj to chaige,
ICI What do the following declarations stand for?
int *i ;
,loat -i ;
char*k;
voidf(int',chart);floattg(floatt,ioal-);int*h(foat',char-);
b.plahatiot
30 Understanding Poinars In C
I is a pointer to a pointer to a pointer to an itrt.
j is a pointer to a pointer to a lloat.
k is a pointer to a pointer to a pointer to a pohter to a char.
f is a function which receives an itrt pointer alld a charpointer and rctuIus trothing.
g is a function whicb receives a float pointer and a poinler toa float pointer and in fum rehrms a float pointer.
h is a function which receives a flort pointer and a pointer toa char pointer and in tum rcfums a pointer to an itrt pointer.
Chapter I: An I trod ction to Pointers 31
Exercise
(2) mdno{
shar c, 'cc ;'inti;long I ;
ioal t;
i='15;I = 77'177 if= 3.14 ;
cc = &c;pdntf ( trc = %c cc = %u', 'cc, cc ) ;
cc=&;pdntl('bi= gtd cc = %d, *cc,
cc ) ;cc = &l;printf (1nl= %ld cc = %u', 'cc, cc ) ;cc=&l;pdntf ( 1nt = %f cc = %u', 'cc, cc ) ;
)(3) maino
{intcr10,d=m;
pdntfpdntfpdntf
swapprintfpdntf
IA
(1)
I Wtat $r'il1 be lhe output ofthe following programs:
maino
{int a, 'b,
*c, *d, *e ;
a=10;b=&a;c=&b;d=&c;e=&d;pnntf ( 1na = %d b = %u c = %u d = %u e =
you', a, b, c, d, e ) ;
pintf ( 1n%d 96d i{d', a, a + rb, *c + Ed + tre ) ;
)
\We ale in main( )....') ;
lnAddtess orc= %u Address ofd = %u", &c, 8d ) ;
lnBebre srflBp( ). c=Yod d=%d',c,d);c,d);\!Bek b main0....'):\Afldr swaD( ), c=%d d=Yod',c,d);
)
swap (intc, inld ){
pdntf ( lnwe ale in ${ad )....' ) ;
printl ( lnAddless ofc = %u Adrcss old = %u', &c,8d )jpdntl (1nBetore chang€{ ), c = 96d d=yod',c,d);
32 (lnderstan"ding Pointers In C
change(c,d);printl ( "hBack to $rap( )....' ) ;pdntf ( "\nAfier change( ), c=%d d=%d',c,d);
I
change (int q intd )
{intt;
pintf ( '\nwe are in changq )....');printf ( "bAddress of c = %u Address of d = %u", 8c, &d ) ;printf ( \nBefore interchanging, c =
o[d d = %d', c, d ) ;
t=cic=d;d=t;b ntf (\After interchanging, c=yod d=o/d',c,d);
)
. i4) main()(
intc='10,d=20j
printf ( "\nBeforc s!,/ap, c = %d d = 7od', c, d ) ;
swap ( &c, &d );printf ( \Affer suEp, c=96d d=96d',c,d);
)
swap ( int 'cc, int *dd
)
{exchange ( &cc, dd );
)
exchange ( int *cq int *dd )
{intt;
,_cc =
.dd ;
Chapter 1: An Introduction to Pointers 33
'dd = t;)
(5) maino
tinta=5,'aa;
aa=&a;a=power(&aa);printf{'ba = Yod aa=%t,a,aa);
)
power ( int *ptr )
{intbi
b = *pt'*fitr
;
retum ( b );)
(6) maino
{inti=3;foat I = 3.50, 'plod ;float' multiply ( irt float ) ;
pmd=multiply(i,f ); Aprintf ( lnplod = %u value at addess = 7ol, pn2d, 'prod ) ; t
)
ioat ' multiply ( int ii, flo6t ff)t
float producl ;
product=ii'fi;pdntf ( lnprcduct = %l address of prcduct =
o/ou", product,
&product) ;
rctum (&product);
main( )
{char'c = 4000 ;
inl 'i = 4000 :
long .l
= 4000 ;
float 'f =,1000 ;double 'd = 4000 ;
printf ( \E=%u, c+ 1 = %u', c,c +'l )pnntf ( 1ni = %u, i + 1 =%u', i i+'l ) ;
pnntf ( trl= %u, l+ 1 = 9tu', l, l+ 1 );printf ( \f = %u, q-+'l =%u', t f + I ) :
printf ( \d = %u, d + 1 = %u', d, d + 1 ))
maino
{int i= 10, j = 20, difl;
. diff= &j- Ai:pdntf("haddEssofi=%u atffIess oli = %rf, &i, Ej);pdntf ( 'hdtfeGnce ol addrEsses of i and j is %d'r'diff )i
)
main0
{int'i,'jjj=i'2;Pdntf(1nj=o/6u',i) '
)
(10) main0(
int i= 10:pdnf (1llvalueoli=%d add€ss ofi = %u', i, &i) ;
Chapt* l: An Introduction to Pointers 35
&i= 7200 ;printf ( lnneu ydue ofi = 96d neflddless of i= %u", i, &i):
)
(11) floata = 3.14;float *z
;
foal *y jfloat *x;foal *v:float *u,
;
float * tun1 ( ioat ') ;tloat* tun2 (float-);
main( )(
clrsc( );z=tun1(&a)lpnnfr ('VNiA? ,a*zl i
)
;oat*fun1(foatt)(
Y=82;v=fun2(&y);retum (*Y ) ;
)
float -*
tun2 ( float "x ){
w=&x;retum (w);
)
lDl Strte True or False:
)
4)
(l) Multiplication of a pointer and an uDsigred integer isallowed-
{ 2 ) Address of a float cao be assigned to a chlr poiioter.(3) A float pointer alwa]rs cotrtaitrs a whole rumber.(4) A pointer p contaitrs addre$s ofa pointer to a'pointer to an
iirteger pohte.. To reach the integer value we should use
No matter how much time rox hove q)ent with pointers you y,/auldalways l d so,rre application oft that woutd leave yoi guessing.
Sointm antflrays
f he C language providas a capability callecl array that enables
I the user to design a s€t of similar data types. Array is a very
^ popular data type with C progrmrnoers. Tbis is because oflhe convmience with which arrays IeDd thernsolves toprogramming. Pointers and arrys are so closbly related rhatdiscussing arra)r$ without discussitrg poitrtels or vice versa wouldmake the discussion incomplete and wauting. In fact all armysmake use ofpointeE intemally. HeDce it 6 a[ too rclevant to studylhcm togelher rather thaD as isotaled topics.
Understanding Pointers In C
What are ArraysAn Array is a colleotioa of similar elements stor€d in adjacentmernory locatiom. An odirary variable is o@able of storing onlyone value at a time. Howwer, lterc arc situations in which wewould be wantitrg to storc mol€ than one value at a time in a singleva.riable. Supposc vr€ *,ish to store the perEeDtage marks obtainedby 100 studerlts in m€mory. In such a case we have two options tostorc these marks in me.morl4
(a) Constsuct 100 vadabl€s to storE perceDtage marks obtaircd by100 ditrcrent studetrts; i.e. each variable cootaining oneshrdent's marks.
(b) CoNtruct one v{iable (called a subscript€d va able) capableof storing or holding all tlre hun&€d mad(s.
Obviously, the s€coDd alkmative is bett€r. A simple reason forthis is, it would.b€ rnrch easier to hodle orc %dable tharlhaodliag 100 difiem,rt ya.iables. Motsov€r, there arc cartai['logiosthat camot be dealt wilh, witrcut fr€ usc ofa subsctipted variable.
Now a fomBl defiritioa of subccripfed variableg: A subscriptedvariabte is a collcstivc ame give,n to a 8!oup of 'similalquantities'. Thrs€ similt quantities oould be percentage marks of100 studcnts, q salcies of 300 €tqloyccq or ages qf 50
snploycrs. Whst iB iryormt is |iat the quaatitiq must be
'gimilar'. Each menrber ia lhe group is reftrred to by ite position inthe goup. For ereplc, assu@ the following group of nultlbelsthrt repr€s€Et p€rs,coiagc oarts obtaircd by five stuilents.
pEr = { 48, 88, 34, 23, 90 }
If we w.nt to rEfer to ltG s€codd ntElbcr of the group, the usual
nolation used is per2. SiEilady, the foudh rumb€t ofthe group isrefsrrEd as perr. Howwer, io C, the fourh nmber is refsrred as
pcrl3l. Not€ thal, itr C couttirgofeleme s begirs with 0, and mt
L Tlrus. in this example perl3l rEfers to 23 and perl4l rcfers to 96,rn general, the notatjotr would be perJil, where, I cao take a value0.^1, 2. 3,-or 4, depe[ding on the positiotr ofthe elemenr b€iDgrel'erred. Here per is rhe subscripted variable, whereas, I is it!subscript.
A subscripted valiable is also calle.d atr .aEay'. Thus, an a[ay is acollection of similar elemsots. These similar el€m"ot"
"orfJ 6" ufi
Itrts, or all ,lorts, or all chrE, etc. Usually, the array of chrrs iscalled a 'striag', wherras an aray ofitts o; tro.ts i" iaffea
"implyan array. Remembcr that all el€rne s of any givea array musibeof the same tlTe i.e. w€ camot have e adat of l0 mmbers, ofwhich 5 are ltrts and 5 arp floats,
To begin with, like other variables m anay oeeds !o be declarcd,so thd the cotrpiler will kaow wtat tind oim *ray -a m* iargJan afay we waat For exaEpla,
lnt ma*s[30] ;
Hcre, lnt specifies the Orpe of thc v{iablg just ss it do€s wirhordinary ya ables and thr word lnlrltl i! fhe trane ofthe vadable.The aumb€t 30 tells how ooy elcorfias of th€ t p€ ht wil be;our array, This number is ofteo howu as .dimeogioa' of the array.Thc bractct ( [ ] ) trfh lhe coq,il€r that wc are <tealiag with m
To fix oul id€as, let us note &*,r a few facb 8boitt ar.ys:
(r) Aa anay is a collectio! ofsiDila. elcmerb. It is also knowras a subscripted variable.
(b) Before using an array its tpc ad size trust be d€clarcd. Forcxanple,
38
lnt arI3ol ;
M TIOOI ;
char ch[25] ;
(c) The ftlt elemsot io the aray is numbered
element is I less lhatr the siz€ ofthe aray.
Chapler 2: Pointers and -Arralt: r'l
num[] = i '
)
So do rem€rEber tha! ensudog that we do not rcach beyondthe array size is entirely the Eograxnmer's botheratioo and notthe compiler's.
Passing Array Elements to a tr'unetionArmy elements can be passed to a furctiotr by callitrg the furction:
(a) by value, i.e. by passitrg values of array elements to thefunction
(b) by refercnc€, i.e_ by passiag addre*ses ofaray elements to thefunction.
Programs showing how these calls atE made are given below.
l' Pto$am 12'lf Demonstralion ol call by value ./main0(
intiiint ma s[] = ( 55, 6t 75, 56, 7S, 78, 90 ];for(i=0;i<=6;{+})
display(mdksll);l/dlsplay ( int m)(
printf ('h%d', m);lAnd here's tbe output...
0, so the last
(d)
1e) If we so itesiro an aiTay catr be itritialised at lhe same place
where it is declared. For exarple,
int num[6] = { 2, 4, '12, 5, 45, 5 } iint n = ( 2, 4, 12, 5, 45, 5 ) iioat pressl] = { 12.3,342, -8.4, -11.3 }:
(fl Ifthe anay is itritialis€d wherc it is defind mentioning the
dimension of array is optiooal as in second oraqle above'
(g) If the army elemetrts a€ not givetr atry specific valucs, they
are supposed to cotrtaitr ga6age values
(h) In C therc is tro check to s€e ifthe subscript used for an array
exceeds the size of the dray. Dat e'ntered with a Eubscript
exceeding the array size will simply be plaoed in memory
ousiite tie anaft probably oa top of orher data dl ofl the
program itsetf. 'ifris witt load to uprcdiotable results, to 6ay
iheicast, anrt there will be no error messag€ to wam you that
vou are goilg beyond thc array size"In some cases the
iomputer rnay just harg. Thus, th€ following progam may
tum oul to b€ suicidal:
f ProgEm '11 '/main( ){
int num[40], i;for(i=0:i<=100;i+|)
66
0676
42 Understatding Pointers In C
Here, w€ arB passing ao individual aray el€inent at a time to the
tunctiotr dtsplay( ) aod getting it pdnted in the tunctior dtiplay( ).Note that since at a time ody otre elemeot is being passed, in the
functiotr it is collected in a odirary integer variable m.
And mw the call by referenc.e.
f Prcgrarn 13'/f Demonstralion ofcall by lefelence'/main( )(
inti;ini ma s[] = { 55, 65, 75, 56, 78, 78, S0 } :
for(i=0;i<=6;i+)disp (&m*s[ ];
)disp ( int 'n )t
pdntf ( "Vr.rfi', 'n ) ;
)
Atrd h€re's the output...
Chapter 2: Pointen and Arays 43
Here, we are passitrg addrcsses of individual array elements to thefunctioo displsy( ). Herce, the variable in rphioi this addrcss iscollected (n) must be a pohter variable. And sitrce n contains theaddress of array elemetrt, to pdtrt out the arrly element we mustuse the 'value at address' operator (*).
Read the following p.ogram carefrlly. The pu4rose of the firnctionis to just display the arlay elernents on ihe icreea. The program isonly patly complete- you are required to *dte thi iractionshow( ) on yow olvtr. Try your hand at it.
/. Program 14 ./
main0
{int ijint ma*sll = { 55, 65, 75, 56, 78, 78, 90 } ;for{i=0li<=6;i++)
disp ( &marks[] ) ;
)
disp (int.n){
show (An );)
Pointers and Arrays
To be_ able to see what pointers have got. to do with arrays, Iet usfirst leam some pointer aritlmrctic. Consider the foiowingexample:
f ProgEm 15 */
main0
{int i = 3,'x;floa1= 1.5, 1'char k = 'c,, *z
;
56
78
78
90
55657556787890
pdntf('Vtvalue oli= 96d", i);pdntf (Walue ol j= %f, j);pdntf (Walue of k = 9dc', k);
x=&i;y=&j;z=8*;
pdntf ( t\noiginal value in x = %u', x ) ;
prinf ( 1nodginal value in Y = %u'' Y ) ;pdntf ( 'hodginalvatue in z=%tt,zli
pdntf ( lnvrNew value in x = %d, x ) :
printf ( 'hNew value in Y = %u', Y);pdntf ( tNew value in z = %u', z ) ;
)
Suppose l, J and k are storcd itr mernory at ad&esses 1002,
and 5006, the output *,ould be...
Value ofi= 3Value ofj= 1.500000
Valueolk=c
Original value in x = 1002
Original value in y = 2004
Original value in z = 5006
New value in x = 1004
New value in y = 2008New valu8 in z = 5007
Chapt* 2: Pointers and Arrays 45
Observe the last three lines ofthe output. 1004 is equal to originalvalue in x plus 2, 2008 is equal to origitr l value in y plus 4, and5007 is equal to original value in z plus I . This so happens becauseevery time a poioter is inqem€r ed it points to the irunediatelynext location of its tj4,e. That is why, when the integer pointer x isincremented, it points to an addrcss two locatioos after the currgfltlocation, since an int is always 2 b)rtes long. Sirnilarly, y points toan address 4 locatiols after the cunent locatioa and z points Ilooation after the cur€nt location. This is a very important resultand can be effectively used while passing ths etrtire array to afunction.
The way a pointer can be hcremetrte4 it can be deqemented aswoll, to point to ea.lier locations. Thus, the following operationscan be perfomed or a pointer:
(r) Addition ofa number to a pointer. For exarrple,
inti=4,'j,'k;j=&i;j=i't:j=j*9;l=j+3;Subtraction ofa number Aom a pofuter. For example,
lnti=4,ti,'k;
x++;y++ ;
2004
(b)
.8i ;
=i-5;k=j-6;
word of caution! Do not atterEpt Ore fullorrilg operationslnicrs,.. 0ley would nev€r wort out
Addition of two 1,oiotersMultiplying a pointer with a numb€rDividing a pofurter with a atutrbcr
Now we will try to corelate the following two facts. which wehave already leamt:
(a) Array elements arc always stor€d itr contiguous memorylocations.
(b) A pointer wben incremented alwalrs poitrts to an immediatelvnext location ofits qpe
Suppose we have an afmy,
int numl]= { 23, 34, '12, ,14, 56, 17 };
The following figure shows how this array is located in memory.
Chapter 2: Pointers and Anayq 4Z
pintf ('addrcss= %u', &numll) ;i*j
)]
The output ofthis program would be:
element no.0 address =,1001element no. 1 addrcss = 4003element no.2 addEss =,{005elemenl no.3 addBss = 4007element no.4 address = 4009element no.5 addEss = 40'11
Note that the aray elements are storcd in oo[tiguous memorylocations, each element occupying two b/tes, since it is an integeiaray. When you run this programr you may get differentaddresses, but what is promised is that €ach subiequent addresswould be 2 b)'tes greater than its immediate Eedecess;r.
Our next two pograms show two ways in which we can access theelements ofthis array. The fitst on€ uses the subscript notation.
f Pto$anj7 'lmain0(
inl numl] = { 24, 3d, 12,44,56, 17 };inti=0i
while (i <= 5)(
printf ( '\naddrcss = %u ', &numfl ) ;prjntf ( tlement = %d', numlil ) ;l++ ;
)
Figure 2.1
Herc is a program that prints out the memory locations in whichthe elemenls ofthis aray arc stored.
f Program 16'/main( )
tint nunll = 124,U, 12, 44,56, 17 | iinti=0;
while (i<= 5){
printf ( \elementno. 96d ., i ) ;
23 34 t2 44 56 t7
400 4003 ,1005 4007 4009 4011
48 Understanding Point*s In C
The output ofthis prcgram wottld be:
address = 4001 element = 24
address = 4003 element = 34
address = 4005 element = '12
address = 4007 element = 44address = 4009 demem = 56
address = 4011 elemenl = '17
The next method accesses the array elemeDts using poioten
/'Program 18'imain( )
{int ntim[] = {24,34, 12,44,56, 17 };inti=0,-j;
j = &numl0l ; f 6lign address o, zelofi elemenr *l
while(i<=5){
printf ( 'haddrcss = %u ' , &numll ) ;
pdntf ( "element= 96d', I ) :
i++ ;
j++ ; f increment poinler b point lo ne* Iocalion '/)
lThe output ofthe program would look like this:
address = 4001 element = 24
address = 4003 element = 34address = 4005 element = 12
address = 4007 element = 44
addrcss = 4009 element = 56
address = 4011 element = 17
Chapter 2: Pointers and Atays 49
In this piogram, to begin with we have colleoted the base addressof the array (address of 0s element) in the va.iable j using thestatement,
j= &numlol; f assigns addr€ss,Oo1 b j'lWhen we arc inside the loop for the first time j contains theaddress 4001, and the value at tlds addrcss is 24. These are printedusing the statements,
pdntf ( \address = %u ' , &numfl ) ;pdntf ( "element = %d',I );
On inqementing j it points to the next mernory location of its O?e,that is location ao. 4003. But location number 4003 contains iheseoond element of the array, therefore when the prltrtf( )statements arc executed for the second time they pdnt out thesecond element ofthe array and its addE$s (i.e. 34 and 4003). Thisoontinues till the last element ofthe array has been p nted.
Obviously, a questioa arises as to which oflhe above two methodsrhould be used when? Acce$sing a.I:ray elemeds using poir!\!!yq faClgl th!4 qno€ssftg lhein ljr subscripts. However, ftom-lhc point of view of convenience inligramming we shouldobserve the following:
Anay elements sholld qe accessed using pointers, if the elements
t!!.19-!Eg!!!!99r4 a fixed order, sav &om be EiniGind. orCof end to besinnliE, or=-ry d temenrrldfinite logic.
r lt would be easier to access the elementjfgilgj lubrDriptjfltrEre,b@"u."llrc, accessing the elements by pointeN would work faster than
r atr ltsc ripts.
Undersnnding Pointers In C
Passing an Entire Array to a F unction
Earlier we saw two programs one m which we passed individualelemeds of an array to a firnctio4 and another io which we passed
addresses ofindividual €lernents to a funotion. Let us now see howto pass the entile aray to the function rather tha[ individualelement.s. Consider the following exarple:
f Program 19'/main0
tint num[] = {24,3'1, 12,,14,56,17};display(&numlol,6);
display ( int'j, int n )
{inti=1;while(i<=n)(
Pdntf ('VElemenl = 9dd', l ) ;i++;j++ ; f increment poinbr b pointb next localion ?
))
Here, the dlsphy( ) frmctioa is us€.d to print out the arrayelemeffs. Note that addre$s of the zcmth elsn€ is bciag passed
to the dlsplry( ) fitnction. The while loop is same as th€ oDe uledin the eadier prograri to access lhe array elernents using pointers.
Thus, just passing.lhe address ofthe zeroth elemeDt ofthe array toa furction is as good as passiry tbe entire aray to lhe firnctionr Itis also necessary to pass the total number ofelements io the array,otherwise lhe dtuphy( ) fi.mctioo would not know when totermjrEt€ tte vhlle loop.
Note that $e addrcss of the zercth element (often klown as thebase addrcss) can also be passed by just passing the name of theanay. Thus, the following two function calls are same:
0qisplay(8num[0],6];\/isplay(num,6);
The Real ThingIf you have g$pg{ the concept of storage of aray elements inmemory alrd the arit metic ofpointeG, here is some rcal food forthought. Once again coNider the followi[g aray.
4001 4003 ,1005 AOM 4009 4011
50
Figre 2.2
This is how we would declarE the above atray in C,
inl numll={23,34, 12,44,56, ,t7};
We alread_y, know tbat oa meotionilg the name of the array we getits base address. Thus5 by sayhg raum we would be able to r*erto the zercth clement of the arfif,-ilralTfZf GeraD-Easi[sEethat *truE a+L1fl![.+ql!q!Lr€Gr
!o Z:. SimiUay, Uy saying'( Ium + I ) we cat! rrf€t to firstat,ndDt of t[e array, that is, 34.In facl tlis is what &e C comller iniemally does. Wieo we-say,num[il, the C compiler iatcrDally cotrv€{ts it to *( num + I ). Thismealts th.t all the followin€ ootatiotrs at€ !ame:
numliJ
'( num + i)
52 (lndersnnding Pointers In C Chapter 2: pointers and Arrays 53
l1
-ii+num)
ilnuml
And here is a prcgram to prove my poht.
f Pmoram 20 '/f Acc-essing anay elements in difierent ways
ti
main( )
{int numll = { 24, 34. 12,44,56, '17 } :
inti=0;
while (i<= 5){
pdntl ( \address = %u ' , &numll) i
printf ( 'element = %d '. num0 ) ;
pdntf ( '%d ', '( num + i) ) ;pnntf ( 'Yod ', '( i + num ) ) ;
printf ( 'Yod', ilnuml) ;
i++ i
))
The output ofthe program would look like this:
addrcss=400'f elerrefi.=z4 24 24 24
address = 4003 elemeot = 34 3}1 34 34
address = 4005 ehrnefi= 12 12 12 12
address = 4007 element = il4 '14 '14 44
address = 4009 element = 56 56 56 56
address = 4011 *n,e,rt= 17 17 17 17
More Than One Dimension
So far we have looked at arrays with only one dimensio[ It is also
possible for arrays to have two or more dimensions The two;
diftensional array is also called a mafix. Here is a samnleprogam rhal initialises a 2-D array and print, orai;.1".;"; ""''
f Prcgrcm21|'tmaino
{int stud[s][2] = {
11234,561,1t212,331,{ 1431, 80 },11312,78),11203,751
);int i, i;
for(i=0;i<=4:i++l{
prjntf(h,);,or(j= 0i j<= , j++)
pdntf('yod .,stud[m);
l)
Look ar rhe pritrtf( ) statemelt...
printf ( 'Yod ', studlr[l ) j
11, "+lltt{] fie trIsr subscripr is row nunber. The secondEuDscnpl te s wbich ofthe two colurDtrs arE we talking about... thi11oth c9tryn or_the frst colum- Rem€mber tfr"i".rrti'og oimws and columns begins witb zem.
Thc complete array arrangerneat is sho*n hlour
54 lJnderstanding Pointers In C Chapter 2: Pointers and Arralts 55
oan be thought of as setting up a ooe-di!0€osiotral array of 5
elsments, each of which is a onedimeDsional array 2 eleme s
lorlg. We ref€r to an element ofa onedimeasional aray usiog a
iingle subscript. Similarly, if we oatr imagirc Eaud !o be a ore-dimensional array then we can rcfer to its zeroth element as
stud[0], the next elsment as EtudEl ard so on. Mo!€;speci6cally,if we execute the stal€ment
printf ( '0.6u", studlo] ) ;
we expect the Od elemetrt to get priated aod tbe 06 elernent is a 1-
D anay. We know that just m€trtiodry a l-D array gives its base
address. Herce the printf( ) would print base ad&ess of the 0d l-D anay. Similarly, stud[l] would give address of lr l-D aray and
so otr.
This fact can be illustrated by the fo[owing program:
.r Pl0onn22'l. /f ReferfgurB 2.3 given in 0E pGvixBsectbn'/\Vl maino
Lt' in, rtuotsltzl= (
( 1234.56 ),11212,331,{ 1434, 80 },{ 1312,78},
{ 1203, 75 }];
inti,j;
for(i=0ii<=4;i+i)pdntf ( "hAddress o, ,6d fi 1D any = l6u', ;, sM[l 1 ,
)
And here is the output...
Address of 0 th l-D aray = 4001
Figure 2.3
'I1rus. 1234 is storEd in stud[0][01,56 i8 stored iD studlollll and
t" "o.
fnt above arraogcment highlights the hct that a-two-
dime[sional array i6 trothing but a collection of a number of one-
dimensional arrays plaoed orc after oother'
Rememb€r that the alraryem€|trt of r 2-D array into row and
,oi.".a i" oaly conceptually ttue' This is because in memory
tfr"." "*
no -tit *A cohoms' to memory whe&er it's a l-D or a
i-o "r-y
At at-*ta are stolpd in one continuous chain'
Pointers and Two Dimensional Arrays
Catr we not tef€r elem€Dts of a 2-D afiay usitr8 poinlEr notatioil'
the wav wc did itr ooe{imeDsioDal anay? ADswer is y!s' only me
prociure is slightlv dimcdt to urderstand- t'et us see how'
The C language embodies e uousual but pow-€'rful capability: it
".n treat pirrs of an anay as aEays' MorG 4ccifiGally' each rortr ot
,**"--a]i.*i"J "t-i' * & thought as a one-dimensioDal
arrav. Ihis i8 a very iEportaut fact if we wish to access aray
el#ents of a twodimersioul array using pohters'
Thus, fie declaration,
' int stud[51t2] ;
56 Undersnnding Pointers In C
Address of 1 th 1-o aray = 4005Address of 2 th 1-D aray = 40 )
Addrcss of 3 th 1-D aray = 4013Address of 4 th 1-D an-ay =,1017
Let's figure oul how the progmrn works. Once the 2-D array isdeclared, there orwards stud is aeated as poirter to zeloth element
of the 2-D array. Heoce the exprglgiorL4itud-+-0 L€iles tN theed.iress of Ge 0" elemeot of Ee 2-D aray. Naturally. lheadrl'ess of the 0d elemeot of the 2-D atay,
I element. But the Orh
elemefi ofthe 2-D array is a l-D aray- And on mentioning l-D
would givs base addtEss oft- l-D anay.
'(stud[2] + 1 )'(-(stud+2)+1)
Using *ese concepts the following Eogram priDts out eachelement of a two-dimensional aray using poirter notation.
f Pnlftn23'lmain0(
int studl5ll2l = {{ 1234, s6 },11212,331,{ 1434, 80 },{1312,781,{ 1203, 75 }
),inli,jj
for(i=0;i<=4;i++)t
printf("h');for (j= 0;j<= 1 ;.i++)
. printf("70d','(-(stud+i)+j));l
)
And here is the oiitput...
array we get its base address. Heqqg j(!]E4! jllLLtygqlhe base
addrcss ofthe 06 l-D array. Referring to Figure 2.3 this rums oulio be 4ffiI:Timilady, caD you interpret the meaning of studlll(which is nothiDg but *( stud + I ))? rtud gives address ofthe 0d
elem€nt, herce st d + I worl.l give lhe adjress of the ls' element
and r( stud + I ) would give lhe first alemeEt. Since the l"'element is nothilg but a l-D array, and on mentioning the l-Darray we get its base ad&€ss, *( stud + I ) gives base address of lsr
t-o,arravW))
Now, we have beetr able to reach e3ch hdividual row. Whatremains is to be able to rcfet to itrdividual elernenrs of a rcw.Suppose we want to rEfer to the elerneDt $hd[2][U using pointers.
We know (Aom the above program) that stud[2] would give the
ad&ess ,1009, the address of lhe second one-dimensional array.
Obviously ( ,1009 + 1 ) would give the sddEss 4011. Or
Gtudt2l+f) would givG lhc addr€ss 4011. And the value at thisaddrcEs cari be obtaircd by usitrg the exPr€ssioo '( stud[2] + I ).But, we havc alncady mt€d wtilc learuing l-D &rays that numlll
1234121214341312.l203
80
7875is sam€ as r(E!n + l). Simi :( ttd[2] + l) ie same as,
6ffissions referio the
srtdt2ll1
Pointer to an ArraY
The way 1,,e cao have a pointer to atr integ€i, or a pointer to a float,
"u, *" ulio have a pohter to an array? The answer is yes
Declaration of a pointer 1o atr array, however, is a little clumsy
For examole. the declaration Lrt ( *q )l4l Eeans tbat q is a poitrter
,o on orr& of4 itrtegers. Let us use this pointer to an army in a
Eogram. Herc it is. . .
I Pmgram 24 '/main0
{iit alll4l= {
5,7,5, 9,
4, 6, 3, 1,
2,9.0,6);
p=(int )a;q=a;
pdntf ( 1n%u %u', p, q ) :
p++:
pdntf ( 1no/ou %u', P, q ) ;
)
whereas, q statts pointing to the text 1-D aray of 4 integers.Poilter to an array is very usefirl while passiag a 2-D array to afurction, as we nould s€e in the next sectioa.
almv to a
1,2,3,4,5, 6, 7, 8,
9, 0, 1,6int'p;int ('q )l4l ;
And here is the output...
65500 65500
65502 65508
To begin {.ith both p and q contain the same address 65500'
However, p is an io&ger pointEr, whercas q is a pointer to an array
of4 intege$. Heoce on incremetrting p it pohts to the next iirteger,
Passing 2-D Ariay to a Function
There are thtee ways in which we can pass a 2-Dfunction. These at€ illustrated iD the following program.
f Program 25 '/f Three ways of accessirE a2-D a,ra(.'l#include <alloc.h>
main0(
int aB[ ]E_ {
);
clrsc( );disphy (a,3,4);show ( a, 3,4 ) ;pdnt(a3,4):
)
display ( int 'q, in row ir[ col ){
inti,j;
for(i=0;i<rcy;i++){
for (j = 0;j<col;i++)Pnntf ('old',' ( q + i'col +i ) ) ;
printf('\n');)
60 Understanding Pointets In C Chapter 2: Pointers and Arravs 6l
123456789016
123456789016
In the displd ) ftactioa we have collected the base address of the2-D array beiag passed to it in an odinary itrt pointer. Thenthrough the twoJor loops using the expression * ( q + i * col + j )we have rcached the appropriate ele rent in the arty. Suppose iisequal to 2 aod j is equal to 3, then we wish to reaih thi elementr[2] J3l- Let us see whe6er the expression * ( q + i * col + j ) doesgrve thrs elemenr oihol Refer Figure 2.4 !o uDderstand this.
printf (1n' ) ;
)
show ( intfq)141, int roll, int col ){
inti,j;int'p;
lor ( i= 0; i< row;ir-i ){
p=q+i;for(j= 0;j<col;j++)
pdntf ( Yod ', ' ( p+j) ):
pintf (t');)prinlt('\n');
)
pdnt ( i;t q[ ][4], int Dw int col ]{
inti,ji
for(i=0;i<rorv;i++){
fq(J=0;j<cot;j+)pdntr ( '96d ', q[][! ) ;
pdntf('Vr');)pdntf("h');
)
And here i$ the output. . .
123456789016
4001 4003 4005 4007 4OO9 40tt 4Ot3 4Ot5 4Ot7 4}tg 4O2t 4021
Figure2.4
l'he expression * ( q + t * cot + j ) becomes * ( 400f + 2 * 4 + 3 ).'l'his tums out to be * ( 4001 + ll ). Since 400I is address of aninleger, * ( 4001 + tl ) tums out to be * ( 4023 \. Value at thisoddress is 6. This is indeed same as e[2][3]- A more generallbrmtrla for accessing each array element would be:
r ( base address + row no. t no. o, columns + column no. )
ln the show( ) function we have defined q to be a pointer to anlnay of 4 integers through the declaratiorx
(Jnderstanding Poinlers In C
int (.q )lal ;
To begin with, q irolds the base address of the zercth l-D array,
i.e. 4O0l (rcfer Figure 2.4). This addrcss is then assigned to p, an
int pointer, and then using lhis pohter all elements ofthe zercth I -
D alay are accessed. Next time thrcugh the loop when i takes a
value lf th€ exprdssion q + i fetches the address of tho first l-Darray. This is because, q is a pointq to zercth 1-D anay and
addilg I to it woutd give us the addEss ofthe next l-D alray. Thisaddress is once again assigned to p, and using it all elements of the
next l-D aray arc accessed.
In the third tunction print( ), the declaration ofq looks like this:
intqll[4]:
This is same as int ( rq )[4], vhere q is pointsr to an array of 4irltegefi. The only advantage is that we can rrow use the morefamiliar exEession q[il [] to acce$s array eleEreflts. We could have
used the sarne expEs$ion in show( ) as well.
Three Dimensional Arrays
Consider the following array declaration:
int a[3]l4ll2l = {{
12,41,{7,8 },i3' 4 ).i5,6 )
Chapter 2: Pointers and Atays 63
{2,3}),{
(8,e)'17,21,{ 3.1},{5,1}
));
Here a is a 3-dimensonal array- A 3-D array can be thought of as
an array of arrays of airays. The ouler allay has three elements,each of whicb is a twodimensional aray of four rows. each ofwhich is a one-dimemional array oftwo elemehts. In other words,a onedimeosiona!_array oftwo eleDents is constructed first. Then
four such ooe-dimeisional arrays are placed one below the other togive a two-diDensional aray containing four rows. Then. threesuch two{imeDsioD4 arays are placed ore behind the other to
leld a theedidensional aray containing three 2-dimensionalarrays. In the array declaratioo note how the commas have beengiven. Following figune would possibty help you in visualising the
situation better.
xd 2-D Alray
tn 2-D kr.yon 2-D Array
62
),
{{7,6 },i3,4 ),i5,3 ), Figure 2.5
64 Understanding Pointen In C
Again remember that the arangement shown above is onlyconoepfually true. In memory the sauE aIlay elemeats arc storcdlinearly as shour in the follorring figure.
Figure 2.6
How would you reler lo the array element I in the above array?The first subscript should be [2], since the element is in third two-dimensional army; the second subscript should be [3] since theelement is in fouth row of the two-dimensiotral array; and thethird subscripl should be [l] since the element is in the secondposition in tie on€-dimensional a.ray. We can thercfore say thatthe element I can be referred as, arrl2Jl3Jll I. lt may be nored herethat the countirg of alray elements even for a 3-D array beginswirh zero.
Can we not rcfer to elements of a 3-D array using the pointernotation instead of the subscript notation? Certainly. Let's firstbegin with a simple Eogram-
/t Program 26 -/
maino{
int aPl[3][2] = {{
{2.41,17.8'^).{3,4}
],
];printf ("\n%u", a);printf ( '\nolou', .a
) ;printf ( 'b%u', -a ) ;.pdntf ( lno/od', *a
) ;printf('ho/ou',a+1);p ntf { '\n%u', 'a + I );kL\printf('h%u', *a + 1);\ \'printf {"\n%d',
*a + 1);j .
)
Figue 2.7 shows the arangcment ofthe 3-D aray in memory.
Figure 2.7
And here is the output ofthe prografi...
.l04
t0rt0{'Iiltt0rt0r
{2,2},12.31,{3,4}
06 2-D arlzy-+- t, 2-D array
21417 8 3 4 2 2 2 3 3 4
104 106 loa ll0 ll2 ll4 116 I18 120 t22 124 126
66 IJnderstanding Pointers In C
J
Referring Figure 2.7 it's not difficult to imagirc why the firstprtntf( ) pdtrts out 104. However, the outsut of second and thftdpritrtf( ) is a little supiisiry. Let's try to undflstaod it
Each element ofa 3-D au'ay is a 2-D aEay. Once the 3-D aray i8deolared a is treated as poh&r to zercth eleiaent of the array.
Hence *a gives the zercth element whioh is .2-D array, We knowthat on mentioning a 2-D array we get its base address hence the
second pri f( ) outputs 104. what about tfre exprEssion **e? *rgives poiater to zeroth element of the 2-D an'ay, h€na€ **a wouldgive the zeroth eleme . But the zetdflr elernent ofthe 2-D aEay isa 1-D array. And oa mentio[iog l-D array we get the addrcss of itszeroth elemeot, Heace **e also yieltts 104. Now you can guess
that ***a would give the €lernent at ad&ess lo4, i.€. 2. Let's Dow
try to alalyse the output ofthe next prirtf( ) statement a gives the
aidr".r oi znroflr i-D arra% therefore, . + I would give the
addrcss of fiIst 2-D aray, which as per the fgure is 116. Can you
now imagine the output ofthe rcst ofrhe prhtf( )s? Try it.
),
{
Passing 3-D Aray to a Function
There are thrce ways i4 which we oatr puis a 3-D atray to a
function. These are illustrated below.
f Pmgram 27 ./
f Three ways of passing a $D anay b funclixl '/main0(
int i, j, k;jnt a[2]Pl[4] = {
{1,2,3,4,5,6,7,8,9,3,2'1
2,3,5,7,4,3,9,2,1,6,3,6
]);
clrcc( );display (a,2,3,4 );show (a, 2, 3,4 ) ;
print (a,2, 3,4 );getch0;
)
display ( int rq, int ii,
'nl ii, int kt )
(int i, j, k;for(i=0;i<ii;i++){
br(j= 0;.i<X; j++ )(
for(k=0;k<kk;k+t)pnnf ('%d','(q + i'jl'kk+ j'kl+ k) ) ;
printf ( 1ll" );)printf(1n');
)pdnf ( 1n" ) ;
)
show ( inl ( -q )Bl[4], irf ii, imii, int kk ](-
int i, j, k;int'p i
for(i=0ji<ii;i+r)t
for(j=0;i<ji;j++){
p =c[][];for(k=0;k<kk;k+)
Pdntf ( '96d ', '( P + k) ) ;printf( 1n' ) ;
)printf('1n');
))
/ print ( int q[ ]l3l[4], int ii, inl ii, int kk )"r'1
int i, j, k;for(i=0;i<ii;i++){
forlj=0;j<ii;j++){
for(k=0;k<tk;k++)pdntr ( %d '. q[]D[{ ) ;
pnff (\l" ) ;
)pnnf('1n') ;
))
And h€re is the output...
123 45678932'l
235743921636
12945578
Understanding Pointers In C Chapter 2: Pointers and. Arrays 69:
932'l
4392IOJD
123456789321
23574392'I 636
The wotking of lhis progre ir same as that of kogram 25discussed earlicr. HeDcc all ftar I yrduld do here i,s explain how qhas been declared in each fimctiol
Table 2.1
Returning Array from FunctiinNow that we tnoq, how to pass a 2-D ot a 3-D aray to a firnotion,let us find out how to r€tultr a,l array ftoItr a fuDotio[ Therc areagain three methods to aohieve this. Suppose we wish to retum a2-D anay of integers from a function we caa rcfum the baseaddrcss ofthe array as:
- A pointer to an integer
- A pointer to the zeroth l-D array- A pointer to the 2-D aray
41lq )t3lt4l 'qis a poitrb to a 2-D snv of3 rows md 4 columns
iDt qt lt3l[4] q is a]6iqt€I ro a 2-D sray of3 rows ird 4 coluotrs
This is shovn in the followitrg ptogram. The firdctior futrl( )reltrms the base addrcss as pointEr to integor, the function fuD2( )rgturns it as pointer to zerolh l-D aray, whereas fun3( ) retums itas pointer to 2-D array ofhtegeN. Note the prototype declarations
of the functioDs caefi ly.
f Prcoram 28 '/I Th;e ways of lBtuming a 2-D aray tun a funclion
*/
#defne ROW 3
#defne COL 4
main0
{int i, i;
tint'a;.int'tun10:
int ( 'b )ICOLI;iirr ('f,ii'20 )poll;int
-p;
int ( 'c )lRowlpol-l :
int ('tun3( ) [RoWIcoLl ;
cllEc( );a=tun10;
pdntf ( hAray allll in mai( ):W ) ;
lor{i=0;i<ROW;i+r)l'
for( i= o;i< coL:j+)printf ('%d';'(ar i'col+ j )) :
pdntf(1r'');)setch( ) ;
b = fun2( ) j
printf ( "\nArEy bl l[ J in main( ):h. ) ;for(i=0;i<ROW;i++){
p=b+i;for ( j= 0; j< COL 'i++ )t
prjntf(t/od',.p);p++;
)
pnntf ( "Vr') ;
)getch0 jc = tun30;
/printf ( "h&ray d l[ I in mdn( ):W ) ;for(i=0;i<ROW;i+[){
for(j=0'j<COL.++)pdntr( %d., (.c)[ilUI) ;
pintf('\rf);)getch0 j
)
Int.fun10(
shlic int alRowlmrl = (1,2,3,4,5,6,7,8,9, 0, 1,6
);inti,i;
"2 Understaading Pointers In C
pintr ( lnAmy a[ [ I in tunl( )M );for(i=0;i<ROIIV;i++){
tor (i = 0;i< COL 'i++ )pintr ( 'r6d ', al i lli I ) ;
pintf( 1n' ) ;
)retum(int.)a:
)
int ( 'tun20 )lcotl{
shtic int blRoll'{mq = { .
9.4' 6' 4,1,3'2'1,7'5, 1'6
);inti, j ;
pdntf ( tAray bt l[ I in tut2( )rtr' ) ;
for(i=0;i<Rqw:i+l){
tu (i= 0; i< col;F )pintf ( *r6d
" btilil );
pnntf ( t');)rctum b;
)
int ('fun3( ) )[Rou,tPOLl{
static int ctRolfulcou = {6. 3, 9, 'l'2,1'5,7,4,1,1,6
):
Chapter 2: Pointers and Arrays 73
inti,j;
printf ( 'hA;y cl II I in tun3( ):h' ) ;for(i=0;i<ROW;i++){
for(j=0;i<COt;j++)printr('Y!d', cl i ltj I ) ;
pdntr ( 1n');)retum ( int (' )[ROl'vllCOL] ] c ;
)
And here is the output- . .
Aray a[]llintunlo:123456789016
Arlay al l[ ] in main( ):123456789016
Anay b[][] in luo2( ):94641321
Anay b[][]in main( ):946413217516
Anay c[][]in tun3( ):63912157
lJ"dntnndl!E!9!!!9o I" C
-
Chqtei 2: Pointers and Arrays Z j
4116
Aray c[ ][ ] in main( ):63S'l21574116
Returning 3-D Array from a Function
lf you have undelstood how to retum a 2-D aray ftom a functio[,
on similar liaes wc can rclum a 3-D array ftom a functioa The
four possible *ays to do so would bG to retum the base address as:
- A pointq to ali integer
- A pointer to ihe zeroth l-D array
- A pointerto the zercth 2-D array
- A poitltcl to the 3-D ariay
Given below is the pDgram, which ifiplemeDts these four ways ofretuming a 3-D array.
f Program 29 '/f Four ways of retuming a $D aray film a funclion
.l
*idefne SET 2
Itdefne ROW 3#deline COL 4
maino
{inti,j,k;
int'a;int-fun'lO;
int ( .b
)lcotl ;int ( 'tun20 ){coLl :
int ( 'c )lRO\aTCOLl ;
int ( 'tun30 )lRol'uporl;int.p;
int ( 'd )lSEIllRoW[coLl;int ( .fun40
)lsEr]lRovupoLl;
clrsc( )ja = fun10;
pdntf ( lnAnay a[ I[ [ I in mai( ):W ) ;
for(i=0;i<SEI;i+i){
for(j= 0;i < ROW; j++ ){
for (k = 0;k < COL;k+r,/pdntf('96d','(a + ir RCIW'COt +j. COL + k )) j
printl ( 'h') ;
)
pdntf(1n');)getch0;
b = fun2{ ) ;
printf ( '\nAn-ay b[]Ull in mJn( ):h' ) :
fol(i=0;i<SET;i++)(
p=(inl,)(b+i.ROlfl);for(j= 0;i < Row;.1++){
for(k=0;k<COL;k+r){
pdntf ( '%d ., .p ) ;
p++;
76 Unilerstanding Pointers In C
)
pnntf (1n');]
pintf('h');)
ttro;c = tun30;
pddtf ( '\nAray c[ ][ ][ I in main( ):W ) :
for ( i = 0; i< SEI; i++ )(
p=(int')(c+i);for(i=0;j<ROW i+t )I' for(k=0;k<COL;k+[)
{pnntf ( '9{d ', 'P ) ;
p++;
)
pdntf ( 1n') ;
)
pnntf (\l') ;
)getch( ) ;
d = fun40 ;
p ntf ( 'hAray d[l[l[] in main( ):W ] ;
for (i= 0 i i< SET;i++ )
{for (j = 0 ;j < ROI,V ;j++ )(
Chapter 2: Pointers and Arrays 77
for(k=0:k<COL;k++)pdntr('%d ', (-d )[i][i l[ k l);
pdntf ( 1n');)
printf("\n");)getch( ) ;
)
int. tun10{'
inti,j,k;static int alSEIllROVtIllCOLl = {
{
));
pdntf ( "hArmy a[ ]l lll in tunl( ):Vr' ) ;for { i= 0 ; i< SET; i++ }{
for (i = 0 ;j < ROW; j++ ){
for(k=0;k<COL;k++)printr { '%d ', ali ltj llk I ) ;
printf(ln'):)
1,2,3,4,5,6, 7, 8,
9,3,2,1
2,3,5,7,.4,3,9,2,
't, 6. 3. 6
),{
78 Understanding Pointers In C Chapter 2: Pointers and Arrays 79
pnnf{'ln'); int (.fun30 )lROltlFOLl){
int i, j, k;retum (int')a; static int clSETllRoWllC0[]= {
)(9.4. 6. 4,
int ( 'fun2{ ) )ICOLI 1,3,2,1,{ 7, 5, 1,6
inti,j,k; ),static int blSErllROWllCOLI= { t{ 6,3, e, 1,
9,4,6' 4, '2,1,5,7,
1,3,2,1, 4, 1, 1,67, 5, 1,6 )
), );{
6, 3, 9, I , printr ( lnAmy cl l[ l[ I in tun3( ):\n' ) :2,1,5,7, for(i=0;i<SEl;i+t)4, 1, 1,6 {
) for (j = 0 ;j < ROw; j++ )); {
for(k=0;k<COL;k++)printr ('\nArEy b[][][in tun2( ):h'); pinf('%d', clilU ][k]);for(i=0:i<SET;i+I)( prnrf{ln');
lor {j= 0;j< ROW;i++) }(
lor ( k = 0 ; k < COL; k+I ) printf('\n'):printf ( '%d ', bti[i]lkl]; )
pdntf('\n');] retum ( int (.)lRotrt4lcotl ] c ;
Ipinf ( 1Il');
) lnt('tun40 )lsErllRorulcoLl(
retum (int {')[COL])b; int i, j, k j
l slatic int dlSE IllROWlCoLl = {{
80 Understanding Pointers In C Chapter 2: Pointers and Arrays 8l
));
printr ( "\nAray d[ ][ ][ ] in tun4( )ln' ) ;
. for ( i = 0 ; i < SET ; i++ ){
lor (j= 0;j< ROW jr+){
lor(k=0;k<COL;k++)pintf ( '96d ", dliltjllkl);
pdnd(tu");)
printf('Vr');)
return ( int (t )lSEIllROWlcoLl ) d ;
)
And n"ere is the output...
Aray a[][][] in tun10:123 4
56789321
23574 3921636
Aray a[][][] in main( ):12345678932'l
2357'43921636
Anay b[I][Iin tun2( ):9464132175't 6
639121574116
Anay b[][][jin main( ):9464'13217516
63912't 574116
Anay c[]ll[]in tun30: ,
318506522016
7 32714230106
Aray c[][][]in m;in0:
),{
3, 1,8, 5,
9, 6, 5, 2,
2,0,1,6
7,3,2,7,1,4,2,3,'9, 1,0, 6
i
82 Understatding Pointers In C Chapter 2: Pointers and Arrays 83
318596522016
7 32714239106
Aray dll[]ll in tun40:170523915116
cJ I /1423
Anay d[][][]in main( ):170523915116
531714237 216
Array of Pointers
The way there,can be an array of ints or an aray of floats,similarly there can be an array ofpointe$. Since a pointer variablealways ooatains an address, an array ofpoiaters would be nothingbut a colleclion ofaddrEsses. lae adclresses preselrt in the alray ofpointers oan be addresses of isolated variables or addresses ofarray elemerfs or any other addresses. All rules that apply to anordirDry array apply in toto to the array ofpointeN as well. I thinka prograrn would cldiry the concept.
f Pmgram 30 .imain( )
{int 'ar[4] ; f fiay of inhg€r poinbls '/int i= 31, j= 5, k = 19, t= 7t, m .
an[0] = Ai;an[1] : &.i 'anl2l = &k;art3l = &l ;
for(m=0;m<=3;m++)pdfltf ( 'h96d', '( adml) ) ;
)
Arld here is the ou&ut...
31
5
71
0'
kl
l-,,1 l--;l l--rl l=-l4008 5116 6010 7I l8
ad01 adll a"IL2I
4008 5116 60lb )r ra
7602 7@4 7@6
ant3l
Figure 2.8
Understanding Pointers In C
Figure 2.8 shorns the contents atrd the arangement of the array ofpointeN in memory. As you cal obwrve, arr contains addresses ofisolated lDt variables i, J, k and l. The for loop in the plog1am
picks up the addresses present in arr ard pdEts the values prcsent
at these addresses.
An array of poiaters can evetr contain the addresses of other
arrays. The following plogram wouldjusti! tltis.
/' Pogram 31 '/maino
tstatic int all = { 0, 1, 2, 3, 4 };shtic int'p[] = {a, a + 1, a +2, a +3, a+4 };
printf ( ln'/ou %u 96d', p, 'p, '( 'p ) ) ;
)
I would leave it for you to figurE out the output of this program.
An array of point€rs is very popularly us€d fol sioring several
strings in manory, as you would see in tlre next chapter'
Dynamic Memory'Allocation
Coosider the array declaratioi,
int ma*s[100];
Such a aleclaEtion would typically be used if lqoinldent's marks
were to +e stored itr memory. The moment we make this
declaration 200 bytes aIe rcseped in memory for stoling 100
integers in il HowEver, it may so happen that when v/e actuallyrun thd program. we might be inteEsted in storing only 60
student's marks- Even in this case 200 bytes would 8et reserved inmemory, which would result in wastage of memory.
84 Chapter 2: Pointers and Arrays 85
Other way rouad there alwa]rs exists a possibility that when yourrn the program you Deed !o store more ihatr 100 student's marks.In this case the aray would fall short in size. Moreover, llpre is noway to inqease or decrease thqauay size-dudng-crGeq![q4-!t][ theprogram. l, other words, wheo we use rmys statil memorval.J99g!9!-!4Eq_p&qe. What if we wart to allocate niemory only atrhe dme of executioo? This -is datrc__Jsl[g* standard [traryfurctions mill^.( ) and catloc(J. Since these tunotioos allocatememory on the- fly (during executiotr) they are-often tno",t1 as'Dyramic meinorjr allocation functions=) L6t us now see aprogram, which uses the corccpt ofd)mamic memory allooation.
f Program 32 ti
#incude ?lloc.h'main0{
hl n, avg, i,-'p, suo = 0;
pintf ( \Enter tle number of studenb ' ) ;scanf('%d', AD);
I p : ( imr) rnathc ( n | 2 ) ; lyir(P==xuLLl
---{
pinu ( 'h lemory allocaton unsuccessqE) ;
eit( ) :
)
for(i=Q;ifn;i++)scanf ( "96d', (p+ i));
for(i=.0ii<nii++)sum:sum+.(p+i);
avg=sum/o;printf ( "A .......ge mafts =%d', aW ) ;
86
e 4arks. Not a byte more, not a b,'te
integgr pointsr.p. Sfuce mr[oc( ) Etums a void pointcr we have
t r""ur[a it into aa integer poiorer. lo Ee first for looE-!!]iIJti-"ii6-i"ttt aritlrne6rc we tave storrd the marks ent!:red from
keyLoar{ulqlhe rn.-ory -that
h* b""n allocated. In the tecondfor loop-we have 4ccessed the same values to fitrd the avemge
marks.
The calloc( ) functioos works exactly similar to Erlloc( ) except
for the faot that it needs tw-o atguments. For example,
inl'p;p= ( int') calloc ( 10, 2 ) ;
Chapter 2: Pointe$ and Arrq)s gZ
Solved Problems
IAI What will be the ouFut oflhe following progiams:
(1) main0
(int a[] = { 10, 20, 30, 40, 50 }
.
intj;tor (j =p ;j < 5;j++ )t/
printf('hyd.,t);a++;
))
O tput
Emr message: LvaftJe tequirEd in fundfun main
Explanation
,Here, we have fiIs! asked- for the number of studelEwhose-4alksare tgbe eltqed-ard lhelalloqated 9ub/-"1-qt!ch rnemory as is
Here 2 indicates lhat we urish to allocate m€mory for storing
integers, (since an integsr is a 2-byte eDtity) aDd I0 itrdicates that
we-Gnt ro resEE e spaqg l&E-$q!El!!@g!ryl ADofher minor Whenever we mention the name ofthe army, we get its baseaddress. Therefore, firsltt!rc flrcugh the loop; the Dritrd( )differeDce between mdto( ) and crnoc( ) is tbat' by defaulrlllhe address. l[erelore, trslttll! though the loop; the pritrtf( )should print the value at this-bae€ ai[li&-s.-fr;iE ls nomemory Sn co
oat attocatea ty dtoi@s' s11 :Ers. wA& u!!g thrse problem up to this. The @ ies ln tEe oext statement,an allav-
the only thing thai it l€rnembers about an array oace declaredii"i""-i-r.",*.*d 6^ tr" GpnFit-*"begimiggof -*c'@lgaur.
is jls base address. And a# aflgEplE_!9_f,tralgE this baseaJdrbss, wfuch C wodt allow befause itirdoes so, ir wouldbe uflable to remember the begirming of the array. An]thing,which can change is called lvalue in compiler,s language.Since value ofa cannol be changed though +, it flashes theerror saying 'Lvalue requircd' so that + oper"ator can changeit. .
88 Understanding Pointers In C Chapter 2: Pointers and Arrays 89
(2) maino
{foat all = { 13.24,1.5,1.5,5.4,3.5 };ioat l, 'k;
1j=,;k=a+d;j=j'2ik=kl2',printf ( 1n%f%1, 'j, 'k ) ;
I
Olttpu,
Eror message: lllegd tse ol Finler in tunction main
Explatatiott
i atrd k have b€en declared as pointer vafiables, wbich would
contain the addx€sses of foats. In otler words. j and k are
Iloat poinlefs. To b€gitr with, the base addrcss of the array
al I is stored io j. The ner(t statement is perfectly acceprablel
flr. "aaress
offte 46 trort fiom lhe base addrEss is storcd in
k. The next t$'o stat€rne s arc €rroneous. Thrs is because the
only operations lhat can be performed oa pointers are addition
and subtaction Multiplication or division of a pointer is IIot
allowed. Hence lhe error message.
main0
{
nlol = 100 ;nl24l = m0;pnnf (t%d 96d', -n,'( n + 24 ) +'( n + 0 )) ;
)
Outpat
100 300
Explanation
n[ ] has bein declared as an array capable of holdirg 25elements [umbered ftoln 0 to 24. Then-100 and 200 areassigned to n[0] and r[Zl resp€otively. Thetr comes the mostimpolant pa -the prhtf( ) statemed Wheaeyer wemendon the name of the array, we get its base address (i,e.address of lhe zercth elqlre of the array). Thus, *n wouldgive the value at this base addness, which itr this case is 100.This is theD prhted out. Look at the rcxt expression,
-(n+24)+'(n+0)
n gives the address of the zeroth element, tr + I gives theaddress ofthe next el€rtre ofthe array, atrd so on. Thus, n +24 would give the address-ofthe last elemetrt ofthe array, andtherefore *( n + 24 ) wonld give the value at this ;itdress,which is 200tu our case. Similady, *( n + 0 ) would give 100and the addition of the two *,ould result hto 300, \trhich isoutputted nexl
main( )
{int b[] = { 10, 20, 30, 40, s0 };int i, 'k;k =&b141-4; .for(i=0;i<=4;i++){
pnntf ( 'Yod ', 'i( ) ;
k++;
(4)
(3)
90 Understtnding Pointers In C Chapter 2: Poinlerc and Arrays 91
Output
10 20 30 40 50
Expldnatio
Fi$t look at Figue 2.9. The aEay elements are stored incotrtiguous memory locations ard each element is an integer,
hence is occupying 2 locations.
Figure 2.9
The expression &b[4] gives the address of b[4] (4010 in thisoase)- From this addEss ifwe zubtract 4, we get 4002 Or didyou expect to get 4006? Remember that by subtracting 4 fiom4010 what ltre mean is ge ss ofan integer, which is
4 integeE to the left of the integer whoG-addii:ss is 4010.
No$r', address of the i teger, whibh is 4 htegers to the left ofthe irteger whose addrcss is 4010, is the ad&ess 4002 Thisaddre6s, 4002, is storcd in k, whioh has been declarcd as a
variable capable of hokling an integer's address. First timethough th€ for loop *k would result into 10, i.e. value at the
addrc6s co ain€d in k k+ then inclements k suoh that itoontains the address of the oext ht€ger, i.e. 4004. Next timetlrough th€ for loop *k would yield the value at address
contained ia k, i.e. value at the address 4004, which is 20'Similarly, rhe loop priots out the Iest of the elements of the
altay.
{5) main0
{char a{l = "Visual.C++' ;char'b = 'Visual C+' ;
printf('\no/6d %d', sizeol ( a ), sizeof (b ) );pdntf ( 'ln96d 96d', sizeof ( 'a ), sizeof ( 'b ) ) ;
)
Output
11 211
Explanation
slzeof reports the m[nber of b5rtes occupied by an entity inmemoiy. The array r is ft,ported to be of ll bytes because
b)4e.
main0
{f Assume arEy begins at addess '1200 '/int anll = {2,3,4, 1,6 );pdntf ( '%u %d', an sizeol ( ar ) ) ;
)
Output
1200 10
Explanati6n
there is a'\0'sitting at the end. b is a pointer h-ce its size ;" Ib)ts-5 atld *b both yield a charactei'V', whose size is one
(6)
b[0] btu bt2l bt3l bt4l
4lnm 4n0/. 4006 4008 4010
l0 20 30 40 50
92 Understanding Pointers In C Chapter 2: Pointeis and Ar41y5 93
Mentioning the trame of an array yields its base address.Hence, arr would give 1200. Since the aray contains flveelemetrts. each of2 bytes, sizr ofthe array is reponed as l0bltes. Note thal except when used with sizeof( ), name of thearray yields its base address.
(7) maino
{f Assume a.ray begirE at addEss 65486 '/intar{l= { 12,14, 15, A,45};pdntf ('%u %u', ar, &ar); 6printf{'%u %u'. ar+ 1. &ar+ 1):'t
)E-
Output
65466 6548665488 65496
Explahalion
Both arr and &.rT yield tire base addless of the array.However, rrrtl gives 65488, i.e. the address of the nextinteger. However, &rrr + I gives 65496, i.e. the address ofthe next array ofs inl€gers.
(8) maino
{I Assume array begirE at ddless 65472 '/int al3il4l = {
1,2,3,4,4,3,2,1,7,8,9,0
)'pdntf ('h%u%u',a+ 1, &a+ I ) ;
)
Outpat
65480 65496
bqlafiation
Name of a 2-D arr.ay always acts as pofuter to the zerothelement of the aray. Since the zeroth element of our 2-Daray is l-D array of4 inlegers, a acts as pointer to this zeioth1-D aray. Hence a+l gives us the ad&ess of the next l-Darray, i.e. 65480.
The expression &a + I yields 65496. i-e. rhe address of thenext 2-D array of 3 rcws and 4 columns.
(9) maino
{f Assume array begirE at locdion '1002'/
int a[3][4] = {1,2,3,4,5,6,7, 8,
9, 10,'11,12
1;
printf ("Vt%u %u %u', a[0]+ 1,'( a[0]+ 1 ],.('( a +0 )+ 1 ));)
- Output
1004 2 2
Explanation '
9594 Understanding Pointers In C Chapter 2: Pointerc and Arrays
A 2-D airay is a coll€ction of several l-D arrays. Name of a2-D aray always acts as pointer to zeroth elemeat of thealmy. Hence, a acts as pointer to the zeroth l-D aray.
The expression r[0] + I is hterpreted by the compiler as *( a+ 0 ) + l. This is same as *a +1. The expression *a gives1002. Thercfore, *e +1 would give the address of the nextinteger, i.e. 1004. Since a[0] + r yields 1004 *( a[0] + 1 )would yield lhe value at address 1004, i-e. *( al0l + 1 ) canbe expanded gs *( "( a + 0 ) + I ). Hence, both theexpressions would yield the salne result, i.e. 2.
(10) main0
{int al3l[4] = {
1,2,3,4,4,3,2,8,7, 8,9, 0
);int'pf;ptr = &a[o]pl ;
lun ( &pt ) ;)
tun (int *p )
{printf ( 1nyd', 'p ) ;
)
Output
1
Explanation
Here, in ptr we bave stored address of l. Then we havepassed ad&ess ofptr to fun( ) and collected it in a pointer toan itrt pointer- Dereferencitg this pointet yields l.
('11) maino
{f Assume a.ray begins at location 1002 */int a[2]Fl[4] = {
(1,2,3,4,5, 6, 7, 8,
9,1,1,2),
{2,1,4,7,6,7,8,9,0.0.0.0
)I'
prjntf ( \i%u %u %u 96d', 4 *a, *a, *a
) ;
)
Output
1002 1002 1002.'l
Explan .tio.,
- The expressions a, "a,
*ra, would give the base addrcss, i.e.1002, wher€as the erpr€ssiol ***. would give the value atad&ess 1002,i.e. l. Note that the expression .[0][0][0] isexpadded into *( r( *( a + 0 ) + 0 ) + 0 ). This is same as
(12) main( )
97
{int a[]= { 2,4,6,8, 10 };int ijfor(i=0;i<=4;i+t){
'(a+i)=a[]+ilal'printf('%d',t(i+a))j
))
Output
4812 1620
Explatation
Imbibe the following three frcts and the program becomesvery simple to undeistaud:
- Mentio ng the name of the array gives the base addressoI the array.
- AIIay elements arc stored in coDtiguous memorylocalions.
- On adding I to the address of an integer, we get theaddress ofthe next i[teger.
Wilh rhose factrs clearly laid out- let us oow try to undeNtandthe program. Remember that infemally C always acoessesan:ay elements usi[g pointers. Thus, when we say a[i],intemally C converts it to *( a + i ), which means value of iah
integer from the base address. Now, if tbe expression alil issame as *( r + i ) then *( i + a ) must be same as i[al. But *( a+ i ) is same as *( i + . ). Therefore a[il must be same as i[al.
Thus a[i]. *( a + i ), *( i + a ] and ilal refer to rhe sameelement lbe ih element from the base address.
Therefore, the expressior used in the for loop, *( a + i ; = a111
+ ilal is nothing but alil - alil + alil- Thus all that is done inthe for loop is, each aray element is doubled and theD printedout through printfo.
(13) main0
tint alsl = { 2, 4, 6, 8, '10 };int i, b= 5;
for(i=0;i<5;i++){
f (alil, &b ) ;
pdntl { 'h%d 96d', a0. b ) ;
))
f (int x, inl -y )
{x=*(y)+=2;
)
Output
27496 11
81310 15
llxpldhaaon
After initialising the array when the control enteN the forloop, the fimction f( ) gets called with value of a[i] andaddrcss of b. In f( ) these are colleoted in vadables x and y.Then comes the exptession r = *( y ) +- 2. Here *( y ) += 2 is
98 Understanding Pointers In C Chapter 2: Pointers and Arrays 99
(14)
evaluated fiIst and thell the Esult of this expression isassigned to x. The first time thmugh the for loop *( y ) gives
5, to which 2 is added and lhe result is storcd at *( y ). Itmeans 7 is assigDed lo b. Finally, the = operator 'assigns 7 tox. However, on assrgning a new value to x, the array elementalol in iDain( ) remai[s uncha[ged. Thus, du.ing every call tof( ), b's value keeps getting updated, whereas therc is nochange iD the values of the array elemenh.
Figure 2j10
main( )
{int alsl = { 2, 3, 4, 5, 6 };inti;
change (a );lor(i=4;i>=0;i-)
pintf { 'Y"d ', a[]) ;
)
change ( int'b ){
inti;for(i=0;i<=4;i++)t
'b='b+1;b++;ri
))
Output
76543
Explsnation
Figue 2.1I
While caling charye( ) we are passing the base address ofthearay, which as per Figure 2.ll is 4002. This address iscollect€d in b in the functioo change( ). Then the oontrolenters the for loop, where we meet the explession *b = *b +1- This means rcplace the value at the address contained in b,with value al the address contained in b plus 1. Every timeb+ is executed, the address ofthe trext integer gets storcd iob. Thus, using the address stored in b, we get an access toaray elements that are now changed to 3, 4, 5,6 and 7. O\cethe control comes back from change( ), the current arraycontents are then printed out ftom end to begindng throughthe for loop.
401Ef , I
b
l-5 I4008
atol alll al21 a13 441
4co2 4004 4M ,1008 4010
bb[ 4oo, I b--,[ 4oM I
100 Understanding Pointers In C
(15) mainO
{int arll= {0, 1,2,3,4 };int,pb;for ( ptr = &ar{01 ; pt <= &ant4l ; ptr++ )
printf ( '%d ', tpr ) ;
)
Output
01234
Elplanation
Refer to Figue 2.12 lot a better utrderstanding of the
pIOgram.
Here ptr has been dectared as an integer pointer, i.e a
variable capatle of holding the address of art integer. In the
for loop, irl the initialisation part, this ptr is assigned the
address of the zeroth elernent of the integer aEay Suppose
this address tums oul to be 6004. Then address of the firstelement of the array would be 6006, address of the seoond
element would be 6008, and so on. In the conditioa part of the
for loop, the address storcd h ptr is compared with the
addrcss of the foufh aray elemen! i.e. 6012. Sirce for the
first time lthe, conditioa is satisfied (shce 6004 is less than
6012), the'cotrtsol reaches pritrtf( ) where the value at address
6004, i.e. 0 gits pinted. After executing priutf( ) the controlreaches pff+, where ptr is incremented such that it contains
the addrcss ofthe rext integer. Since the next integer is stored
at 6006, pf now contains 6006. Once again the condition istested- Since 6006 is also smaller lhar 6012, the conditiofl issatisfied honce the printf( ) prints out the value at 6006, i.e. l.And then pffi is executed again so that it corltains the
Chapter 2: Pointers and Arrays 101
address of the next iateger, i.e. 6008. This prccess cotrtinuestill all the array elements have beea prioM.
arrl0l arrlll alll2l .Irl3l arltll
0 I , 3 4
6008 6010 6012
ptpts
f eoor I o*, frooo I
FigtuIe 2.12
(16) main0
(,int arl l= {0, 1,2,3,4};int i, 'ptr;for (pb= &ar40l, i= 0; i<= 4 ; i+| )
prinf ( %d ', ptfl ) i)
Output
0123 4
Expla atiol .
In the initialisation part ofthe for loop, multiple initialisationsare being done. Fi$tty, ptr is set up vith the base address ofthe alIay and then i is set to 0. Since 0 is less than 4, thecondition is satisfied for the first time atrd the control reachesprintf( ). Here the value ofthe exprcssion ptr[iJ gets printed.
102 Understanding Pointerc In C
Now ptrlil is nothiDg but r( ptr + i ). Sipce ptr coDBins tlebase address of the arr6-yl ptu t I ) would gi-E the address ofthe id irteger 8om the bas€ ad&ess. Since i is going to vary
fiom 0 to 4, this would give addrcsses ofo", l''.2"o. 3'o and
46 integers ftom the bas€ addE$s of the aray. Naturally, the
exFession *( ptr + i ) would give values at these addrcsses.
Thus, the for loop would print out all the array elements.
(17) maino
(int anll={0,1,2,3,4};inl i, *p
;
for( p = ar, i = 0 ; p+ i <=ar+4 ; PF[, i+r )
Pdntf ( '96d ', '( P + i) ) ;)
Output
.024
Explanation
The following figul€ would help in understanding theprogram.
Chapter 2: Pointerc and Arrays t03
the initialisation part, p is initialised to trc base address of thearray. whereas i is initialised to 0. Afier these inirialisationsthe cortrol rcaches the conditiotr. The condition is a littlecomplicated so let us isolate it for a clearE u[derstanding.
p+i<=alr+4
Here + enjoys a higher priority thar <=. Therefore, firct p + Iafld arr+4 arc performed ard then tha <= goes to work. p+iyields 6004. wherEas arrH evaluates to 6012, SiDce 60Oa isless than'6012, the condition is satisfied and fte coIlholreaches pr-intf(-), where value at ( p+i ), i.e. 0 gets printed.Thed the control r€aches the iacrernentation part of the forloop, wherc p# inq€|trr€dts p to 6006, and ii inorements Ito 1. Next, once agaitr the coniditioa is tested. This time p+lgives 6008 (since p is 6006 and i is I) and arft4 gives 6012.Since the condilioo oDce again gets satisfie4 thi priut( )pnnts out the value at ( p+i ), i.e. 2. Similarly, next timearound 4 gefs printed aud then the corditiol fails therefore theexecution is terminated
main0
tint an[]= {0, 1,2,3,4};int'pt;for ( ptr = an+4;pt'>=ar; ptr- )
pdntf ( 'ol'd ', 'pf ) ;
Output
43210
Explanatioh
(18)
arrtol al'0l ard2l ad31 aq[a]
6004 6006 6008 6010 6012
0 I 2 3 4
Figure 2.13
ln the for loop frcre ee multiple initialisatioDs arld multipleiroremeDtatrons, each s€parated by the cornma operatol. ln
Chapter 2: Poinlers and Arrq)s t0s
Output
43210The following figure would lead to a better understanding ofthe program.
a'I[0] ar{ll ar[21 arrt3l an[4]
6010 6012
Dts PE
I rorz I PE-- -l eoro Il-l
I0 2 3 4
Pignrc 2.14
In the initialisatiotr part, ptr is assiFed the address of the last
element in the array. This is because rrr+4 gives the addrcss
ofthe fowth iateger Aom the bas€ ad&€$s. First time tbrough
the looD the cotrditiotr evaluates to true, siDce the addless ofthe fourtlh elemeot (6012) would certainly be bigger thaD the
base addrEss (60M) of the array. Next, the conbol reaches
prhtf( ), wbi;h prints oltt the value at adiiress cortained in;tr. i.e. \"lue at addr€ss 6012. N€xl, the statement ptr- gets
executed which reduces pk io 6010. Sirce 6010 is also bigger
thar 6004, rhe condition is satisfied onoe again, ard the valu€
at 6010 gets printed through the printf( ). This process is
lepeated for all the aray elcments.
main0
{int arll = {0,1,2,3,4 };inti,'pf;for(pb=ar+4, i =0: i<=4 ; i*)
printf ( "t6d ', Pt[-il) ;
)
Explanatio
ar{01 a{tl aEl2l an[3] . a44l
60M 6006 6m8 6010 6012
0 I 2 3 4
Figure 2.15
The above figule shows the amngement ofthe array elementsin memory-
In the iiritialisation part ofthe for loop, ptr is assigned a value6012, since arrH gives the addrEss of the fouth integer Aomthe base address of the array. Here, the variable I is alsoinitialised to 0. Siace th6 condition is satisfied for the firsttime (i being 0), the printf( ) prints out Ore vatue of ptr[-ll.But what is ptrl-il? Nothibg but *( ptr - t ). And since i is 0,*( ptr - i ) evaluates to *( 6012 - 0 ), i.e. 4. Then the controlreaches i+ where i is incr€rnented to l. Nexg the condition ischecked atrd sirce it evaluafes to true, the prini( ) pritrts outthe value of pfr[-il. Since this time i is l, ptr[-i] becomes *(ptr - I ), i.e. *( 6012 - 1 ), i.e. * ( 6010 ). Thus rhe value 3gets prinred. Likewise, 2, I ad 0 also get printed subsequenttimes though the for loop.
main( )
{int anlj= {0, 1,2,3,4};int tptr
i
(1e)
(20)
106 Understanding Pointers In C
for ( ptr = ar + 4 ; p&>= ar ph- ). pdntf('%d ', ar Ipr- ar]];
)
Output
3210
Explanatiort
A picture is worth a lhousaDd words. Going by lhis dictum.the follolving figure should add clarity to your understandingofthe pmgram.
Figue 2.16
Now things are getting really complicated, as the printf( )would justify. Let us begin with the for loop. Firstly ptr isassigtred the address 6012, the address of the fouth integerAom the base address. Since this address is gre.ter than tiebase addrcss, the condition is $alisfied and the control reachespritrtf( ). What does rrr I ptr - arr I evaluate to? ptr - arfmeans 6012 - 6004 which yields 4 and hence arr[4] printsout the fou h element ofthe array- Then ptr- reduces ptr to6010. Since 6010 is greater than the base address 6004, thecondition is satisfied and once again the conhol reaches theprintf( ). This time ptr - {'r'becomes 6010 - 6004, i,e. 3.Thus arr[3] pdtrls out 3. This pmcess is repeated till all theintegeft ill the array have been p.inted out
Chapter 2: Pointers and Arrqts 107
Possibly an easier way of understanditrg the expression ptr -arr would be as follows. Suppose ptr coniains 6012 and arrcontains 6004. We can thell view the subtraction as ( rrr + 4 -arr ), since ph is nothing but .rr. + 4. Nol^. I suppose its quitelogical 10 expect the result ofthe subtraction as 4.
(21) main0
tstatic inta[]= (0, 1,2,3,4 ];static int'p[] = {a, a + 1, a + 2, a + 3, a + 4l ;int .'ptr : p;printf ( "h%u %d", a, 'a ) ;printf ( 'olou %u 7d', p, 'p, *p
) ;pintf { ln%u %u %d", ptr, 'ph *ptr
) ;
Output
6004 0
9016 6004 09016 6004 0
E,Vlanation
Look at the initiatisatior of, the array p[ l. DuriDginitialisafion, the addresses of various elemenis oi th"
".r i
a[] are stored in lhe aray p[ l. Sioce the array pl 1 contalnsaddresses of idegers, it has been declared as
-ari arrav of
pornters to integers. Figue 2.17 shows the conteats of arraysa[ ] and p-[l In the variable ptr, the base addrcss ofthe ariayp[ l, i.e- 9016 is storad. Since this address is the address ofp[0], which itselfis a pointer, pti has been declarcd as pointerto an integerpoi[!er.
Let us undelstand the first pritrtf( ) rcw.
T.adoi arIlli anl2l alrt3] artal
0 2 3 4
6006 6008 6010 6012
108 Unilerstaniling Pointers In C
printf ( "hy"u %d', a, 'a ) ;
It prhts out the base address ofthe array a[ ] and the lalue at
this base address.
a[0] atll al2\ 431 {al
6004
p[01
6006
ptu
6008
pql
6010
pt31
6012
pt4l
60M 6006 6008 6010 6012
9016 9018 90m 9022
prr
lg0'617888
0 2 3
Chapter 2: Pointen and Anays 109
Now onto tlle last printf( ).
pdntf ( '\n%u %u 96d', pr, 'pr, *ph ) ;
Here ptr contains the base addiess ofthe array pl l, i.e. 9016;*ptr would give lhe value at this addrcss, i.e. 6004; **ptrwould give the value at the ad&ess given by *ptr, i.e. value ataddress 60M, which is 0.
(22) maino
{static intalt = {0, 1,2,3,4 };sbtic int'pU = {a a + 1, a +2,a+3,a+ 4};
int *Ptr
= P'
ptr++j a}pirfff ( '\n96d 96d j6d', pr - p, -pr - a, *pb
) ; '
'Ptr++'printf ( 1n9{d %d 96d', pr - p, 'p[ - a, 'p[ ) ;
l++ptr;
pdntf ( 1n%d 9(d 9{d!, pr - p, -pr - a,-ptr ) ;
++.ptr;pdntf { \%d 96d 9{d', pb - p, 'pr - a, 'pr } ;
)
Outryt
111222
344
Explanation
Figure 2.17
Looking at the figsre, this u'ould turtr out to be 6004 and 0'when you execute the p'.ogram' the address may tum out to
be somethfug other than 6004, but the value at the address
would be surely 0.
Now look at the second Pritrtf( ).
pdntf ( 1n%u %u 96d', P, 'P, *P
) ;
Here p would give the base address of the aray p[ l, i e'
9016; *p would give the value at this address, i.e 6004; **p
would give the value at the address given by *p, i.e value at
addrcss 6004, which is 0.
110 Undentanding Pointers In C Chapter 2: Pointers and Amays 111
work and increfienls value in ph to 9020. Now with ptrcontaining 9020, let us once again analyse the expressions ptr- p, *ptr - a and **plr'- . -
Figure 2.18
plr-p
Figure 2.18 would go a loag way in helping us to understandthis prograno-
Herc ph has beetr declared as a pointer to an integer pointerand assigoed-t[e base address of the array pt ]. which hasbeen declared as an array of integer pointers. wllat happenswhen ptr+ gets executed? ptr lgiots ro the next inGgerpornter rp the armv pll. b other words. now btr adfiIdin. tfia-adclress 9(r18. Now let us analyse the meaning ofplr _ p. *ptr- a and r*ptr.
pk-p
Since ptr is contaiDing the address 9018, we can as \ ell savthal ptr is containing the addEss given by p + L t tren ptr - iis reducedto ( p + 1 - p), which yields l.tptr - a
*ptr means yalue at the address coatained in ptr. Since ptrcontairs 9018, the value at this address would be 6006. Now6006 can be inaghed as ( r + t ). Tbus the e\pressionbecome,s ( a + 1-.), which is nothing but l.
ptr conlairs 9018, so *ptr yields 6006. and hence *+ptrbecomes *( 60116 ), which yields I -
Thus tbe ouPul ofthe firsf prhtf( ) becomes I I LTake a deep brealh atd then begin u,ith rhe analysis of*pt ++. Here * and r+ both are unary operalors. Since --occurs aller the vadable, + would be dode later. Firstlv*(9018) is perturmed, but since this value is not beiniassigned to any vafable it gets ignored. Next, ++ goes ti
401 altl at2\ at3l al41
0 I 2 3 4
6004
ptol
6006
ptll
6008
Pl21
6010 6012
pt3l pt4l
6004 6006 6m8 6010 6012
9016 9018 9020 9022 9024(\
ptr ptr \lf noro I ,'*',ft"l I
7888.
pts
7888
ptr
f,file"t-f,mtl7888
PF
7888
pts
llqo2o I .**ro,l-eo2tl
7888
pE ptr
f ,Ell *-pt',fG7l .@bt"?888 78BB 6012
t12 Undersnndirug Pointers In C
Since ptr contains 9020, il can be visualised as ( p + 2 ). Thusptr - p wouldbecome ( p + 2 - p ), which gives 2.
.ptr - a
*ptr would give value at addrcss 9020, i.e. 6008, which isrcthing but the address given by a + 2. Thus ihe expressionbecomes (. +2 -. ), which gives 2.
-ptr
*ptr gives the value at address 9020, i.e. 6008, and *( 6008 )gives the value at 6008, i.e. 2.
I hope youi cortfid€nce is building and you are ready to meethead on the expressiou *+plr. Here, since +t precedes ptr,firsdy ptr is i crehented such that it contaios the address
9022, and then the value at this address is obtained. Since thevalue is not iollected in any variable, it gets ignored. Nowhaving cooked enough pointer stew you can easily imaginethat the output ofthe third printf( ) woutd be 3 3 3.
Finally, let us |mdeistand the exprcssion +*ptr. Hereobviously, the pdority goes to the r. Thus, this expressionincrements the value given by *ptr. Since ptr contains 9022,*ptr gives value at 9022, i.e. 6010. This value is incrementedto 6012. So p[3] now contains 6012, whereas value of ptrrcmains stationary at 9022- Let us rlow analyse theexpressions plr - p, *pli - r and **ptr.
ptr-p
ptr contains 9022, therefoE ptr can be imagined as ( p + 3 ).Thus ( ptr - p ) becomes ( p + 3 - p ), which yields 3.
'ptr - a
Chapler 2: Pointers and Arralts 113
*ptr yields 6012 which can be rhought ofas ( a + 4 ). Thusthe exprcssior is reduced to ( a + 4 - .), which yields 4.
*ptr
*ptr ields 6012, tlEreforc i*ptr would yield the value at*ptr, or the value at 6012, which is 4.
(23) main{)
{static int a[] = { 0, '1, 2, 3,4 };slaticint*pll={a, a + 1, a + 2, a +3, a +4};
int'ptr;
Ptr= P;HPr++;
pdntf ( \lvd %d 96d', pu - p, -pr - a, *pr
) ;.***plr;
printf ( tt%d 16d 96d', pb - p, 'ph - a, "pf ) ;
*"pf ;printf ( \]%d 96d %d', ph - p, 'pt - a, *pf
) ;
)
Olttput
Explanation
To begin wi&, the anay a[ J is initialised and the aray p[ ] isset such tllat it contains the addresses of elements of arrayr[]. Thus array pl I becomes an array of poitrtels. The baseaddrcss ofthis array ofpointers is then assigned to ptr, which
1'l22
I 14 Understanding Pointers In C
is rightly called a pointer to a pointer The possiblearmngement ofthe aray elemeits in oemory is sho*n in thefollowing figure.
Figure 2-19
Let us now analyse the expression **ptr+. ptr contains theaddress 9016, therefore *ptr would leld the address 6004.**ptr would give lhe value at this ad&ess- This value tumsout to be 0. However, this r.alue is not assigned to anyvadable. Lastly ptr+ goes to work. This increments thevalue stored in ptr -to 9018- Once you are surc that ptrcontains 9018, let us oow proceed to fi[d out what the output
of printf( ) is- Let us take otre expressioa at a time andanalyse il slep by careful step-
ptr- p
Sifoe ptr is contahing the adrlress 9018, we calt as v/ell saythat ptr is contairfng the add.ess given by p + l. Thus ptr - pis reduced to ( p+ l - p ), which yields l.
'ptr - a
*ptr means value at the ad&ess contained in ph. Since ptrcontaiN 9018, the value at lhis addrEss would be 6006. Now6006 can tr€ imagined as ( I + I )- Thus the expressionbecomes ( a + l - a ), which isnorhing tlirt t.
*ptr
ptr contaiN 90t 8, so *ptr would yield 6fi)6, aod hence **ptrbecomes *( 6006 ), which would yield t-
Thus the output ofthe first pdntf0 tums out to be I I l.
The [ext statement needs a closer took In *#*ph, the orderof evaluation would be *( ++( *par ) )- Sinc€ ph conlains9018; *( ptr ) would yield the value at 9018, i.e. 6006. Then++ goes to work on 6{}06 and incrqneds it such that it is now6008. Thus p[1] would now cortain 6008. And finally*( 6008 ) would give 2, which is ignored since it is notassigned ro any variable.
Now, with ptr containing 9018, let us otrc€ again anall.se theexpressiotrs ptr - p, *ptr - a arrd *rpfu.
ptr-p
401 ao1 al2l at3I^L4l
0 I 2 1 4
6004
ptol
6006
Dtu
6008
pI2\
6010 60t2
p[3] pt4l
600J ffit6 r)0O8 6010 60t2
9016 9018 9020 9022
ptr pts
l- ,016 I *.'*'-' f;;;-l
7888 7888
pts ptr
l-;;l -*..p",1-e018 |ptll ischangedto 6008
a[2] ischanged to 3
7888
pts
7888 .
ptr
l- so18 I **rt,l- ror8 I7888 78a8
116 flnderstand.ing Pointers In C Chapter 2: Pointers and Arrays 117
Since ptr contains 9018, it car be visualised as ( p + I ), thus
ptr - p would beoome ( p + I - p ), whioh would be 1.
'pt-a
*ptr would give value at addrcss 9018, i.e. 6008, which is
nothirg but the address given by a + 2. Thus ihe expression
becomes ( a + 2 - a ), which gives 2.
-w
*ptr gives the value at addrc$s 9018, i,e. 6008, and *( 6008 )gives the value at 6008, i.e. 2.
Thus the output ofthe secord priu6( ) would be I 2 2.
Finally, we reach the third expression +**ptr. As the unary
opeElors are evaluated Aom dght to left, the order ofevaluation of the above cxpressioa becomes: ( +( *( *ptr ))). since ptr contatus 9018, *ptr lelds 6008. *( 6008 )results i[to 2. This value at the address 6008 is then
incremented ftom 2 to 3.
ptr ' p
Siuce ptr coatains 9018, it cm be visualised as ( p + 1 ), thus
ptr - p wouldbecor4e( p + 1 - p ), which wouldbe l.
'ptr - a
*ptr would give value at address 9018, i.e. 6008. which is
nothing but the address given by . + 2. Thus lhe expressioD
becomes ( a + 2 - a ), whicb gives 2.
*ptr
*ptr gives the value at addrcss 9018, i.e. 6008, and *( 6008 )gives lhe value at 6008, i-€. J.
Thus the output oflhe thi.d printf( ) is I 2 3.
(24) mainO
(int nl3ll3l= {
2,4,3,6,8,5,3,5,1
);
f Assume that arEy begins at address 404 '/pintf ( 1n%u %u %d', n, n[2], nP]PI) ;
)
Output
404 416 'l
Explakalion
tr[ ][ ], to begin witlL is declared as a two-dimensional array.Whenever we mention the name of the array, rie get its baseaddress. Therefore in printf( ), the fiIst output would be thebase address of the array. ln our case it tumed oui to be 404.The array elemenls arc aranged in memory as shown inFigure 2.20. Remembq that thele are no lows and columns inmemory.
A two-dimensiooal aray is nothing but an array of severalone-dimensional arrays- The 2-D array coltains addresses ofthese l-D arrays. Thus n[0], nul and n[2] contain iheaddresses 404 410 and 416 respectively. Hen€e the secondoutput of printf( ). The third output is quite staightforward.
118 Understanding Pointerc In C Chapter 2: Pointers and Anays 119
n[2]l2l prints out Se elcment io the second row atld secondcolumn ofthe aaiay,
2 4 3 6 8 5 3 1
404 406 ,t08 4r0 412 414 416 418 420do]tol nllltol{21[0]
2 4 3 6 8 5 3 5
404 406 408 1tO 4t2 414 416 418 420
Figorc2.2O
(25) maino
(. int n[3]PI= {
2,1,3,6,8,5,3, 5, 1
);int'ptr;p[= n;printr ( \l%u ', n[21] ;pdnf ( '%d ', fila ) :printf ('96d', r( fi + 2) ) ;
)
Output
41633
Explanation
ptr has beer declar€d as atr inleger pohter, and to begin v,/irh
is assigned thi: base address ofthe aray, i.e. 404.
Figule 2-21
n[2] gives tlte base address of the second one-dintensionalarray, that is 416. Next comes the expressioa ptu[2]. Can weuse such an erpression? Yes, because ultimately ptr[2] isnothing but r( ptr + 2 ). Thus, even though ph has not beendeclared as rm aray, we are perfectly justified in using theexFessioa ptrJ2l. ptr stores the ad&es$ 404, so *( ptr + 2 )
" gives the ralue oflhe second iateger from 404, which in thisprogam happens to be 3.
(26) main( )
{int nl3ll3l = {
2,4,3,6,8,5,3, 5, 'l
l;int i,j;for(i=2;i>=0;i-)(
tor(j=2;j>=0;F)Pdnf ( t|%d 96d', nn[], '( -( n + i) +i ] ) ;
))
Output
11
120 Understa diflg Pointers In C
55
8866
4422
Explanation
Th€ output of n[ilH is as per the expectations, I believe. Allthat is done is, using tlrc for loops, rows and columns arevaried, i controllitrg the rcw and j coffrclling the column.what is definitely difficult to oomprehead is the seoondexpression in print( ), t *( tr + t ) + J ). Let us try toundelslaod ir. The followiog figulo should prove helptul indoing so.
Chapter 2: Pointers and Anays l2t
414. The value at this addrcss, that is 5, can be obtainedlhrough the expression *( Dlll + 2 ). We know all loo wellthat u[1] can also be expressed as r( n + I ). Thus, theexpressior *( n[1] + 2 ) is same as *( *( n + 1 ) + 2 ), which issame as oflll2l. Therefore in general, we can say thar DIilLilrs same as'( *( n + i ) +J ). with that I suppose the outpul ofthe above program is quitE simple-
(27) main0
tstatic int a[3][3] = {
1,2,3,4, 5, 6,7,8,9
];
2 4 3 6 8 5 3 5 1
404 406 408 4tO 412 414 416 4t8 420
Fignre2.22
kflagine a 2-D array as a collection ofseveral l-D arrays. Theonly thiog that the compiler needs to rememb$ about a 1-Darray is its base address. Thus, if Oree l-D arrays ar€ to beremembere4 the compiler should store somewh€re the baseaddresses of these armys. These base addresses are stored inn[0], nlll aod n[2]- Now ifn[l] gives the base address ofthefirst array, lhen n[l] + 2 would give tlre address ofthe seconditrteger from this base address. In this case it tums out to be
stalic int 'ptrl3l = { a[0], a[1], a[21] ;inl "ptr1 = ptr i
inti;
printf (\" );for(i=0;i<=2;i++)
pintf ( 'ol"d ", tprU ) ;
pdntf("\n");for(i=0;i<=2;i++)
pdntf('%d ', tafl ];pdntf ( 'b') :
for(i=0ji<=2;i++){
printf ( 'yod ', *ptrt ) ;
Ptrl++')
)
Output
122 Unilersnnding Pointers In C Chapter 2: Pointers aad Anays 123
1. On incrementing ptrl it poitrts to the next location after822, i.e. 824. ThereforE, next r'lme 6rough the for loop,**ptrl gives value at 410 (which i8 obtained ttrougn *ptrfl,i.e. 4. Similarly, last time through the loop, the value 7 geispdnted.
(28) maino
{int t[3][2][4] = {
474747
Explanalion
406 ,lO8 410 412 414 416
ptstol PE[l] Ptt2I
418 420
a22
prl
824 826
ptrl
|-8;1 Prt*,f-E-lr-
416q4 4t0
{2,4,3,6,'1,6,7,9
),{
8,2,1,1,2,3,7,3
1,6,2,4,0, 7, 9, 5
));
. printr ( "\n%d %d', {21[1181, .( -(.( r + 2 ) + 1 ) + 3 ) ) j
)
Output
55
Explanation
In memory the 3-D array elemeots are arranged as shownFigwe 2-24.
),{
Figue 2.23
ptr[ ] has treen declared as alr array ofpointeN oontaining the
tasi'addresses of the tluee l-D arrays as shown in Figure
2.23. Orce past tbe declaratiotrs, the control rcaohes the first
for loop. tn this loop tlrc pritrtf( ) pfirts the values at
addressis storcd in ptrtol, Ptrtfl and ptr[2], which tum out
to be 1, 4 and 7.
III rhe trext for'loop, the values at base ad&esses stored in the
anay a[ ] are printed, which once again tum out to be 1, 4 and
7. The third for toop is also siinple.
Since ptrl has been initialised to the base address of the array
otrl l. it coolains the address S22 Therelore *ptrl would
;iv; i; value at addrcss 822, i.e. 'l(}4' and **ptrl would give
ihe value at address srven by *ptrl' i e value at 404' which is
m
124 Understanding Pointers In C
2436 1679 82ll 217f 1624 0'7 9 5
212 240200 204 2t6 224
Figtre 2.24
Here t[ ]l l[ I has be€n declared as a tbree-dimensional arrayA 3-D alray can be considercd as a collection ofa number of2-D arays- Thus, the first expression in the priotf( ).t[2llt][]l refers to the elernent in l" row. 3'o column ol the 2n0
2-D array. This tums out to b€ 5, vt/hich is printed throughpritrtf( ).
The next exprcssion in printf( ) is a little complicated. Sincethe only thiflg that the compiler needs to remember about the
thiee 2-D arays is their base addrcsses, dlese addrcsses are
st6rcd h r[0], t[1] and t[21. Therefore, the expression t[2lu]would give ihe address of the first tox, of the second 2-Darray. Referring to the figue, this address turns out to be 240.To this address if we add 3, we would get the address of thethird integer from this address. This address would be 246.Naturally, the yalue al this address (i.e. 5) can be obtainedthrough the expression *( tl2l[1] + 3 ). But t[2][1] itself canbe expressed as *( t[2] + 1 ). And in this expression t[2] canbe exprcssed as *( t + 2 ). Thus the expression *( t[2]Ul + 3 )can be expressed as r('( *( t+2 ) + 1 ) + 3 ).
[Bl Answer the follorving:
{1) For the follorting statements would arr[3] and ptrl3l fetchthe sahe cha€cter? <YeVNo>:
char anll = 'Surpdsed' ;
char'ptr = 'Surprised' ;
Chapler 2: Pointers and Arrays 125
Explanation
Yes
{D For.th€ statements in(l) does the compiler letgljLe character. arrl3l and ptrl3l in lhe same mannerz
-
Explahatio
No. For arr[3] the compiler generates code to stan at locanonarr, move thrce past it, and fetch the character therc. When itsees the expiession ptr[3] it gercrates the code to start atlocatioD stored ill ptr, add three to the pointer, and finallyfelch the character poinled to.
ln other words, arr[3] is tkee places past the start of theobject named arr, whereas ptr[3] is three places past theobject pointed to by ptr.
(3) Can you comlrine the following two statemelts into one?
char 'p ;
p = malloc (100 );
bqlanatioh
char.p=rp211o.11*,
/4) Does menrioning lhe array name gives lhe base address in all/ ihe contexls?
Explanation
126 127
No. Whenevq mentioning the array uame gives its baseaddress it is said that the array lus decayed into a pointer.This decaying doe$'t take place in tivo situations:
- When array name is used with sizeof operator.- Whea the array aame is al operand ofthe & operator.
(5) Arc the exprcssions arr aod &arr same for an arrav of 10 r]integers?
Explanation
No- Even though both may give the same addiesses they meantwo dillerent things. arr gives the address of the first int,whereas &arr gives the address of array of itrts. Sioce theseaddresses happen to be same the results ofthe expressions aresame.
(p) When char aJ I aDd ch.r *a are treated as same by lhen compiler?
Explatation
When usirg them as formal pammeters while defining afunction.
(7) Would the following progam compile successfully?
main0(
char a[ ] = "Sunst'oke' 'char.P = "Coldwave' '
a = 'Coldwave' ;P = 'Sunsfoke" ;
pdntf { "\n9k %s', a, p ) ;
)
Explanatiot
No, because we 1rlay assign a new string to a Pointer but not
to an aray.
(8) A pointq to a block of memory is effeaively same as an
array. <TruelFalse>
Explanatioa
True
(9) What does the following declaralion lnean:
int (.ptr)f0l;
Explanalion
ptr is a pointer to an array of l0 integers.
( I 0) If we pass the name of a l-D int array to a function it decays
into a pointer to an itrt. lf we pass the name ofa 2-D array ofintegen to a function what would it decay itrto?
bqlanatiol
It decays into a pohter to an aray and trot a pointer to a
pointer.
(ll)Are the three declaralions char **apple, char *orangel l,and char cherryl l[ | same? <Yes/No>
Erplanatien
128
No
(12) What would be rhe equivalent pointer expression for referringlhe element alilHlkllll?
Explanation
'(r(*('(a+i)+j)+k)+l)
( I3l ln the follo\i ing program how would you prinr 50 using p?
main0
{int a[]= { 10, m,30,40,50 };char'P;p=(ch . )a;
)
Ettplatatioa
printf ('\a%d',.( (int')p +4 ));
(14) How would you defire the tunction f( ) in the followingprogram?
int anl[rAXROlfl][MAXCOL] ;
fun ( ar);
Explana/io
fun ( inl a[ ]ruAxcoll ]{)
Chapter 2: Pointers and Arrays 129
tun ( int (-ptr )I.[alu\COL] ) f ptr is pointer b an aray'/{)
ti0
Exercise
IAI What will be rhe output ofthe follou,ing programs:
(1) main{)
{int anl3l[3]Bl ;
f Assume base address of ar to be '1000 '/pdntf ( \l%u %u %u', ar, at + 1,ar+2\:pintf ( '\n%u you %u', anlol, an[0.] + 1 , arfl ) ;
pintf('h%u %u %u', adllt11, an[1][0]+ 1, an[0][1] ) ;
]
(2) main0(
stailc i a[3][3]Bl = {(
1,2,X,4, 5, 6,
7,8,9),{
2,4,6,8, 10,12,14, 16, 18
),{
3,6,9,12,15,18,21,24,27
));
static int 'Ptl I = {al0l[0], at0lfl I, a[0][2],
aFltol, al11l1l, atl1p1,
al2ll0l, aqlfil. a?lql
Understanding Pointers In C Chapter 2: PointenandAnays t3l
(4)
);int'pfi[] = { a[0], a[1]. a[21 ] ;
int'pt2=pt,i;
printf (t') ;
for ( i= 0; i<= 8; i++ )(
pnnf ( '96d ', 'pt2 ) ;
Pt2++;)
prin$ ( 'Vr') ;for(i=0;i<=2:i++)
prinr ( %d ', -( pldll ) ) ;
pdntf('ln');for(i=0;i<=8;i++)
printr ( '96d ', 'pb[ ) ;
]
maino
{shlic int adl= { 97, 98,99, 100, 101, joz 103, 104 };int'pk=ar+1;
print ( ++pf, pt.-, pE ptr++. ++pf ] ;
)
pdnt ( int 'a, int'b, int'c, inl'd, int .e
)(
printf (1n%d %d %d 96d 96d', -a,.b, t .d,.e ) ;
I
majn0
tinr at3lpll2l = {
{1,2,
132 Understanding Pointers In. C
);
pintf { 1n96d %d 9{d ', '('( a[0] + 2 ] + 1 ),.(.(.(a+2)+ 1 ) + 1 ),'(anl[4+ I )) ;
main0{
static int a[]= { 0, 1,2, 3,4 };staticint*pll = {a, a + 2, a + 1, a +4, a +3 } ;
int -plr ;
printf ( "h96d %d %d ', 'plr, plr - p, 'ptr - a ) ;
Ihe likelihootl 4d program crashing is in direct ptoportio\ to thetxmber ofpointers used ii it-
Qointffs dnlstr@s
n the last chapter you leamt how to define arrays of differingsizes aad dimensions, how to initialise them, how to pass themto a functiols, etc. With this tnowledge under your belt, you
should be Eady to hatrdle s&iags, whioh are, simpty put, a specialkind of aray. String$, rhe ways to htuipulate them, and howpoi ers arc relaied to strings ale going to be the topics of
),{
),{
3,4,5,6
3,4,1,2,5,6
5, 6,
3,4,1,2
(5)
ph=p;*.++ptr;
discussion ill this chapter.
What are Strings
The way a goupjlj4lECgqleg be s!ojd_!q_q!_!-ttr9g9l_9Iray,similarly a group ofchamcters can be stoied in a character al y.( hamcter aravs arc manv a time -also known as 'strinps Mostianguag@t;nag, u"
134 {Jnderstanding Pointers In C Chapter 3: Pointers and Strings 135
character arrays, but somehow conceal this fact from the
programrner. Character am5rs or strings are the data types used by
Fogrammlng languages to manipulate text such as words and
sentences.
A string coDstant is a onedimensiooal array of chgllcterstenraffi truf f $uTJ;iexamfi ichar namel] = ('H', A,'E, 'S,'lJ,'E,'R;10 ];
Each chaBcter i4ihc alrallqccupieq@bdE-qf$!9oq lnd_gelast character is always '\0'. Whal charactq is this? It looks liketwo charaitec,-Tutliisi6rally atr escape sequenoe like 'h', It iscalled 'null character'. Note @t'\o: ad '0: q,e'!pt s4-m9. ASCIIvalue of '\0.Js O, whereas ASCtr value 9f '0' is {!. The charaoter
anay iriffi'ry would look lfte this:
Figue 3.1
Note that the array elemeots arc stored in coEhguous memory
locations.
The terminating n! l ('\0'l is importatrt, because itjsjhlonulvayrhg fiuctiaDs that work with sEing can how where-altringinds.In fact, a string not telffifre6d by L:\0:is not really a strin-g. but
mer$-Lsollectiod of characteN.
C concedes rhe fact that you would use strings very often and
hence provides a shortcut for initialising strings. For example, the
string initialised above can also be initialised as,
char namel] = 'HAESLER' ;
Nole !hat. in this declaration'\0' is not necessarv- C inserrs rhenull alrromatically. Ih€ \0;;;;l md,-m irinttng strings.This is illustrated in the follovring pmgram.
/- Program 33 */
main0
{char namel]= "Kilnsman' 'int ij
i=0;while ( oamen )(
printf ( 'bo/oc yoc yoc %d, name0, ' ( narE + i ),.(i+name),ilftaneJ];
i++;
))
And hele is the output...
KKKKt t
iiii
nnnn
ssssmmmnlaaaannnn
This program doesa't rely on the length of the striag (number ofcharacters in string) to prinl out its co ents and hence is definitelymore general. Here is aaothea version of the same program; thisolre uses pointels to access the aray elements.
H E s L E R \0
4001 4002 4003 4004 '1005 4c[6 4007 4008
136
f Program 34 'if Prcgram to pdnt sting demenb using pointer nobtion '/main0
t,/fhar name11='16;61a|1' '
char'ptr;
ptr = name; f siore b6e addless oJ sting -/
while ( -ptr != '10' ){
pnntl ( '%c', .pr ) ;
Pf+|;)
)
As with the integer aray, by mentiodng the name of the array we
set the base ad&€ss (addrEss qf the zemlb eleraq*>gf-the a!r.yfufrr*-arm*ffiA i, lte variable ptr using'
ptr = name ;
Once the base address is obtained in Ptr, *ptr raould yield the
value at this aditress, which g€ts pdrd Promptly thrcugh,
printf ( 'o6c', 'pts) ;
Theq ptr ls incremented to point to the next chaIacter in thb
string. This deiv€s ftom twq factsl array elements are stored incontiguous mernory locatiols and on incremerting a pointer itpoints to the innediately trext location ofits tJDe. This process is
canied out till ptr.gs!:t po-itrJtq-llbq-la!! Jharg9ler in the stli!9,
lPllsr\o',Even though thcre are so many ways (as shown above) to refer to
the elements of cbaracter aray, rarely is any ore of them used to
ChLpter 3: Pointers and Strings 137
print out an array. This is because, prhtf( ) ftrctio! has got asweet and simple way of doing it, as shown below. Nott thatprintf( ) doesn't pdnt the .\0,.
f Program 35 ./maino
{char namell = 'Klinsman' 'printf ( 'ho/os'. name ) ;
)
The %s is,-a fognar ryjfigatioo for priutjng out g qEilg_ Thesame speclncaEon can be used to rcceive a string ftom rhekeyboard, as shown below.
I Program 36 'imain0
{char namel2sj ;
printf ( lnEnter your name: ' ) ;scanf ( '%s'. rlame t :
printr (EEil6-yo-iF,-iame ) ;
)
And here is the outpt t
Enter your name: DebashishHello Debashishl
Note that the decla.atioo ch.r mme[25] sets aside 25 charaotersunder the arlay naEe[ l, whereas the scanf( ) funotion fills irt thecharaclers ryped ar keyboard into ttis-arsaFsSEE;;;GFB.r-I!. Narurally. we should pass the base address ofthe arrav to thescant( ) lunctlon.
138
Staldard Library String Functions
C has a large set ofusefi string handling library funciions. Here,
we would illustrate the usage of most commonly usod functions(strlen( ), strcpy( ), strcar( ) and strcmp( )) through a program.
f Program 37 '/#include <sting.h>
main0
{char sff [20] = 'Bamboored' :
char stzll = 'ChaC '
char str3lml ;
int I, k;
t=sUen(sH);Pdntf ( 'hlerEth of stirE = %d', I ) i
sucpy ( slr3, sbl );printf ( '\nafter copying, sting str3 = %s', str3 ) ;
k = stGmp ( sfi, stz ) ;
printf ( \on compaing stl and dr2, k = %d', k ) ;
k = strcmp (str3, slrt ) ;printf ( lnon compadng st3 ard sM , k = %d', k ) ;
strcat ( sk1. st2 ) ;
pintf ( '\non concatenation strl = 96s', si'1 ) ;
)
fhe output would be...
length ofsting = 10
after copying, sting str3 = Barnbooy'ed
on comparing sH and st2, k = -1
on comparing str3 and sff!, k = 0
Chapter 3: Pointers and Strings 139
on concalenation str'l = Bamboozledchap
Note that itr the call to the fiinction strlen( ), we are passing thebase address of the string, ald the function in tum retums theIength of the string. While calculatiry the length it doesn't count'\0'. Can we not lrlite a ftoction xstrlen( ) I.hfch imitates thestaDdard library fiEctioD rhleD( )? Let us gi"la u oy...
i' Program 38'/ ,/main( )
{char arl ]= 'Bambooy'ed' 'int lenl,len2;
lenl = xstden ( an ) ;len2 = xstrlen ('Hum8Dunpty') ;
printf ( lnsting = %s lerEth = 96d', ar, lenl ) ;printf ( '\nsting = %s leng$ = 96d', 'HumptyDumptf, bn2 ) ;
)
xstden (char's ){
intlength=0;while (.s != \0' l{
lenglh++;
)
retum(length):)
The outpul would be...
string = Bamboozl€d length = 10string = HumptyDumpty lenglh = 12
140 Undersanding Poinws In C Chapt* 3: Pointers and Strings 141
The turctiotr xstrle( ) is fairly sirrple. All that it does is it keepscounting the chaiacteN till the eod ofstring is trot met. Or in otherwords keeps counting-gbaracters till the pointer s doesn't point to
final string. I lsave it to you to develop your own *sttcat() anhnes of xstrlen( ) ard xst{cpy( ).
Another useful striag fuootioo is strcmp( ) which compates twostrings to find oulltrtrcfhelthey axe same or differetrt. The twostrings are compared lette. by letter until there is a mismatch orend oFonsolltre sdqg! i! iqcheq whichever occurs first. If Ore
two strings are identical, strcEp( ) reh'rtrs a value zero.'lf thev'renot.li r66mllEE nunreric differenie betw:en th-the ASCII values ofLhe first nonl-nratciinlitir of characiefs.
The exact value of mismatch will mrely concem us. All we usuallywant to know is vhether or not the first string is alphabeticallyabove the second string. If it is, a negative value is returned; if itisn't. a posirive value is refumed. ADy non-zero value means thereis a mismatch- ter us try to implement this procedure into afunction xstrcmp( ), which works simitar to the strcmp( )function.
xstrcmp ( char 's'1 , char's2 ){
while ( ts1 =='s2 )
(ir (
.sl == 10' )
Ietum (0 ) ;
sl++;s2++ j
.)
retum('s1-'s2);)
Alothcr function that we have used in Program 37 is strcpy( ).This functiol oopies the contenls of one strilg into another, Thebase addresses ofthe source and target stdngs should be suppliedto this tunotion. On supplying the base addElgggsEgylLljoeson copyiDg the source shitrgjllq lhp target striDg till it doesn'tencounlEilfiEdod of source strirg..ll is our .espo;sibility to see toit that target string's dimeasion is big enough.Jo hold-the stringbeine,aopiedjaro it. Thuq a string gets copi€d hto aoother, piece-meal, charaoter by oharacter. There is no shortcut for this, Let usnow ancmpl to mimic strcpy( ) via our own st ng copy firnclion.which we lvouldca rstrcpy( ).
xstrcpy (char1, char's )
{while (.s l= \0')(
,t =.s;s++;l++;
I't = \0' ;
)
Note that having copied the entire souce string irto the target
:trinCt it rj necgssSry_bglac: a '\0' into the larget string to 44rk
trs end.
The strcat( ) furction concateDates the source string al the end ofthe target string. For exarnple, "Bamboozled" and "Chap" onconcatenation would result into a strilg "Bamboozledchap". Notethat the target shing strl I I has beetr made big enough to hold the
142 Understanding Pointers In C Chapter 3: Pointers and Strings 143
Pointers and Strings
Suppose we wish to store 'Hello". We may either store it in a
strillg or we may ask the C compiler to store it at some location inmemory and assign the addrcss ofthe string in a char pointer. Thisis shown below:
char strl]= "Hello' '
char.p ='Hello";
There is a subde dilference ia usage of these two foms. Forexamole- we cannot assisn a shins to aDother- wheteas. we canassign a char pointer to tuolher char pointer. This is shown in thefollowing progam.
f Program 39 '/main( )
{char strl []= "Hello' ;charstu2l10l;
char.s = 'Good Momir€' ;char'q i
sf2 = std jf enor*/q=s;/'works./
)
strl ='Bye';FerDr'/P = 'BYe" ; /' l'/otl(s'/
Alsq. o-!.ce a sqiqe laq tregn defned.strings, such an operation is
/. Program 40 '/main0{
char strl [] = 'Hello" 'char'p = 'Hello''
The cazsl Qualifier
The kewvord cotrst (for constant), if presenl- precedes lhe data
t}?e of a variable. It specifies that the value qftts:aeable-Ei[lot*cha4g9$Ilugborll-&efietf.f,t Any atlempl to alter lhe value ofrhe variable defined wi$ this qualifier will result into an errormessage ftom compiler. cotrst is usually used to rcplace #delinedconstants.
const qualifier ensures thar your program does not inadvertentlyalter a variable that you intended to be a constant- It also remindsaflybody rcading the program listing that the variable is notintended to cha[ge. Variables wih rhis qualifier arc often namedin all uppercase, as a reminder that they are constants. Thefollowing program shows the usage ofconst
f Program 41 '/main0(
float r, a ;
const foat Pl= 3.14:
pdntf ( lnEnter radius: ' ) ;
scanl ( 'olof, &r ) ;
a = Pl'r'r;printl ( "Area of circle = %f, a ) ;
)
144 Understaading Pointen In C Chapter 3: Pointer: and Strinss 145
const is a better idea a$ codpared to #defirc because its scope ofoperation can lF controlled by placinq it appN'priately ejrher insidea fiuction or oufside aI filnctiotrs- If a colglilplgqlin5ide atunc@reas,ifitis placed outside "U f&€6on&$+its efect would be global. Wecannot exercis€ such finfi control wtile usiDg a #deline
crrs, Pointers
Look at the followhg program:
f Pw.an 42'lmain( )
{char sH[]= 'Nagpul 'charsr2{101;
xstrcpy ( str2, sfi ) ;printf ( 1n%s", st2 ) ;
)
xstrcpy (chart, dEr's ){t/while ( .t != 1S ){
t*.s#;
)*t
= 10' ;
)
This progmm simply copies the contents of sfrl[ I into str2l ]using the firDction xsarcpy( )- What would happen if we add thefollowing lines beyond the last stat€ment ofxstrcpy( )?
s=s-6i
.s=,K;
This would change the sourc€ saing to ':Kagpur'- CaIr we notensure lhat the source Sing doesn't change eveD acaidentally inxstrcpy( P We ca4 b/ chatrging the plotoq/pe ofthe fuirction to
void xstrcpy ( chai onsl chal. ) ;
Corespondingly the definitiotr \r,ould change to:
void xstrcov ( char't. mns{ char t }
{f code '/
)
The following code fragrned would help you io fix your ideasabout cotrlt further.
char'p = "11s110' t
" *'* b yaiaile, so b sfring '/.P='M';fuo*s'/
P='BYe"jl'orks'/
qonst char'q = 'Hello' ' f $ing b corEbrt Finter b nd 1'q='M';lenor'/q = "BYe' if wo s'/
char const ts = 'Hello' ; F sting b corEtant pointer is mt '/
's = 'l\.,|' ; f ercr'/s = 'Bye" ;f wofts'/
char *
const t ='Hello'; f poinbr b colEbot sfiing b mt'/
t = 'Bye' i f ercr'/
constchar*constu='Helb-;f*iU b consbnt so is trinter */
'u='M;fenor'/u='8ye';ferDr */
r46 Undersnnding Pointers In C Chapter 3: Pointers and Strings 147
Returning consl Values
A function can return a pointer to a conshdt stritrg as shownbelow.
I Program 43 '/main0
tconst char
.tun( ) ;
consi char 'p ;
p=tunO;.P
= 'A' ; /. enor'/printf("\n%s",p);
)
const char ' tun( )
{retum 'Rain' ;
)
Here since the fimction fun( ) is retmring a constant string, wecannot use the pointer p to modi& it Not only this, the follov.ingoperatiotrs loo would be iDvalid:
(a) main( ) canngt assign the ietum value to a pointer to a non-cotrst stri0g.
O) main( ) cannot @ss the Ietrm value to a fimction that isexpectiog a pointer to a tron-const string.
Two I)imensioual Array of Characters
In the previous chaptfi we saw seveml examples of 2_D trumericarays. Let's now look at a similar phelomenon, but one dealingwith chamcters. The b€st way to urde6tand this cotrcept is through
a program. Our example program asks you to qpe yout name.Wllen you do so, it checks your Dame against a master list to see ifyou are urofihy ofentry to the palaoe. Here's the progmm...
f Program 44 */
#include <stdng.h>
#define FOT ND I#define NoTFOUND 0main( )
{char masbrlistlolllol = {
'afStay''',paras',
'ftman','sinivas',taar,'rajesh'
):int i, iag, a;charyoumamenol;
printf ( 'hhter your namq ' ) ;scanf ('%s', youmane ) ;
flag = 11916Or*, 'for(i=0;i<=5;i++){
a = strcmp ( &m6blflsu[0], pumame ) ;
{printf ( "Welcome, you can ent€r he pala6e' ) ;
flag = Pgg*' 'break;
))
if ( flag == ll6lPgg^t,printl ( "Sorry, you are a tespassef ) ;
148 Ufldersto ding Pointers In C Chapler 3: Pointen and Strings 149
)
And herc is the output fot two sample runs ofthis proglam...
Enter your name: dineshSorry, you are a bespasser
Enter your name ramanWelcome, you can enbr t|e palace
Notice how the twoiimensional cha@cter aEay has beeninitialised. The order of the subscriDts in tle aimpoltant. The first subscript givas thinumber of names in thearray, while the second subscript gives the length of each item inthe array.
Instead ofinitialising names, had these names been supplied fromthe keyboar4 the program segnent u,ould look tike this...
for(i=0;i<=5;i++)scanf ( 'Yos'. &masbrlis{ilpl ) ;
While comparing the strings through strcmp( ), nore that theaddrcsses of the strings are being passed io strcmp( ). As seen inthe last section, ifthe two strings match, strcmp( ) would retum avalue 0, otherwise it would ietum a non-zero value.'
The variaile flag is used to keep a record of whether the controldid reach inside the if or not. To begin with, we set this flag toNOTFOLIND. Later through the loop if the names match this flagis set to FOUND- When the control reaches beyond the for loop, ifflag is still set to NOTFOUND, it means none ofthe names in themaste:llllllll<tched with the one supplied from the keyboard.
The names would be stored in memory as shown in Figure 3.2.Note that each string e[ds with a '\0'. The arrangement as you canappreciate is similar to that ofa two-dimensional numeric aray.
Figure 3.2
Here, 1001, l0l l, 1021, etc. are lhe bqqi3ddresses of successive
namds.Es-E6-E6--iEe above 6gure, some of the names do notoccupy alllf,66-yes reserved for them. For example, even though10 bltes arc rcseryed foi storing the name "akshay", it oocupiesonly 7 bytes. Thus, 3 bytes go waste. Siinilarly, for each namcthere is some amount of wastage. Itr fact, more the dumber ofnames, more would be flle wastage. Cao this not be a\oided? Yes,
it can be... by usiog a data tlTe caled atr array of poiltsrs tostrings. whicb is our oext topic ofdiscussiotr.
|rray of Pointers to Strings
'akshay';paras"
'raman','sdnhr6','gopd,
"ajesh'
As we know, a poitrtq variable always oontains an addrpss.
Therefore, if we colstuct a array ofpointers it would cofiaitr a
nirmber of addresses. I,€t us see how the mm€s itr the earlierexample can be storcd in lhe array ofpoiDters.
ch'namesl]={
);
akshay\o parag\o gopal\o rajesh\o
1001 1011 t02t r03l 1041 l05l
150 Understanding Pointers In C Chapter 3: Pointers and Strings t51
In this declaration nam€s[ | is aD array ofpoidtsrs. It contains base
addresses ofiespective names. That is, base addresses of "akshay"is stored in lrrmes[0], base addr€ss€s of "parag" is stoied innamesu and so on. This is depioted in the following figure.
I"Lhry\olr0M
Trr.,"\o I1(x8
I ".1,,i-r-\ol2006
fs"p,r\ol l-"j"h\o I4008 60/}2
naEes[ ]
fe-"sql7118
8112 8r14 8116 8lt8 8120 8122
lm4 7ll8 l(x8 2006 4008 6002
Figue 3.3
In the two-alimensional axray of characters, the strings wereocaupying a total of 60 bJ.tes. As asaiNt this by using the array ofpointers to stings ihe same shings can now be stoEd usfurg only53 bytes, 41 bytes for l e actral sairyE ard 12 for the array ofpoiotets. A substa i4l saving that go€s on increasitrg with theoumber ofnames being stored.
Thus, one rcaso4lqslore slrisgs-i! an array of pohtel$ is to makemoFeffi @L]E9lrtavailahle-gleEory.
Another reasotr to use alralglpqiq@-to" sl9le.-s$TgLi-s:l;o_guhingreater earie in tte manipulation of the stsiggs. The followingprcgra@ isverysimple.We watrt to exchange the positions of the names "Ianrad" and
"$inivas".
f Program 45 '/m-ain( )
{char 'namesl ] = {
'a|rshall,'parag','raman',
'srinivas','gopaf,'rajesh'
l;char'temD i
printf ( \Oiginal: %s 9Ls', nantes[2], namesp] ) ;temp = names[2] ;
namesl2l = namespl :
namespl= lemp :
pdntf("\nNew:%s %s', nan€6[2], mrnespl ) ;
]
And here is the output...
Original: raman srinivasNew: sdnivas ramam
ln this progmm all that we are rEquircd io do is exchange theaddresses of the names stolgl;g]Bg arraJjlt-pqitlEls, rather.thanthe EfrEFIRAiselGs:Th_lrs" bv effectins illct one erchanse we arei-E&hatrge we areable to interchange name_!r. This Eak€s rnamgiry strings veryconvenlenl.
fhus, from the point ollgglStrg.igrt-EE r"ry usage and easeof programming, an arFy of pointers to strings definitely scoresover a two-dimeflsional chaiacter array. Tbat is wh. y, even thoughin principle sFings can be $lorcd and handled throl:g} a two-
152 Undentanding Pointers In C
dimensional ar-.ry ofcharacters, in achral practice it is the aray ofpohtels to strilgs which i !trorq corEnoDly used.
In Plogram 45 iastead of o@hangiry the oames within main( )suppose we d€cide to carrJ. out this crchadge through a furBtionBwap( ). To this futrction suppose we would pass the addresses
givel by ( tramer + 2 ) and ( nrmca + 3 ). These addr€sses wouldbe collected ir two vadables, which are pointers to pointers
(why?). Using these pointeN theri the Dames can be exohanged.
This is how the $wap( ) fimction would look like...
su/ap ( char *sl, char \2 )( -char't; /.
t = 's'1 ;
's1 = 's2 ;.s2
= l;)
Limitation of Array of Pointers to Strings
When we are using a twodimtglqi@!libefiy to eithet idtiali lhe saings where we are <GEl'riry the
Chapler 3: Pointers atd Strings 153
for(i=0;i<=5;i++){
pdntf(\Enternane:!);scanf ( '%$. namesE ) ;
))
Tte progmm doesn't work because when we are declaring thearyfj-s.-coltabiryj Jdues, Atr?im;ia-G;;E;tetywrong to sefld these galbg ( ) as the addresseswhere it should keep tf,e strings received from the keyboard.
As a compromise solutiotr we may fiIst allocate space for eachname using malloc( ) and then storc lhe address rehrmed bymalloc( ) in the aray of pointers to shitrgs. This is shown irt the'following program-
f Program 47 '/f Program to overcome limihthn of aray gl pointeE to stings '/#include <alloc.h>
#include <shng,h>
main0{
char 'name[s] ;char str[20] ;int i;
for(i=0;i<5;i++){
Pdnf (lEntera Stim' ' ) 'gets (slr);nameu = ( char') malloc ( stlen ( ifr) );stnpy(naflEfl,dI];
)for(i=0;i<5:i++)
printl ( 1n%s', nameE ) ;
array, or teceive the stings using $crD( ) fi{rotion. Howeve!,
when we are using an array ofpointers to strings we can idtialisethe strings at rhe p.laoe whc(e we aI€ declari[g tte aray, but we
cantrot receive the stings fiom kE/toad using rcenf( ). Thus, the
following pogrm would rcver wort out.
f Program 46 '/main( ){
char'nsmes[6];
154 [email protected] In C
Solved Problems
[A] What will be the output of the followiug progmms:
(1) #include <sting.h>main( )
{char s[ I = 'Rendez\ot6 !' ;
prinf ( 1n%d:,' ( s + sthn ( s ) ) ;
)
O"tPut
0
EJepla ation
No 'Reodezvous !', but a zero is printed out. Mentioning the
name of the string gives the base addrss of the string. The
tunction strlen( sJ itums the length of the stling s[ l, whichin this case is lz-In printf( ), usiag the 'ralue at address'
operaror (often called 'contetrts of operator), we are trying toprint out the contents ofthe 126 addrcss Aoul the base address
of the strlag. At lhis ad&ess there is a '\0', which isautomatically stored to mark the eod ofthe striag. The ASCUvalue of '\0' is 0, which is what is being prioted by the
prtntf( ).
(2) main0
{pdntl (5 +'Fffiinile );
)
Output
(3) maino
{
155
mile
Explanation
When we pass a stiag to a function, wbat gets passed is thebase address ofthc string. Itr this case what is bsiog passed toprht( ) is the base address plus 5, i.e. address of 'm' in"faosimile". prlntf( ) p.ints a string startiug from *re addressit receives, up to the etrd ofthe string. Hstroe, in this case'mil€' gets printed.
char ci[20] ;inti;tor(i=0;i<19;l+i)
'(ch+i)=67''(dr+i)=10''prinf ( t96s', ch ) ;
)
O rput
ccccccccccccccccccc
Explatation
Mentionilg the rume of the array always gives its basead&e$s. Thercfore ( ch + i ) would giv€ rhe add&ss of the i6elemetrt from tbe bos€ ad&ess, aod *( ch + I ) would give thevalue at this address, i.e. the value ofthe i6 elernent. Tlfoughlhe for loop we storc 67, vhich is the ASCtr value of uppercase 'C', in all lhe locations of the string. Once the codrolreaches outside the for loop the valuc ofl would be 19, and inthe l9d location froE lt€ bas€ address we storc a '\0' to ma*the end ofthe sting This ir essential, ac Oe compiler has no
1s6 Unilerstanding Pointers In C Chapter 3: Pointers and Strings
other way of knowing where the shing is teminated. Io thepritrtf( ) that follows, 7.s is the foIEBt specifioation forprintiry a stting ad c\qives th. b"leaddress of the string.
Hencc*artitg ffinr the first eleme , the complete string isprhted out. -
(4) mdin0
{char stl I = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 } ;
)
Output
000000/
Explanatiott
In all 10 elem€nts of sh[ l, ar integer, 48 is stored.
Wooderhg whether a char string cao hold itrts? The answe!
is yes; as 48 doe! not g€t stor€d literally iD the clernelrts. 48 isiuterpret€d as lhe ASCI value of the ohalactel to be stored inth€ string. The charact€r cotespotding to ASCII 48 happeN
,o be 0, which is assigned to all the loc.tions of the string.
e, a character pohter, is assigaed the base ad<hess ofthe stdng
rtrH; Next, in the if conditio4 the value at addr€ss contahedio r is chect€d for tuth/hlsity. As 0 lepresellts ASCtr 48, the
cordition evaluates to tue every time. IEespective ofwhetherthe condition is satisfi€d or trot r is itrcrgmented so that each
time it points to the subsequcnt aray elemed. This entirelogic is repeated in the for loop, printing out l0 zeros in theprocess.
(5) main()
{charstr'lll='Hello''char stz[ ] = 'Hello' ;
if ( strl == str2 )pnnf('inEqual');
elsepnnf{\lunequal');
)
Ourput
Unequal
Explsnation
When we meotiou the oame of the ariay we get its baseaddress. Since strl and str2 are two different arrays, theirbase addrcsses would alwalas be differetrt. Heflce, thecouditioa in if is awir goiDg to get sati$fied. If we are tocomparc the conte s of two chrr atays, we should comparethem on a character by char.cter basis or use strcmp( ).
(6) maino
{charst4lol = { 0, 0, 0, 0, 0, 0, 0, 0;0, 0 } ;char's ;inti;s=str;for(i=0;i<=9:i++)
char's ;int i;s = str :
for(i=0;i<=9;i+}){
if(\)pnntf ( '%c', 's ) ;
)
0000
1s8 Understanding Pointers In C Chapler 3: Pointers atd Strings 159
if { -s
)pdntf ( '%c', -s
) ;
s++;
)
Ou.tprt
No output
Explanation
Though you may not have expected zerces to be outputtedthis time, you surely did exp€ct some output! We stored thecharacter ooresponding to ASCII 0 fu all 10 eleme s of thestring. Nex! w€ assign s, a char pohter, the base ad<lress ofthe string. Through fhe for loop, we arc atternptiog to prhtout all eleEents one by one, but not before imposiug the ifcondition.
The if is made to test the value at addrcss cootained in s
before the execution ofprintf( ). First time through the loop,*s yields ASCII 0. Therefore lhe lf statemert reduces toif ( 0 ), and as 0 stads for hlsity, the cohdition ftils. Hence, s
is incremented aDd coDhol loops back to for withoutexeculing the prfutf( ). The same thing happeN the next timearound, and the nex! and so on, till the for loop ends,resulting in no ouout at all.
pnntf ( 'yoc', 'abcdeEh'[4] ) :
Explatatiott
We know that exp.€ssion r[,ll gets converted to *( a + 4 ),where a gives the base address of the array. On similar linosn.bcdefghn[,{ becomes r( tr.bcdtfghn + 4 ). this is same as*( base iddress + 4 ). ( brse .ddrct! + 4 ) yields address of'e'. Thus, what gets pass€d to pff( ) is the chaBctel 'e','wbich is promptly prhled ouL
char sfm = 'Stings' ;pdnf ( '96s', sfr ) ;
)
Output
Cannot predict.
Explanatial
Herc str[ ] has beetr declarcd as a 7 chaiacter aray and into ita I character striry has beeo stoted. This v,.ould result intooverwriting of the bye beyond the rcventh byte reseNed forthe array 1,ith a '\0'. Th€re is always a possibility thatsomething irlpofiant gets overwri$ea, wiich would be unsafe.
main0
{char
tsE[ I = { 'FrogE , 'Ib', 'ilctr, 'IIe.', 'nlef, "Crcak!' } ;
pdntf ( '96d 96d', dzeof ( sfr ), sizeof ( stlol ) ) ;
)
(8) main( )
{
(7) mainO
{(e)
OutWt
160 Undersnnding Pointers In C
Olttpul
122
Erplanatioa
Me[tionhg the name of the array gives its base addrcs$.However, wheu used wilh siz€of( ) it yields the number ofbltes occupied by the array in mernory. Since str is holdingsix addresses, of2 byt€s eacll $lzeof( str ) gives 12.
str[0] yielils addrcss of "Frogs'. this ad&ess is reported as 2bytes big.
main0
{char s[] ='C smad' 'inli;for(i=0;sn;i++)
pdntf ( 1n%c %c 9dc %C, sn,'( s + i) , ilsl,'( i+ s ) ) ;
)
Output
ccccssssmmmmaaaarrrrtttt!!t!
Explanation
Chapter 3: Pointen and Strings 161
The above program nrbs irl the point Olat s[il, i[sl, *( s + i )and *( i + s ) are various ways of referring to *re sameelement, that is the ib elemc[t ofthe stsiDg !. Each element ofthe stritrg is pinted out four times, till rhe en<l of the string isencountered. Note that in the for loop therc is al1 expressions[i] in the condition pat. This meaas tte loop would continueto get executed till s[il is rot equal to zero. We oan afford tosay this because a string alwaSrs ends with a '\0', whoseASCII value is 0. Thus the for loop will be teminated whenthe expression s[tl yields a '\0'.
(11) main( )
{char s[! = 'Oinks Grunb and Gutrav6' ;
pdntf ( \96c', '( &s[2] ) ] :
printt(tu9k',s+5);pdntf(tryos',s);printf ( \Yoc','( s + 2 ) ) ;printf(\%u',s);
)
Output
n
Grunts and Gutrau6Oinks Grunts and Guffa,,!,s
n
404
E4 anation
In tlie fiIst printf( ) the 'address of operator, &, gives theaddress of the secotrd element of the string. Value at thisaddress is 'a', which is printed ollt by the printf( ) usirg yoc.
Since ! gives the base address of the array, ( s + 5 ) wouldgive the .ddress of the fifth element from the bas€ addxess.
(10)
162 Understanding Pointers In C
This address is pass€d to the s€ootrd printf( ) Using the
formal sp€cification yos, the co ents ofthe string are printed
out the 5d eleinem oowards.
The fiird prin( ) priDls lhe etrhre stsing as the base address
ofthe saing is being passed to it.
The fourth print( ) is made to print the second character ofthe striog, as *( s + 2 ) is oothitrg but s[2] Thus '[' gets
printed.
Does the output of lte 6nal pritrtf( ) suprise you by printiDg
out a number, 4(N? Note that the format sp€cifioation you isused \i/ith s, which gives lhe base address of the saing. Ithappercd to be 404 when we executed lhe proglaltL whioh go1
printed out. On executiDg the same yourself, you rray get any
other addr€ss, depending oa what addEss is allotted to the
strilg by the cotrryiler
(12) main( )(
char ar{ I = 'PtolQocleliru my peace ol mind..'
inti;pdntf ( \%f, 'ar ) ;an+;pdntl ( '\n%c', -arr
) ;
Output
Enor mesrage: Lvalue rcquiEd in furrcIion main
Explarratio
Chapter i: Pointers and Strings l6j
arc rcferring to tle base add&ss ofthe string. This is the onlyLtformation lhat helps the C conpiler keep track of the stringarrl l. If this hfomation is los! there is oo way the oompilercan acoess the striog. So, this particular address is given afavoured stahrs, that of a constant. The statement arr.+ isessstrtially wrong because a constant oa!'t be incrcmentedand hetroe the compilel asks for an Lvalue, which is a valuethat can be ohanged.
main0{
charst{l = 'Limeicks' -
char *s ;
s=&stl6l-6;while ('s )
Pdntf ( "%c', 's++ ) ;)
(13)
Outp t
Limedcls
Explanation
The following figqr€ would help ir analyzing this program.
Though everything seems to be in order at first glance, thele
lies a fundamedal error irl oua pfogiam. When lve say arrr we
164 Chapter j: Pointers and Strings 165
'ple@');
staicchar-MI={s+3,s+2,s+'l,s};char-p = pg 'pdntf('ln%s',*+ip);Printf ( tli6s','-'+lP r 3 ) ; -/prinf(t96s"'pt-4+3);pintf ( 1no/Gs', p[-llF1l + 1 ] ;
)
Oatput
cone
aseIeen
Explanation
This time we seem to be faced with a galaxy of sta$! Wewould do well to take rhe help of a figure iu orossing themone by one. At the outset, s[ I has been declared alrdinitialised as an array ofpoidters. Simply salng r gives us thebase ad<lress of this array, ,()06 as can be seea Aom Figure3.5. ptrl ] storcs the addre$s€s ofthe locations wh6e the basead&esses ofstrings comprising s[ J have been stored, startingwith the last string. To put it more clearly, ptr[o] stores theaddress 4012, vhich is the address at which base a{&ess ofthe string "please" is stored. Similarly, ptr[l] stores thead&ess 4010, which is where the base address of the string"cone" is store4 and so on. Sirce ptrl I essentially stores
addresses of addresses, each olemetrt of it is a pointer to apointer. aDd has been declared as such usirg **.
Finally, the base addrcss ofpli[ I is assigned to a pointer to apointer to a pointer, p. R€€ling?! Going ttuough the figure
Figue 3.4
s has been declarcd as a pohter to a ch.r, whereas str[ ] has
besn declaEd as a chardcter strilg. Let us Bow evaluate the
expressior &str[6] - 6. Here &str[6] gives the addrcss of the
sixth eleme* ofthe string. This address oan also be obtained
by the expression sh + 6. On subtractfurg 6 from this, we,end
up v/ith good old str, th€ address ofthe zeroth element, whichis assigaed m r.
In the prhtf( ), lhe valuc at addrcss cotrtaired in s is printed,
and then s gpt$ incr€mented so that it poitrts to the next
character in the sting. The while loop conti[ue8 till I doe$r'tpoint to '\0', vhich ma*s the eDd ofthe stritg. Wheo r points
to '\0', the value of i3 would be 0, a falsity. Helrce the whlleloop will be terminated"
main0
tstatic char's[I= {
'ice','sl€€tl"
. 'coIE,
srt 1
I- k \0
4001 4002 4003 4004 4005 ,1006 4007 4008 4009 4010
l-4oo{j11-f 4oorl
(14)
would decidedly aid you to get disentangled. Thus, p is
assigned lhe addrcss 6020.
\Chapter 3: Pointers and Strir,8.s 167
point to the oext locatioo of its type. The words 'of its q?e'hold significance here. A pointer to a char on incrementinggoes ooe bj.te fifther, sirce a .htr is a l-byte entity Apointer to arl iBt points 2 byt€s fi ter, as an irt is a 2-b]teentity. Also, a pointer by itsef is always a 2-byte entity, so
increm€lting a pointel to a poiok would .dvanoe yoo by 2bltes.
Having convinced ourselve$ thtt P trow storcs 6022, we go on
to evaluad:'the exprcssion firther. rp signifies contents of6022, i,,e, 4ol0. r'p meaDs vatue at ltis add!€ss, i.e.' value at4010, which is the address lOlO- The prlrrtf( ) p nts the
string at this address, which is 'cone"-
r-r++p + 3
p, presetrfly co ains 6022, wldch m incremetrtitrg becomes
6024. value at this ad&€ss is lhe addr€ss 4008, or in t€rms ofB, s + l- On lhis 0!€ d€clem€[t q,€Btor --works.to giYe 4006,
i.e. s. Value at 4006, or r( t ) is 1000. Thus the bxpressiou is
now reduced to ( 1000 + 3 ), md a,nat finally gets passed toprintf( ) is the addrcss 1003. Value at this address is a '\0', as
at the end ofevery sting a 'W' is ihs€rted automatically This
'\0' is pritrted out as a blatrkby pfirq)-.PL2l + 3
The cuneDt address itr p is 6{D4. 'Pl-2J can be thought ofas*( *( p - 2 ) ), as ntrmlil is sme as r( rum + I ). This itr tumevaluat€s as *{'(60A -2)\i.e. i( *( 6020 ) ), as p is apointer to a pointer. This is equal to r( 4012 ), as at 6020 the
address 4Ol2 is present. Value 8t /Ol2 is 1015, i.e. the base
address of the fourft strin& hlease"- Having reaohed the
address of letter 'p', 3 is adde4 which-rields the address
1018. The string starting fiom 1ol8 is pdtrted out, {hichcomprises ofthe last thlee leltets of'please", i.e. 'ase'.
Figure 3.5
Having soied out what i$ pres€nt wherc, we now proceed iothe printf( )8. Let us taclde tlro expressioas one by ooe.
"*+p
The fust o!€ piitrts out the stiog statiog ftom the address**J-lp. The -* goes to wort fiIst atrd increments p not to6021, but to @22. 't\e C compiler has been made tounderstand that on fucEmenting a pointer variable, it is to
\olslilele \o nle I\01 DI 1 3 \0
1000 1004
stol
,rol0 4012
pttol pt{ll prrt2l ptr[3]
40t2 4010 4008 4006
@20 @22 6026
P
l- 6010 I
168 Understatding Pointers In C
pl-1llll+ 1
The sbove €4,r€ssion oao be thought ofas *( pl-U - f ) + f,ar num[il aod r( n[D + i ) amounts to the same thing.Further, p[-11 can itselfbe sirrplified to *( p - I ). Hence wecan interyEt thc given expr€ssiotr as *( *( p - i ) - 1 ) + f .
Now lel us evaluate this exprcssion.
AAer the execution of the third printf( ), p still holds theaddress 6024. *( 6O14 - f ) gives r( 6022 ), i.e. address 4010.Therefore the erpt€ssioo Dow becomes *( 4010 - I ) + 1.Looking at lhe figore-you would agree tllat 4010 can beexpressed as r + 2. So now the expressior becomes *( s + 2 -1 ) + 1 or *( s + I ) + l. Once again the figure would confirmthat *( $ + 1 ) eialuates to '( 4008 ) and *( 4008 ) yields 1004,which is the b6se addrcss of the second string "green". Tothis, I is addid to yield the address of the first elemert, 'r'.With this as the startitrg addEss, prhtf( ) prints out what isrcmainitrg ofthc string "green".
main( )
{char si4 I = 'For Your eyes onlf 'inti:char 'p ifor( p = sf, i = 0 : p +i<= st+stlen ( str) ; p++, i++ )
pdnf('96c"-(p+i));)
Output
Fryu ysol<spac€>
Explanatioa
169
Figue 3.6
The for loop here hosts two initialisations and twoincrcmentations, which is perfectly acceptable. However,there must alli.ays t e a unique test conditio[
In the initialisation part, p is assigned thg base address of thestring, and i is set to 0. Next the conditio[ is tested. Let usisolate this condirion lor closer examination.
p+i<=str+stien(str)
Since length Df str[ | is 18, str + shlcn ( str ) would give theaddress of '\0' present at the end of tlrc strhg. If we assumethat the base address of the string is 40O1,l en the address of'\0' would be ,1019. Sincc p bas been assigned the baseaddress of the sEing in the first go, p + 0 would leld 4001.Sirce this is less than 4019, the condition holds good, and thecharaoter prcsent at the address ( p + 0 ), i.e. 'F', is printEdout. This can be uodeGtood bett€f, with the aid of the Figue1.6.
After this, both p and t are ircEmqted, so that p colltains4002 and i coatains l, aod orce agaiu the conditior in the forloop is tested. This time ( p + i ) yields 4003; whereas the
(15)
"rt lF I v I v s I v ,0
4001
p
l-;or I
170 Ilnderstandtutg Poin ers In C
€xDressio! sf + .hlm ( sh ) contilues to yield 4019
Thercfore, egaiD lhe coodidon is satisfied and the chamcter at
address 4003, i.e- 'l' gets printed. Likewise, alternate
elem€nts ofihe strhg arE ouEutted till i is 8, coresponding to
which f is piated Nov, when p and i are incremcnted one
more 1ime, iha &st co litioo €valuates to:
p + 1<= sf + stlen (st)4019 <= 4019
The l8d el€usnt of ttr is of coulse the '\0', whioh is also
pritrted out as a blalt- Otr filtther inctemeotation of p and i.iootrol snaps out of the for and the program execution is
terminatetl
(16) main0
t, char stll = xldaydr ;
char's;s=sf+g;while ( s >= sfr )(
pnnf{'9{c',t);s-:
))
Output
MahyalaM
Explanatioa'
s, a poi t€r to a ch.r, is assigned an address 8 locations ahead
of tie tase ad&Ess of 6€ saing. Tbat meals s is ourrentlypoitrtiE to the last eleme 'M' ofthe string. Ifwe assume the
171
base address to be ul00l, the[ s would contair the address4009, Since this address is greater than the base add&ss, filsttime thmugh the loop the condition is:satisfied. Nsi-th€ valueof the expressioo *$ i$ prinred. Sinc€ s oontains the ad&€ss4009, the value al this addr€ss, i.e. 'M', gets p nted. Then s isdeGemented to point to the preceding elemeot, i,e. theelernent at addi€ss 4008.
This way ooe by olq the elements ofthe sEing are printed outin the reverse order, till s equals str, the addrss ofthe zerothelement. That the output is indeed the reverse ofthe originalstring can b€ verificd if you read 'MalayalaM' backwar&.You have bcen presented with a suing ttat reads the salneftom eithff end. Such strings, inoideotalll go by the oame'Palirdrcme'.
(17) main0
{char al I = 'Able f,as I ete I saf, elbA' 'char1, *s, 'b;s=8;b=a+sHen(a)-1;t=b;while (s != I )(
pnnf('96c',t):s+;pdnif( ',1);t-;
))
Output
Mbbllee wwaass ll ee
Explatation
172 Understanding Pointers In C Chapter 3: Pointers and Strings t73
C is a philosophy ol lih
ErplanarioL
To begir with, ss and tt are assigned the base addresses of thetwo strings sI J and t[ l. In the while, the value at addresscontained in ss is tested for operating the loop. The first nmethrough the loop ss contains the base address of the string.Hence *ss gives'C', whose ASCII value is 67. As any [on-zero value is a t[uth value, the condition evaluates to tue, andthis valuo is stored at the addiess contaircd in tt, i.e. at thebase addrcss of the stritrg t[ ]. Note that the + opentoroccurs afier the variables, so aller 'C' has been stored in thefirst location ofthe string t[ ], both ss and tt are incrcme[ted,so olat both now point to the fiIst elements of s[ ] and t[ ]respectively. In the second go, value at the addrcss containedin $r is tested in the while, and this time a blank isencourterc4 whose ASCII value is 32. The condition againholds good, therefore the blank is storcd in string t[ ], and ss
and tt arc incrernented. This goes on till the end ofthe stringis encourtered, At the end of any string, a '\0' is stored.ASCII value of'\0' is 0, which when tested in,the while,evaluates to fi[sity, and the contol comes out ofthe loop.
Note that the '\0' has not been stored into string t[ l. hence thecompiler does not larow where the string erds. We do so byinsertiDg a '\0' on leaving the while. Finally, the contents oflhe stsing t[ | are pdnted out.
rnE in( ){
dlarsll= 'Lumps, bumps, srrcllen veins, rEw pains':
dffltr4ol;dlarts,'t;t=t;ss=s;
The char pointer r is assigned the base ad&ess of seing a[' I.The ch.r pointgr b is assigned the addrcss 24 elements ahead
of the base address. Why 24? Because the furction sHen(a)yields tlle length ofthe string a[ lr which itr this case tums outto be 25. Thus b points to 'A'presed at the end ofthe string.
Another character pointer, t, is also initialised to the same
value as b. Assuming the base address of the st irrg to be
5001, s would be assigned 5001 atld b and t would be
assigned the address 5025.
Natuelly, first time thrcugh the while loop sioce s and t eenot €qual, the condition is satisfied. Hence the Pdntf( ) priats
out the chamcter at which s is pointing. Thus the character 'A'gets printed. Now s is inoremented, so that it poirts to the
character 'b'. The next printf( ) prints the value at ihe addrcss
oontained in t. Thereforc another 'A' appears on the scleen.
Affer printing, t is defiemented so that it starts pointing to 'b' .
This goes on till s ard I meet each othir, whence the whileends. At this instanoe, 3 and t both arc pointing to '/, ihe
middle charaqter oflhe entilo string.
(18) maino{
char sl I = "C is a philosophy of life' ;
char t[40] ;
char *ss,
'tt :
t=t;while ( 'ss )
1t++ = rss++
i
't=\0';printf(\r%s",t);
)
Outplt
(1e)
174 Understanding Pointers In C
while ( -tt++
=.ss++ ) i
pdntf("\nYos',t);
)
Output
Lumps, bumN, su/ollen veins, newpains
Expldnation
The program begirls by assigniag the ba8e addtesses of shingss[ ] and t[ | to th€ chaBcter poitrte$ !s and tt. The whlle loopthat follows next may raise a few eyebrcws. We have made itoompact by combining the assigntnent, test conditio[ and theinorcrnentation in the whlle loop itself. In effect the whlle hasbeen reduced to:
whlle ('tt++ = rss++
)
Hele the Ilull statement is executed so long as the conditionremairN true. How the condition is €valuated is like this...
In the while the value at the address storcd in ss replaces thevalue at the bddrcss stored in tt. After assigoment the test iscarried out io decide whether the while loop should contirueor not. This is done by testhg the expression rtt fortruth/falsity. Since curently tt is pointing to 'l' of'lumps', .ttgives '1' which is a truth-value. Following this s3 aird tt bothare inqemetrted, so that they have the addresses ofthe fiIstelements of strings s[ ] and t[ ] respectively. Siooe thecondilion has been satisfied the null statement is executed.This goes on till the end of the string s[ I is encounteredwhich is marked by the presence of a '\0', havitrg ASCtrvalue 0. When this character is stored in t[ l, *ta would give'\0'. This time when the coodition is tested, it evaluates to
17.5
false since *tt yields a 0 (ASCII value of '\0'). Thus, allelements of the first string are faithfully oopied into the
s€cord one, including the '\0'. On printing out sfting tl l, we
get the entire string as it was in 3l l,
(zo) maini )
{int ad12l ipdntf ( \l%d', sizeof(ar) ) :
)
Output
24
Explanarion
The slz€o( ) opsrator givcs the size ofits argument. As arr[ ]is an integer array of 12 elsments, saying rlzeof ( 8rr ) giveE
us the size of this aray. Each integer is 2 byt€s long, hsoa€
the array arrl I eogages twioe the numbe! of elements, i.e. 24
bytes.
(21) main( ){
char'rnensl l = i"Some love one',
'some love two','l lo,ie one',' 'That b You'
);pdntf ( t96d %d', sizeof ( mess ), sizeof ( mess I1l ) ) ;
)
Outpu,
176 Understanding Pointers InC
82
Explanation
messl J has been declared as an array of pointers to striogs.This signilies that the array messl ] stores the startingaddresses of the four strings initialiied in the program.mers[0] has the sta ing addess of the string "Some loveone", messll] the starting addrcss of the second shing',Somelove two" and so on. As each address is 2 bytes long, fourbase addresses need 8 bytes, herce thc array messl I is 8 byteslong,
The sizeof( ) operator gives the size of the datatype that issupplied as its argument. Thflpfore, sizeof ( mes3 ) is rcporteda8 8.
mess[l], the filst element of the array of pointers storcs anaddreBs, whioh is invariably 2 byte6 long. Therefore prirtf( )reports slzeof( me$lll ) as 2.
char names[3][20] ;
inti;for(i=0;i<=2;i++)t
pdntf ('\nENTER MIrrE:' ) ;scanf ( '%s', narnesm ) ;printf ( 'You entercd 96s', namesli] ) ;
))
Outpttt
ENTER NAME: Par4You entered Parag
Chapler 3: Pointers and Strings 177
ENTER NAME: VeenuYou enteed VeenuENTER NAME: JainaYou enbred Jaina
Erplanation
namer[3][20] has been declarpd as a two-dimensional arrayof characters. We can think of it as an array of 3 elements,each element-itselfbeing an array of 20 charaoteN,
Let the base address of the 2-D alray, i.e. names be 400 I . Inthe scsnf( ) and pritrtf( ) statements, !smer[] refers to theaddress of the I'h string in the aray. mmeslol refers to thezeroth element of the 2-D array, or the base address of thestring ofcharacters Etarting from 4001. llrmesll] deflotes theaddress of the fiIst element ofth€ 2-D artay, which is 20 bytesahead, i.€.4021, and so on.
Assued that trrm€slil stands for the base address of the I'hshing, we ploceed to see what actually is going on in thisprogram.
The fiIst time though the for loop, when you arc prompted"ENTER NAME:", say you entered 'Parag'. The scanf( )accepts this name and stores it at the address given bynamesl0l. The priDtf( ) iflmediately reads Aom lhe sameaddress name[0], and pdnts the rEme starting at this addresson to the screen. This is repeated by incrernenting the value ofi each time through the loop. Who i is incrcmerted for thethird time. thc process is lerminated.
(22) main0(
(?3) main( ){
char names[5][20] = {'Roshni',
178 [Jnderstanding Pointers In C Chapter 3: Pointers and. Strings 179
'Manish',"Mona',"Baiju",
"Ritu"
);intiichar 't jt = names[3] ;
namespl = names[4) i
namBs[4] = t;for(i=0ii<=4ii++)
pdntf (ln%s', nameslil) i
)
Output
Enor messsgei Lvalue requiEd in function main
ExplanatioL
Apparently, what the program atiempts !o do i8 interchange
the addresses stored in mmes[3] atrd DrDe"t[4] using atr
auxiliary variable t. SoundE straight fon*'ad, but is essertially
against the v€ry concept of how the C compiler d€a-ls wilhstrinss. The compiler keeps Fack of any string by
remJmbering only tl,e base address of the string. So it has its
reservations when it comes to chalgilg this infomation, as itanticiDates that there would be no one to blame bui itselfonce
this iiformation is waylaid and we dernand an aocess to the
string laterl And this is what i$ beitrg attempted itr the
statement namesl3l = names[4]. Here we are trying to change
the base address storcd ilr namerl3l As said eadier, this willnot be allowed. Thus the starting address of a stsing is afl
indelible entity, in no way aa Lvalue, which is a value that
can change, Hence lhe error message.
char messlBl[3oJ = {' "Don\walk in frontofme ...',"l may nol follow;','Don't walk behind me,.,",'l may not lead ;",'Just walk beside me.,.','And be my ftiend."
);prinlf( \o/oc %c', *( messl2l+ I ), '('( mess + 2 )+ I ) ) ;
)
Output
kk
Explasaliort
The two-dimensional array comprises of one-dimensionalarays, each of which is 30 characters loflg. We know,messl2l[9] refe6 to the th element ofthe 2 l-D anay.
Recall Orat melsl2l would give the base address ofthe secordstring. If this addre3s turns out to be 4001, then the expressionmcsr[2] + 9 would become ( 4001 + 9 ), which would give theaddress of the ninth charactq from the ad&ess 4001. Thisaddress happens to be the address ofthe letter'k' in the striog'Doa't walk behind me". Hence this letter 'k' can be accessedby the expression *( mess[2] + 9 ). But we aheady know thatwhenever we use the notation mess[2], it is intemallyconverted to *( mess + 2 ) by the compiler. Therefore*( m€ssl2l + 9 ) can also be expressed as *(*( mess + 2 ) + 9).
Thus, mess[2][9], *( mess[2] +9)and*(*(mess+2 )+9)are one and the same, i.e. the 96 element of the 2nd string in
(24) main( ){
IB]
(1)
180 Undersland@ Pointers In C
the aday. The same array element can thus be accessed in any
of these three ways. The pritrtf( ) on execution outpnts the
letter 'k' twioe.
Answer the folloving:
Is the following pogram colrect? <Yes,No>
main0
tchar*slr1 = 'United';char
*str2 = "Fmnt'i
char'str3 i
str3 = strcat (str1, str2 ) ;
p ntf ('\n%s', str3 )i)
Explanation
No, since what is plgsent in memory beyond "United" is notknown and we are attaching "Fro[t" at the end of "United",thereby overwriting something, which is an unsafe thing todo.
How would you improve the code in (2) above?
Explahation
main( )
{char str'1 [15] = 'United" ;
char'st2 ='Front';char *str3
;
str3 = strcat (str1, st2 ) i
pdntf ( lno/os', str3 ) ;
)
Chapter 3: Pointers and Strings t81
(3) In the followi4g code which function would get called, theuser-defined strcpy( ) or the one in the standard library?
#include <sting.h>
main0
tchar strl[]= 'Keep India Beauliful... emigratel" icharsl2[40]jslrcpy ( sl4, strl ) ;
prinf('\n%s", st, )i)
sircpy ( char't, char's ){
while ( 's ){
t++;
)'t=10';
)
Erplanatiorl
User-defined strcpy( )
(4) Can you compaot the code of$trcpy( ) given in (3) above intoone line?
Explanatiol
strcpy ( char 1, char ts )
{vrhile(*t++='s++1;
(2)
182 Unders tanding Pointers In C Chapter 3: Pointers. and Strings 183
'(5)
)
How would you futd the lenglh of each sting in the program
[A](9) above?
Explonqlion
maln0(
char 5r[ ] = {'Frcgs', 'Do', 'Nof, 'DiE.', 5hefr, "Cmatl' } ;
lntl;
tor(l= ();i<= 5; l++ )pdntf ( 1n%s %d', 6tr[, sfi€n ( $nl ) ) ;
)
Would the foltowing code oompilc sucoessfully?
maln( )
{printf ('%c', 7l'Sundaram" I ) ;
)
Explanaliofl
Yes. It would print 'm' of "Suudaram".
What is the diff€rence in the followiry declarations?
ch8r*p = 'Sanuel" ;
charall= "Samuel' ;
Etqlaaation
Here a is all aray big enough to hold the message aod the '\0'following the message. Individual charaotgrs *ithio the array
oao be changcd but the ad&ess of the array would rernainsame.
Ou Oe other hand, p is a poitrtEr, itritializcd to point io a stringcoNtant. The pohter p ltray be modified to point to anothershin& but if you sttempt to modiry the sting at which p ispoitrting the Gsult is undefined.
(8) While handling a stsing do we always have to prccess itolDtaotgr by character or ther€ cxisb a m€thod to processlthaentir€ sting a! one udt.
Eqiluatioa
A 8thg car bc proc€8sed ody o! 8basis.(6)
0)
184 Understanding Pointers Jn C
Exercise
IAI Attempt the following:
(l) Wdte a furction xstrchr( ) which scans a string frombeginning to end in search of a character. If the character isfound it should retum a pointer to the first occurrence of thegiyerr character in the stillg. If the given characler is notfoirnd in the string, the fiDction $hould retum a NULL. Theprototypc ofthe function would be:
char ' )6trchr ( char'sting, char ch ) :
(2) Write a function xstrsar( ) that will scan a stsing for theooculronce of a given sub-string. The prototype of thefurlctiofl ]r,ould be:
char ' xstrctr ( char 'stdngl , char'sting2 ) ;
The funotion should retum a pointet to the elemert in strltrglwhere strlng2 begins. IfltrlEg2 doesn't occur in stritrgl lhenxstrstr( ) should rEhrm a NULL.
For example, ifetrlngl is nsomewhcre over fte rainbow", and.trltrg2 is "over" then rrtrst( ) should retum address of 'o'in rtrlDgl,
(3) Suppose 7 names are siorEd in an aray of pointers mmer[ |as shown below:
char 'names[ ] = ('Sanbsh','Amol','Sanh6h Jah','KhlDe-,'Rahuf,'Amollumai,'Hemanf
);
, 185
Write a Eogram to arange these ,rames in llphabetical order.
Wdte a progmm to compress my given string such that themultiple blanks prcsent irl it arc eliminated. Store thecompEssed message io anot er sting. Also write adecoinpressaat program to ggt bock the odginal string with allits spaces restored.
The uncompressed string can be:
'lmpeidPalace. Rome. Attenlion Julius Caesar. oear Caesar, u/ehave the clariication you EquesM. Details lo follow by courier.Mean$rhile stay clearol Brutus.'
Write a program to encode any given string such that it g€tsconvet€d into an unrecognizable form. Also write a decodefunction to get back thc original string, Try to make theencr,?tion soheme as difficult to brcak as possible.
What will be the output ofthe following programs:
main( )
{char stingl J = 'oddLengfiStting' 'char'ptr1 = sfing, 'pM = sting + sizeof (string )- 1.inti:
for(i=0;ptrl l= pf2;i* )
{
)pdnf( '%d', i) ;
)
main( ){
shtic char slrl [ ] = 'Good' ;
(4)
(s)
IBI
(1)
++ptrl ;
-N2;
(2)
Chapter 3: Poi ters and Strings 187
(3)
static char su2[20] ;
slatic char sr3Pol = 'Daf '
intl;
| = stcmp ( stcal ( st3, $rpy ( st4, sH ) ), stcat (
sr3,'Sood'));pdntf(%d',1);
I
main0{
char slr Il = 'Way oftDubl€ Is out hDugh it' ;
inti;
br(i' 0;i<.3 ii++ )pdnf('Ybc','( st + i) ) i
for(i=0;i<=3;i++)Pdntf ('%o','(sf + 18 + i ) ) i
for(i=0;l<=13;i+t)printf ('96c','(sf +4 + I ) ) ;
for{i=0;l<=9:i++)p ntf ('96c','( sr+ 22 + i ) ) ;
)
main( )
{chars[]='Caof''char ttl = 'is Phil6ophy lib' 'char u[40] ;
char'ss I s, rt = t. ruu
= u ;
while ( .ss ll 'lt )
twhile ( 'ss ){
if( ('uu++ ='ss++ 1 == " ;bBak;
)
. while ( 'tt ){
if(('uu++='tt++)==")brcak;
))'uu=\0;puts(u);
)
main( )
{char a[2][2][25] = {
{'Jack and Jill',"Went up the hill"
),(
'Jack felldown","And bloke hh crown'
))i
pdntf ( 'b%s %s %s %s', &atollollgl, &al0l[1][12],&a[1]l0ll10l, &allll1lllal ) ;
)(4)
An e4)erl C Programtuel is o e who avoids all elrols except thoserelaled with poi ters.
Qointers anf S tractures
ile handling real world data, we usually deal with a
colleciion of itrts, chars and floats rather than isolatedentities. For example, an gntity we call a 'book' is a
collection of things like a title, an author, a call number, a
publisher, number ofpages, date of publication, price, etc. As youcan see, all this data is dissimilar; authoi is a string, prioe is a lloat,whereas number. of page$ is an int. For dealing with such
c.olleotions, C provides a data type oalled 'structure'. A structuregathers together different atoms of infomation that folm a givenedity.
Look at rhe following progEm that combines dissimila! dara typesinlo an entity called shucture.
I Program 48 '/main( ){
struct munt
190 Understanding Pointers In C Chapter 4: Pointers and Straclures 191
int no i
char acc_namel15] ;
lioat bal i
);struct account a1, a2, a3 i
printf ( "\nEnter accounl nos,, names, and balances\n');scanf ( 'olod yos %f', &1.n0, a1,acc-name, &a1.bal)
. scanf ( "%d %s %f', &a2.no, a2.acc_name, &a2,bal )scanf ("%d %s %fl, &a3.no, a3.acc_name, &a3.bal)
printf("\nolod o/os 0/0f', a1,no, a1.acc_name, al.bal);printf('\no/od o/os %f', a2.no, a2,a6c_name, a2.bal);pintf('\n%d %s %f', a3,no, a3.acc_name, a3,bal);
)
Now a few tips about the programl
(a) The declaration at the beginning of the program combinesdissimilar data tlpes into a single entity call€d structaccount. Here struct is a ke),\trord, account is th€ stucturename, and the dissimila! data types are stucture elements.
(b) al, a2 and 13 are structure variables of the q?e structaccoutrt.
(c) The structwe elements arc acoessed using a '.' operator. So torefer no we use tl,no and to refer to acc tr&me we useal.rcc_name. Before lhe dol there must alwayi be a structurevariable and after the dot there must always be a shucturcelement.
(d) Since a1.!cc_name is a string, its base addrcs$ can beobtained just by mentioning al.acc_name. Hence the .addrEss
of operator & has been dropped while receiving the accountname in scanf( ).
(e) The shucture elements are always arranged in contiguousmemory locations. This arangemenl is shown in thefollowing figure.
al.no a1,acc name al.bal
375 lsameer\0 11234.55
.,l00l 4003 4018
Figut€ 4. I StructurE elements in memory
An Array of Structures
In the above example ifwe were to stole data of 100 accounts, wewould be rcquired to use 100 differeflt shucture variables ftom alto 4100, which is definit€ly not very convenient, A better approachwould be to use an aEay of stuctures. The arangement of theatray of strucrures in memory is shown in the following figure.
alo].rc a[o].bal alll.no alll.bal a[g].no a[g].bal.
,1000 4002 4006 4008 4054 4056
007 2000.55 134 4892.30 t22 6432.90
Figwe 4.2 Aray of structures in memory
Now let us write a Fogram, which puts the array of struotules towork.
f ftoglam 49 ./
main( )(
slruc{ account
{
192 Understanding Pointers In C
int no ;
float bal ;
);struct account a[10i;int i, acc i
float balance;
for(i = 0 ; i<= 9; i++ ){
prinlf("\nEnter account no. and balance;, );scanf('%d %f', &ac6, &balance )jalil.no = acc : alij.bal= batance;printf ("yod %f', alil.no, alil.bat);
)1
As you can see the structure elements are still accessed using the'.' opelator, and the array elements using thg usual subscriptnotation
More about Structures
Let us now explore the intricaoies of structures with a view ofprogramming convefl ience.
(a) The declaration of shucture t pe and the structute variablecan be combined in one statement. For example,
struct player(
char name[2o]jint age;
);struct player pl = {'Nick Yates', 30 } ;
is same as
Chapter 4: Pointers and Structures 193
slruct player
{char name[2o] ;
int age ;
) pt = ( 'Nick Yates', 30 ) ;
or even...
struct
{char rEme[2o] ;
int age ;
)p1 = ( "Nick Yates", 30 );
(b) The value ofone structure variable can be assigned to anotherstructure variable of lhe same type using the assignmentoperator. It is not necessary to copy the struoture elementspiece-meal. For example,
slrucl player
{char name[2o] ;
int age ;
);stuct player p2, pl = { "Nick Yates', 30 } i
p2=pli
(c) One structure can be nested within another strlrcture as shownbelow.
slruct part
{char type ;
int qty ;
);struct vehicle
{char marutl2o] ;
194 Understanding Pointers In C Chapter 4: Pointers and Structures 195
struct pad bolt i
);struct vehicle v;v,bolt.qty = 300;
(d) Like an ordinary variable, a structute variable can also b€passed to a function. We may either pass individual struch[eelements or the entire structure at one go. If aeed be we canalso pa8s addresscs of struoture el€ments or address of astluotu€ variable as shown below.
stuot Player(
charnamt2ol;int age i
);strucl player p1 = {'Nick Yatos , 30 } ;
display ( pl.nam, p1,age ) ; I pEsing indivirud 6l6monb'/show ( pl ) j I passing sruduB valiabla'/d ( pl,nam, &pl.age ) ; f psssing addBss€s.of stuctuIo dem€nb'/print ( &p 1 ) j I passing addr€ss of shtGtrs yadablo '/
Structure Pointers -The way we can have a pointer poitltiog to atr lut, or a Poht€f,poilti[g to a char, similarly we oatr have a pointsr pointhg to aitruct" Such pointers ale knowtr as 'stuchlre pohters'. L€t us lookat a program, whioh demonstr.tes the usage oflhese pointers-
f Program 50 '/main0
{struct book "/t
charname[2s];char autDr[25] ;
inl callno j
Isfuct @ok b!.= { "Let us C", YPK", 101 } :
-${tq!]!ilIpr= &bl ; /prin ( '96s yos o6dln', bl .name, bl .author, bl .callno ) i
pfnf ( 16s %s o/odb', ptr -> name, ptr -> author, ptr -> callno ) i
)
The first prlrtf( ) is as usual. The second prlntf( ) however ispeculiar. We ca['t use ptr.nrme or ptr.c.llno because ptr i6 not astruch[e variable but a point€r to a structue, and the dot operatorrequir€s a stucturc variable on its left, ln such cases C proyid€s anoperator ->, aalled an arrow operator to refer to the shuotureeleErents. Remembsl that on the left had sidc of the '.' shuotur€opsrator, theE mugt always b€ a stucture variablc, whereas on theleft hand side ofthe -> operator thele must always be . pointer to astsucturc. The arrangement of the structue variable and pointer tost uctuI€ in memory is showa in the ffgure given below.
Figure 4.3
CaD we trot pass the address ofa strucfure variable to a function?We carl. The following program demonstrates this.
bl.mmc bl.author bl.callno
IrtUsC I YPK ll014ml 4051
ptr
I- 4oor I8000
196 Understanding Pointers In CChapter 4: Pointers and Structures 197
stuci af Program 51
-/ {
f Passing addrcss ofa structure vadable'/ siruct bstruct book {{ int i;
char namel2s]i ioal f;charautho(2s]; char ch ;
intcallno ; ]x;); struct c
tmainO inl j;( float g;
void display (strucl book * ) charch;
struct book bl = { "Let us C", "YPK', 101 }; }y;display (&b1 )i |z:
)Suppose we make a call to a function as shorm bolou,:
void display ( strucl book 'b ) f b is a pointer to a structure '/{ run ( &.y);
pdntf ( 1n%s\n%s\n%d", b->name, b->auhor, blcallno ) ;
) In the funotion fun( ) call we access the elements of structure bthrcugh the address ofz.y? We can. For this we need to first find
And here is the output. , out lhe ofhet ofJ. Using this offset we catr fiDd out ad&pss wheler begins io memory. Once we get this address we oan have an
Let us C access to elements i, f and ch. This is shown in the followingYPK101 pro8ram'
f prcgram 52 ./Again, note that, to access the structure elements Dsi[g pointer to a druct aslructure we have lo use the L>' operator. Also. the shucture {struct book should be declared outside main( ) such that this data $ruct bt)?e is available to display( ) while declaring the variable b as a {pointer to the structure. int i ;
lloat f;
Offsets of Structure Elements )r,.n,t.n'Consider the following stluctule:
198 Und*standing Pointers In C
struct c
tinti;float g ;
chai ch j
)Yl);
main0(
int -p
i
struct a z;
clrsc( ) :
fun(&z,y):pdntf ( 'h%d %t %c', z.x.i, z.x.t, z.x.ch ) ;
getch( ) ;
)
fun(sructc'p)(
int otfset ;
structb*addEss;
otEst = ( ch r ) & ( ( stuot c' ) ( & ( ( druct a' ) 0 ) -> y ) t j )
- (char') ( ( sfructa') 0 );addrcss = ( struct b ' X ( char' ) & ( p -> j ) - ohet ) ;
addr€ss -> i= 400 ;
address -> f = 3.i4 ;address "> ch r'd :
)
In the above program shucturcs b and c having members i, f, ch
and j, g, ch are nested within the stuctwe r with stnrcture
variables x and y of, stluotule b and c respe.tively. Next we have
called the fudctior fun( ) with the base address of drc stucturevariable y. Now &om fun( ), we wish to access the members of
Chapter 4: Pointers and Structures 199
strirctur€ mriable t, But sinoe fu( ) has been passed a pointer tostructue c, we do trot have direct acoess to elements of x. Thesolution is to calculate the offset of the fiIst m€mber of y, in ourcase, j. This has been achieved through the staternefl:
ofhet = ( char ' ) & (( struct c') (& ((slruct a ') O )-> y )-> j)(char-) ( ( slructa' ) 0 ) ;
Figue 4.4
Let us understand this statement part by pad,
In the expression ( ( rtruct r * ) 0 ), 0 is being t)?€gasted intopointer to rtruct .. This explessiorl is pretending that there is avrriable of t)?e slruct r at address 0. The expression & ( ( ( structa * ) 0 ) -> y ) gives the addr€ss of sttuctur€ variable y. But this isaot the base address ofthe shuoture c. Hence we haye typecasM itusing struct c *. Using lhis address we can access the member J ofthe slructule vadable y. Finally, aft€r taking the address ofmember j, we have t)?ecasted it using char * to make thesubuaction po$sible. The statement to the dght of the '-' operator isstraighdorward. On subtraotiotL we get the offset of member j ofstructure variable y. Now using offset the base address iscalculated thrcugh the following statement.
address = (struct b') ( ( char. )& (p -> j )- offset ) ;
200 Understanding Pointers In C
In the above statement & ( p > j ) gives the addrcss of member jof structue variable y. Subtracthg offse1 fiorn this yields theaddross of stuotule variable x. Using this address, lve have stoEdthe values in the member variables i, f and ch. Back inlo main( ),we have printed these values using prtntf( ).
Linked Lists
Linked Iist is a vbry common data structute often used to storcsimilar data in memory, While the elements of an array occupycontiguous memory looations, those of a linked list are notconshained to be stored in adjacent locations. The individualelements are siored "somewhere" ill memory, rather like a familydispeNed, but still bound together, The order of the elements ismaintailed by explicit lirks between them. For instance, the marksobtained by differeilt students car be stored in a linked tist as
shown in Figure 4.5.
Data Nctt
Figue 4.5
Observe that the linked list is a collection of elements callednodes, eaoh of whioh stores two items of infomation-an eleme(ofthe list and a link. A link is a poifter or an addrcss that indicatesexplicitly the location of the node containing the successot of lhelist element. In Figue 4.5, the arows rcpresent the links. TheData pait of each oode cotrsists of the marks obtained by a student
Chapter 4: Pointers and Structures 201
and the Next pad is a poi[ter to the next node. The NULL in theIast node indicates that this is the last [ode in the list.
There are several operations that we can think of performing onlinked lists. The following pro$am shows how to build a linkedIist by adding new nodes at the beginning, at the end or in themiddle of the linked list. It also contains a funotion disphy( )which displays all the nodes present in the linked list and afunction deleae( ) which can delere any node in lhe linked list. cothrough the program carefully, a step at a time.
f Program 53 'if Prcgram lo maintain a linked list'/#include 'alloc.h"
f $ructure containing a data part and link pad */
struct node(
int data ;
slruct node 'link i
stuct node *p ;
p = NULL ; f empty linked list:i
pdnf('hNo. of elements ln the Linked List: %d", count ( p ) ) ;
append(&p,1);append(&p,2);append(&p,3):append(&p,4);append ( &p, 17 ) ;
cllsc( ) ;
display ( p );
addalbeg (&p, 999 ) ;
)lmain0
{
202 Understanding Pointers In C
addalbeg ( &p, 888
addatbeg ( &p, 777
display (p ) ;
addaftor(p,7,0 )iaddafter(p,2, 1);addafter ( p, 1, 99 )
dlsplay(p);printf ( '\nNo. of Elements in th€ Linksd List =
y!d', ount ( p ) ) ;
delets ( &p, 888 ) ;
deletB ( &p, 'l ) i
delete (&p, 10 );
display(p)ipdntf('\nNo. olelements in the linked llst= %d', count ( p) );
lif ddds a node al'ttre snd ofe llnked lisl'1app€nd ( struct node
*q, lnt num )(
struct node *temp, 'r;temP =
-q "
if ( -q
== pg;-117',t*",st is empty, cleate first node'/
(,lemp = malloc ( sizeof ( struct node ) ) ;
lemp "> data = num '
temp>link=NULL'
' -q=temp;
Ielse
'(temp:.'q ;
I go to last node'i
Chapter 4: Pointer.s and Structures 203
while (temp -> link != NULL )temp = 1sO -, 1;n* ,
f add node at the end 'ir= malloc ( sizeof( struct node )) ;
a) data = num ;
r) link = NULL ;
lemp>link=r',})
f adds a new node at the beginning of the llnksd list '/addalbeg ( sfuct node 'q, int num )
{slrucl node lemp ;
I add new node '/temp = malloc( sizeof ( structnode ) ) ;
bmp ) dala - num '
temp>link='q'q = temp ;
)
f adds a new node afrer the specilied number of nodes '/addafier ( slruct node 'q, inl loc, int num )
{stuct node Iemp, 1 ;
inti;
temp=q;f skip lo desked portion'/tor ( i= 0; i< loc ; i+t )
{lemP = t6,r, -, ,'n* '
f if end of linked list is encountercd '/if ( temP == ;t1911 ;
204 Understanding Pointers In C Chapter 4: Pointers and Structures 205
{ retum c;pdntf ( tl]herc are less than %d elements in list', loc ) ; )relum ;
I f debtes lhe speciied node from the linked list '/) delete (strucl node "q, inl num )
{f insert new node'/ stuct node .old,
'temp ;
r = malloc ( sizeof ( stucl node ) ) ;
rldata=num; temp=.q;r-> link = temp .> link;temp -> link = r; while (temp l= NULL )
){if (temp -> data == num )
/* displays the contenb of he lhked list -/
{display (structnode'q ) I if node lo be deleted is lhe fEt node in the linked list'/( if (temP =='q 1printf("\n")i (
'q = temp -> link i
/' traverse the entire linked list'/ f frEe the memory occupied by the node 'iwhile (q l= NULI) free (temp ) i
{ retum;p ntf ( "%d ', q -> data ) ; )q=q->tink;
I f deleles the intemediate nodes in the linked list./) else
{/'counts the numberot nodes prBsent in the linked list'/ old -> link = temp -> link ;
count ( strudt node 'q ) nee ( lemp ) j
{ Etum ;
intc = 0; ))
/' traverEe the entirc linked list'/while ( q != NULL ) f fave$e the linked list till the last node is reached '/{ else
q=q->link; {c++ ; old = temp ; f oH points to the prcvious node */
) temp =le" -' "n* '
/'go b the next node */
)
206 Underslanding Pointers In C Chapter 4: Pointers and Structures 207
)
p ntf ('\nElement o/od notfound', num );)
To begin with we have defined a structure for a node. It co ains a
data palt and a link part. The vaiiable p has been declared as
poiflter to a node, We have used this pointer as pointer to lhe firstnode in the linked list. No matter how many nodes get added to the
linked list, p wquld contiflue to pointer to the first node in the listWhen no node has been added to the list, p has been set to NULLto indicate that the list is emptY.
The append( ) function has to deal with two sihrations:
(a) The node is being added to an empty list.(b) The node is being added at the end ofar existing list.
In the first case, the condition
ll(-q == xU111
gets satisfied. Hence, space is allocaled for the node using
malloc( ). Data ard the link part of this trode a.e set up using the
statemeflts:
temp -> data = num '
temp -> link = NULL
Lastly p is made to point to this node, since the fiIst node has been
added to the list and p must always point to the frIst node. Notethat *q is nothing but equal to P.
In the other case, when the linked list is trot ernpty, the condition
if (-q == xg11- 1
would fail, since *q (i.e. p is non-NULL). Now temp is made topoint to the first node in the list through the statement
temp = 'q ;
Then usitrg temp we have traversed tbrough the entire linked listusitrg the stat€metrts:
while ( temp ) lini != NULL )temo = tsm, -> link j
The position of the pointers before and after traversing the linkedlist is shown in Figure 4.6
Figue 4.6
Each time through the loop the statement iemp = temp -> linkmakes temp point to the next node in the list. When temp reachesthe last node the condition temp -> link !: NULL would fail.Once outside the loop we allocate space for the rew node throughthe statement
p telnp
t
IEnode beingadded
208 Understanding Pointers In C
r= malloc (sizeof{struct node ));
..Onoe the spaoe has boen allocated for the new node its data part isstuffGd \rith num and the link part with NtlLL. Note that this nodeis now going to be the last Node in the list.
A11 that now remains to be done is connecting the previous lastnode with the new last node. The previous last node is beingpointed to by temp aod the new last node is being pointed to by r.They are conn€cted through the statement
temp "> link = r I
this link gets established
There is often a confusion as to how the statement temp = temp ->link makes temp point to the next node in the list. Let usunderctand this with the help of an example, Suppose in a linkedlist containing 4 nodes temp is pointing at the first node. This isshown ill Figure 4.7.
temp
EC I,T.*l f,-f,ool ET,;] I;F*{150 910
Figure 4.7
Imtead of shov/ing the links to the next node I have shown theaddresses of the next Ilode in the link part of each node.
When we execute the statement
temp = tgmp -> link
the right hand side lelds 400. This address is now stored in temp.As a result, temp starts poinling to the nod€ present at address400. In effeot the statement has shifted t€mp so that it has startedpointing to the next node in the lisr.
Let us now undeNtand th. addatbeg( ) functioD. Suppose there arealready 5 nodes in the list and we wish to add a new node at thebeginning of rhis existing linked list. This situation is show inFigure 4.8.
Figure 4.8
For adding a new node at the beginning, frrstly space is allocatedfor this node and <lata is stored in it through the statement
temp -> data = num
Now we need lo make ihe titrk pan of this node point lo theexisting first Itode. This has be€lt achieved through the statement
rEBefore Addition
After Addition
210 Understanding Pointers In C Chapter 4: Pointers and Strucnres 211
temp -> link:1 '
Lastly, this now node must be made the fiI5t node in Ore list. Thi$has been attained tkough the stateme
'q = temp ;
The addafter( ) function pemits us to add a new node after a
specilied number ofnode in the linked list.
To b€gin with, through a loop we skip the desired aumber of nodes
after which a new node is to be added. supDose w€ wish to add a
new node oontaining data as 99 after the 3d node in the list. Thepositiofl ofpointers once the control rcaches outsidc the for loop isshown in the Figue 4.10(a), Now space is allooated for lhe nodc tobe inserted and 99 is stored in the dats part of it. All that rernains
to b€ dorc is leadjustment of link6 such that 99 go€s ir bctweeo 3and 4. This is achieved through the statements
r.> link = t€mp -> link;temp -> link = r i
The filst statement mskes link part ofnode contaiuing 99 to pointto the node containing 4. The second staternent ensues that thelillk part ofnode containing 3 points to the node containing 99. Onexecution of the sccond statement the earlier link between 3 and 4is severed. So now 3 no longer points to 4, it points to 99.
The disptay( ) and count( ) functions are straiSht forward. I leavethem for you to understand.
'Ilat brings us to the last functio! in the prcgram i.e. dclete( ). Iothis function through the while loop, we have traveNed thrcughthe entirc linked list, checking at each node, whether it is the nodeto be deleted. If so, we have checked if the rode being deleted isthe first node in the linked list. Ifit is so,,we have simply shifted p
(which is same as 'q) to the ext node arld then deleted the earliernode.
If the node io be deleted is atr i ermediate node, then rhe posirionofvafious pointers atrd links before and after the deletion is shownin Figue 4.9.
Figure 4.9
The rddafter( ) fihction pemits us to add a new node after aspecified number ofnode in the linked lisr.
To begin wirh, through a loop we skip the desircd number ofnodesafter which a new nod6 is to be added. Suppose we wish to add anew node containing data as 99 after the 3d node in the list. The
nodc to ba dcleted - 99
Beforc Del€tton
temp
J
i _eJ_l _ _ -l+ mt noa"
After Deledongeh deleted
212 Understanding Pohtters In C
position ofpointeis once the contol reaches outside the for loop isshown in the Figure 4. I 0(a).
Fisue 4.10
A oommon and a wrcng implession that beginners carry is that alinked list is used only for stodng integers. However, a linked listcan virtually be used for storing any similar data. For example,there can exlst a linked list of floats, a linked list of names, or evena linked list ofrecords, where each record contains name, age andsalary of an employee. These linked lists are shown in thefollor/ing figure.
Chapter 4: Pointers and Structures 2t3
Figure 4.11
Now that we have understood how a linked list can be maintained
how about ensuring that every element added to the linked list gets
inserted at suoh a place that the liDked list is always maintained iD
ascending order? Here it is...
f kogram 54'lf Program for adding and deleting nodes from an ascending order
linked list '/#inclde 'alloc.h'
i__-Ll*l I
(.) Bcfore Inrertion
fb) Alter Insertion
LiDk€d list of floats
Linked list ofnames
LiDled list of Structrcs / Records
N st n.is for NULL
214 Understanding Pointerc In C
stucl node(
inl dab ;
struot rbd€ link ;
);
main( )(,- sfud node'p;
p , 11911 ; f smE{y ttnk€d tbt r/
Edd(&p,5);add(&p,1);add(&p,6)iadd(&p,4)iadd(4p,7);
Chapter 4: Pointers and Slructures 'rt<
f if fist is eflpty or if new nods is lo be inserGd b€forche fEl node Yit('q == NUIL ll('c ) -> dala > num ){
'q =r;('q)>link=bmp;
)ebo
,(f. hat eE6 fie enliE linlsd llst h s€arch tle po€lton b lns€n
tp rcw node '/while ( unp l= NULL ){
il ( bmp .> data <= num &E ( lomp .> llnk .> data > num ll
{ bmp.> ltnk = NULL ))
r .> llnk = tsmp ) link .
blrptllnl=r'lB M;
)bmP = 51, -, ,nl( , f go b fi6 mxt node '/
))
)
f dipbys fi6 conbnE ot ho llnkod lbt ./dbday ( stnd nodo 'q ){
pnnf ( 1D') ;
f ha\€6e tle BnliIB linfed lM'/while ( q != NULL ){
Ptinf('9{d',q}dab);q=q>link;
))
. clrsc( ) idlsplay(p);ptlntf('hNo. ot Blanr€nb h Llnkod Ust = 96d', coufl[ ( p) );
d.let€(4p,7)dslsts(&p,4)dsloto(&p,5)dsl6b ( &p, 9 )
display(p);printt ( tNo. of sl€monts in Unked Ust = 96d', munt ( P ) ) ;
)
f adds node b an ascending odei llnked lisi '/add ( slruct node *q, lnt num )
{struct node 1, 'temP = 'q ;
r = malbc ( sizeol ( stl$t nodE ).) ;r -> dala = num ;
234 Understanding Pointers In C
f stucture reprBsenling a nod8 of lhe doubly linked list '/sIuct dnode
{struct dnode 'prev jlnt dala ;
stucl dnodB ' nsxt ;
);
main0
{struct dnods 'p i
P = NULL
d_append
d_append
clrsc( ) j
d-display(p);plintf ( lnNo. of elemenb in the DLL = %dvt', d_count ( p ) ) ;
d_addabes (&p, 33 ) j
d*addalb€g ( &p, 55 ) ;
d_display(p);printf ( 'hNo, of elemenls in the DLL = %dvr,, d_ount ( p ) ) ;
d_addafrer ( p, 1, 4000 ) ;
d_addafrer ( p, 2, 9000 ) ;
d-display(p);pdntf ( '\nNo. of Blements in the DLL = %d\n', d-count ( p ) ) ;
d_delete ( &p, 51 ) ;
d_deleb (&p, 21 ) ;
d-disday (p );
I empty doubly linked list'/
&p,11)j&p,21);
Chapter 4: Poinlers and Struch.res 23s
prinf ( "hNo. oI elements in lhe DLL = %d\n', d_ount ( p ) ) ;
)
f adds a new node at the end of the doubly linked list '/d_append ( strucl dnode 's, int num )
{slruct dnode 'r, 'q = 's ;
f if $e linked list h empty '/ir('s == NULL )
{fcreate a new node '/'s = malloc (sizeof ( structdnode ) ) ;
's))prEv=NI,JLL;'s ) .> data = num '
's))next=NULL'
I traveGe the linked list till the last node is Bached '/while ( q -> next l. NULL )
q=q">next;
f add a new node at he end '/r= malloc ( sizeol( siructdnode ) ) ;
r)data=num;r -> next = NLrLL ;
rlprev=q;q->next=ri
)
f adds a new node at the b€gining of the linked list'/d-addatbeg ( stuct dnode *s, int num )
{structdnode.q ;
f c.eate a new node '/
)else(
280
Chapter 5: Pointers and Data Structures .28t
&first 1 )&flsl 2&lirst 3&first 4&lirst, 5&frst 6 )&first 7 )
clIsc( ) ;pdnil('Firstlinked list :' ) ;
display(frst);pdnf ('hNo. ofelements in Linked List: %d' , count (first ))j
&s€cond, 8 ) ;
&second, I ) ;
&se{ond, 3 ) ;
&sec.nd,4 ) i
&second, 5 ) ;
&second, 6 ) ;
&second, 7 ) ;
pdntf ( h\nsecond linked list : " ) ;
display ( s8cond ) ;
printf ('\nNo. of elements in Linked List: %d" , count ( second ) ) i
merge (liM, second, &thid ) ;
prinf('V nThe concatenated list i " ) ;
display ( lhird ) ;
pdntf ("hNo. of elements in Linked List: %d', count (third ) ) j
)
f adds node to an ascending oder linked list'/add ( struct node "q, int num ){
stlct node 'r, lemp = *q
;
havo several data struohues share the salle spaqe, without paying
partioular attention to their relative size at aay time.
The seoond advantage of litrked lists is that they provide flexibilityin allowing the items to be rearanged efficiently. This flexibility isgained at the expense of quiok access to aay aIbitary item in the
list.
Irr this chaptq we would write pro$ams to perfom more
complicated operations on the linked list, We would also find out
ho\l. linked lists catr be used to matltain polynomials and
manipulate them. Let us begin with merging of two linked lists.
addaddaddaddadd
addadd
add
add
add
add
add
addadd
Merging of Linked Lists
Suppose wo havc two linked lists pointed to by two independent
pointas and we wish to merge the two lists into a third list While
iarrying out this merging we wish to cnpure that those elements
which ire common to both the lists occur only once ir the third
list, The plogram !o achieve this is given below. It is assum€d that
within a list all element! ale unique.
f Pmgram 60 '/f PIogEm to merg8 h o llnked llsb, Estlicting lhe common denents b
occur only onc€ '/#lnclude 'alloc,h'
slruct node(
int data ;
suuct node 'link ;
);
main( )
{struct node'llEl 'second, 'tlid ;
irst = second : thitd = NULL ; f empty linked lisb'/
282 Understanding Pointers In C
r = malloc ( sizeof ( slruct node ) ) ;
r-> data = num i
I if list is empty or if new node is to be inserled before the lirst node ./
if( 'q == NULL ll (-q ) -> data > num )(
tq=r;( 'q ) -> link = lemp ;
)else(
f faveBe the enlire linked list to search the position to insefihe new node '/
while (temp l= NULL )
tif (temp.> data < num && (temp -> link -> dah > num ll
temp ) link == NULL ){
r.> link = temp.> link i
temp -> link = r '
retum i
)temP = 1660 -,1,n* fgo b nexl node'/
)
r-> link = NULL;temp -> link = r'
)I
f displays the contents of the linked list '/display ( struct node'q ){
pintf("b') ;
f faverse the entire linked list -/
while (q l= NULL )
t
pdntf ( '%d ', q ) data )q=q_>link;
))
f counts ttle number of nodes present in the linked list '/count ( struct node ' q ){
intc=0;
f traverse lhe entire tinked tht ./while (q != NULL ){
q=q)link;c++ ;
)
Etum c :
)
f me4es he tm linked lists, resld,rting the common elements to occuronly once in fEfnal list '/
merye ( stnrcl nod€'p, slrucl node,q, slruct node -s ){
stuct node 'z ;
z = NULL ;
f if both lisls are empty '/ir(p == NULI &&q == NULL )
relum ;
f tsaveFe Mh linked lists tilllhe e nd. lf end of any one list is Eachedloop is teminated '/
while ( p != NULL &8 q t= NULI ){
f if node being added h the lirst node '/if ( 's == NULL )
284 Undersnnding Pointers In C
's = malloc ( sizeof ( struct node ) ) ;
z='sj
z -> link = malloc (sizeof (struct node ));z: z->.link;
)
if(p->data<qldata)(
z>data=pldataip = p.> llnk i
if(q->data<p">data){
a.16216 = q -> data iq=q_>link;
)else(
if (p -> data == q -> data )(
z -> data = q -> data;p=p->link;q=q->tink;
))
))
f if end of first list has not been rcached '/while (p l= NULL )(
z -> link = malloc ( sizeof ( struct node ) ) ;
Chapter 5: Pointers and. Data Structures 285
z=z->link;z>data=p)data;P=Pllink;
)
f end ot second list has been reached '/while (q != NULL )(
z-> link = malloc (sizeof(struct node )) ;
z=z)link;. -1 6316 = q -> dala ;
q=q->link; .')z-> link = NULL;
)
In this program, as usual, we begin by building a structure toaccommodate the data and link, whioh togeth€! represent a node.We have us€d pointers lirst, Becotrd and thlrd to point to the threelinked lists. Since to begin rvith all the three linked lists are empty,these pointe$ contain NULL. Next, by calling the function rdd( )rcpeatedly two linked lists are built, one being pointed to by lirstand other by the pointer secotrd. Finally, the merge( ) function iscalled to merg6 the two lists into one. This m€rged list is pointedto by tlre poider third. While merging the two lists it is assumedthat the li$ts themselves are in ascending order. While building thetwo lists the add( ) function makes sure that when a node is addedthe elements in tlle lists are maintained in ascending order, Whilemerging the two lists the merge( ) firnctions accounts for thepossibility of any ofthe two lists being empty,
)else
{
)else(
Linked Lists and Polynomials
Pollaomials like 5x4+2xl+7x2+10x-8 can be maitrtained using alinked list. To achieve this each node should consists of threeelements, nahely coefficient, exponent and a link to the next term.While oaiotaining the polyromial it is assumed that the exponent
286 Understand.ing Pointers In C Chapter 5: Pointers and Data Structures 287
ofeach successive telm is less than thal of the previous t€mr. Oncewe build a linked list to rcFesent a pol)aomial we can use suchlists to perfom common polynomial operations like aildition andmultiplioation. The program that can pelform these operations isgiven below.
/' Program 61 */
/* Program to add two polynomials maintained as linked lists */
#include 'alloc, h'
/' structure represenling a node of a linked list, The node can sbe tem ot apolynomial 'i
struct polynode
{lloal coeff i
intexp;struct polynode *link
i
);
void poly-append ( slruct polynode '", float int ) ;
void poly_addltlon { struct polynode ', struct polynode',slructpolynode")i
main( )(
struct polynode *lirt, 'second, 'btal;lntl=0;
firct = semnd = btal = NULL ; f empty linked lists'/
poly-append ( &first,'1.4, 5 ) ;
poly_append (&firct, 1.5, 4 ) ;
poly_append (&irst, 1.7, 2 ) ipoly-append ( &frst, 1,8, '1
) ;poly.append ( &first, 1.9, 0 ) ;
clrsc( ) ;
display_poly(frst);
poly_append ( &second, 1 .5, 6poly_append ( &econd, 2.5, 5poly_append ( &second, -3.5,4poly_append ( &s€col|d, 4.5, 3 )poly_append ( &second, 6.5, 1 )
pdnf( 1n\n' ) ;
display_.loly ( s€cond ) ;
f dEns a dash€d honzontal line '/pdntl( 1,l');uiile ( i++ < 79 )
printf('-')'Pdnf( 1r n');
poly_ddition ( fBt, second, &total ) ;
display_poly (tolal ) ; I displaF the rEsultanl polynomial '/)
f adds a bm to a polynomial '/toid poly_append ( stuc{ polynode'q, float x, int y ){
sfud polynodo lemp ;
bmP ='q '
f cEates a norv node if fie list is eflipty 'iif ( 'q == NuLt 1
{'q = malloc (sizeol( stuctpolynode ) ) ;
bmP='O')ehe{
f traveBe he enlirE linked list'/wltile ( Gmp -> link != NULL )
bmP = tqrp -t,,n* '
328 Understanding Pointers In C
FigurE 5.14 illustates $omc stuctures that are not binary tees. Besuf,e flrat you urderstad why each of theur is not a binary tee asjust defued.
(a) (b)
Figue 5.14
Let us ron, get itscd to some more t€rmitrolory us€d itr associationwith binary tr€€s. IfA is 6re rcot of a binary;€e ana S is til;;iof ils leff or right subtreg 0ren A is said to
-be the fether of B anrt
B is said to be the left or rlght solt ofA. A nodc that has no sons(such as-D, c, E, or I of Figure 5,13) is called a le!f. In geneml1ny mde say ll], is ar atrcestor of node n2 laud ni ie adescendant of nt) if nl is either the fatber of rl2 oi the frther oisome ancestor ofD2. For exatrple, in the tree of Figue 5.13, A isan anoestor ofc. A node tr2 is a left dercctrdrnt ofaode nl ifn2is either the left sotr of trI or a descendaot of the left son of nI. Arlght dercetrdatrt may bc similarly defined. Two nodes arebrothers iftbey are left and right sons oftbe same fathsr.
Although @tural trees grow with their roots in the grouod andtheir leaves
-in the ai!, compute! scientists almost -universally
portray tr€e d4ta structues with the root at the top aad the leaves a:t
Binary Trees
Let us beEin our study of binary trees by discussiag some basiccorcepts and terminology. A simple birtary tiee is shoBn in Figure5.13.
Figure 5.13
A binary tee is a finite set of elcmelts that is either empty or ispa(itiorcd into three disjoint subsets. The first subset cootains asingle elsrnent called the root of the hee. The other two subsetsare themselves binary tEes, called the left and right subtrees ofthe original tree. A lefl or ight subtlee oan be empty. Eaohelement of a binary tree is called a node of tte tlee atrd lhe treeconsists ofnine aodes with A as its root. Its left subtree is rooted atB and its right subhee is moted at C. This is indicated by the twobranches emanating ftom A !o B on the left and to C on the right.I'he absenoe ofa bmnch indicates an empty $ubtree. For example,the leff subtree of the binary tree rooted at C and the dght subtreeof tlle binary tree rooted at E are both empqr. The binary tre€srooted at D, G,E atrdI have empty ght and left subtees.
Yaileu+A K/",ellr/",
ForJ ('proiriU tn(r lit'r rrrlhour n,,inr,:rs i\ rt'c $itl,out t(,odHe nrc.l. rnorc rhan iu.r - norlJrng.r.qurinrrnre rrlth lotnter.tl Ite dcsrre. ro c\flol lh<ir rrnrnen-rc f,.renrtal p,,illef,lrercniPos(r arld l,rnch arrd rhis hook corcr.. rrenrhrng rllar ha-:rn)lhIg ru LI' srrh lo'nrrrs in r .irrrplr. ..,.i-ro rilr,ler.run,ll{.1}. I hLi t'rplcs (r,\!'rcd Jre:
-j Pointcrs flnd Arrays
' Poinlers and Stnrctures
'.- Pointers and dynamic nrenlory Ilocalion-- Pointcrs to FLrncrion\
Pointels and !,ariable argulncnls IistsNerr, far and huge pointers
Pracrjc l usc olpointers
Usine pointers to cxplorc Boor sector. paflition table.Directory slructurc. etc.
Pointers aDd virns like activiticsPointcrs and Doubly linked lists. Circular lists. Binarvlrce{ anJ l h..:rJ<d b,niry lrcc\
P,'rnr(r. lr) ar )orrr dour m<rn) c\lra\. I rnlc rt h.r{ thil Inrtc J( nropr"nrrer. liti ccsr<,. Ilo\e\cr. rl not us.J ptonerl).poinrer{_hclp }ou d,' sornerhrng heroical|r .rupid deaj rhi,b,rck anJ resjst lhat tcmptation.
$€bsite : $arn:bpbonlitre.com