Understanding Pointers in C [3 ed.] 8176563587, 9788176563581


142 29 64MB

English Pages [255]

Report DMCA / Copyright

DOWNLOAD PDF FILE

Recommend Papers

Understanding Pointers in C [3 ed.]
 8176563587, 9788176563581

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

i

Elr rr

lrE ry tsa IE E

ffi

{r,

G6

E@

G' E Y,,^ t-

f"ttti l-.:.

.I'PB PUBLICATIONS

Pointers and Stings, 142 The const Qualifier, 143 Retumirrg eonst Yaluef, 146 Two Dirtensional A|ray ofCharacters, 147 Array ofPoi\rers to Strings, 149 Lirnitario4 ofArray ofPointers to Strings, I 52 Solved Problems, 154 F,xerclse. 184. t

Table of Contents Aclotowledgments Jntrcduc|ion Io Second Edhiot

t- IDtroductio[ To Poitrters,,,,,....,..;...............,.......-.......1 The & and , Operctors, 2 Poifier Explessions, 4 The Jargon of Pointers, 9 char, int andfloat Poihters, 9 Passing Addrcsses to Functiohs, 12 Fuictions Retuming Pointers, 15

tv,' 4. PolnterrandStructures ......,..........------------.,.........189 An Array of gructures, 191 Mole about Structures, 192 Structure Poi ters, I94 Offsers ofstructufe Elemehts, 196

Solyed Problems, 17

Exercise, 30

2.

Pointers atrd

Arrryr

Linked Lists, 200 Stacl$ and Queuet, 220 Doubly Lhked Lisk, 2ii

...

llhat are Arrays, 38

Atay Elernents to a Function. Poihters and Atays, 43 Passing

Solved Prcblens, 243

41

Etercise,270

Pqssing a4 E ttirc Affoy to a Function, 50

5.

TheRealThing,5l Morc Thqn One

Di

ension, 52 Poinlers arrd Tfuo Dimetsional Arrays, Poi tetto sn Atay, 58 Pdssing 2-D Arroy to a Function, 59

Mergirrg dLinked Lists, 280 Li ked Lists and Polynonials, 285 Sotting a Lin*ed List, 297 Circalar Linhed List, 323 Trees, 326

*

Three Dimensiondl Arrays, 62 Passing 3-D Array to a Functiok, 66

Binary

Stiitrgs

vt

Tre*, j28

Traversal

Retuming Aftayfrorn Fuictiot , 69 Relumifig 3-D Aftay from a Function, Array of Poi ters, 82 Dyuhtic Memory Allocation, 84 Solved Problems, 87 Erercise, 130 3. Pointers and Wat are Slrings, 1j3 Stqhdard Library String Funcrions, I38

Pohters rlrd Dats Structurcs ...,......,.,..........,,,,.....,,,...,....279

d a Binary Tree, 33 1

Binary Tree, 336 Threaded Binary Tree, 344 Graphs,356 Solved Problems, i69 Exercise. 389

Deletionlrom

,.....................133

6.

a

PointersMisceIlrtry..,,,.....................................................391 File Poi rets, 391 Pointers to Functions, 394

Preface to Third Edition

typedef with Furrction Potuters, 397 398 srgc and srgv - Arguments to mairt( Poin ers afid Ydriable Nurnber of Argunen s' 399 rcor,lat and huge Poinlers, 40i Which Poi en to Use?, 408 4I Physicol ,4ddrcss to Segne

),

:qsel

The Darcing Dolls, 412 Caps Locked!, 413 How Much Memory Do You

In all walks of life anythiDg can be done better the next lime

around. I realised this more emphatically when I completed lhe third edition oftlds book. Ihus, Ore so-cJlled ,perfect' c'hapters of the second edition had to be redone for more clarity and simplicity.

I

Have?, 415

Exercise,4l7

7. Appllcrdorr of Pohters

'..,....--........................................423

Exploting the Dith 423 Dictioiary, 434 Manoging Database, 439 The Keybod Queue, 459

InJix to Postfa, 462 Evaluation of Postfa Exprcssion, 467

Locatw Duplicote Filelanes, 469 Eoshing

474

i

Function Calls and Stqck. 480 Solved Probtens, V85

tnrex

graphs,

While reading the fust draft ofthis edition I felt that something is 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 chapter on applications of pointers in real-world programming. After all, no amount of theory is useful unless you cun poi it into practice. So the final draft became semifinai since I decided to add this chapter to the book. And now I am presenting you the edition which I feel is complete in all respects, pmying tlat I won't be required to wrire aflother editiol of this book, Any author would testiS/ that writing a new edition is always more palD in the neck than writing a fresh title.

lili I

I

|

For quite some time now I have beeo getting requests fiom readers that the chapter on .pointers and Oata Structures, be made more elaborate and exhaustivg. I have completely overhaule.d this chapter. Now it also includes binary treis ani

493

tt

"-

Poihten ca be tuade to work ifyou frddle ,a,ith them lo g e ough. Ifyou Jiddle with anything long enough you wilt uttimately fiess it

An Introtuctionto Qointrs

f f Tbich featue of C do beginners find most difficulr to understand? The answer is easy: pointers. Other VV v 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 pointeN that mak€s it the excellent language it is.

of

The difficulty begiDners have with pointers has much to do with C'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 to something, or in a certain direction.

Understanding Pointers In C

2

Chapter 1: An Introduction to Pointers

It is difficult to get a grip on poioters just by listening to

We oan print this address through 1Le following program:

programmer's jargon, In our discussion of C pointers, therefore, we will try to avoid this difliculty by explaining them in terms of simple programming concepts. The fi$t thing vi,e want to do is e\plain the rationale ofC's pointer notalion.

/- Program 1 */

main0 {

The& and * Operators

inti=3; printf ( "\nAddress of i= %u^, prlntf('hvalue of i = %u", i)

Consider the declamtion,

&i)

;

)

inti=3;

l'he output

This declaration tells the C oompiler to:

(a) (b) (c)

3

ofthe above program would be:

Addrcss ot i= 6485 Value of i= 3

Reserve space in memory to hold the integer value. Associate the name i with this memory location. Srore the value I ar this location.

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 happens

We may rcpresent i's looation irl the memory by the following lo be 6485 memory map:

i-__}

El--* 6485+

Location Dnme

I-ocation no. (Ad&ess)

other pointer operator avaikble in C is '*'. called 'value at ult ess o erator. It retums the vaiiE stored at a particdlalEddfess. r\, e'value at address' operator is also called an 'indirection' orator.

l,hlene carefully

the output

olthe following programj

/' Program 2 '/

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 a number to be relied upon, because some other time drc computer may ohoose a different location for storing th€ value 3. Ttre impofiant point is, l's address in memory is a number.

nrain0 I

inti=3; printf ( "\nAddress of i = %u', &i) ; printf ( \nvalue ofr = %d-, i) ; printi ("\nvalue of i= %d",.(&i)); )

4

Chapter I : An Introduction to pointers

IJnderstanding Poinlers In C

5

The output ofthe above prog€m would be:

As you can see, i,s value is 3 andj,s value is i,s address.

Addressoli=6485

use j jn a program wilhout dectaring :an'r it. And ". j rs a \arjable. which conlains lhe 8rn.e "l:1^1"]!

Valueofi=3 Value oli = 3

addre., of i, it is-aeilurea-

0r.

Note that pdnting the value of *( &i ) is same as printing the value

lnl 'j

ofi.

'lltis declaralion tells the compiler that I will be used lo store the rddress ofan integer value _ in o*re. *Jro.; poino

Pointer Expressions

;

Ilow do wejustify tlie usage of * in the declaiation,

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

_ iri"g;;

lnt'j;

,t

g:-Py

+.

the meaning of It stands for ,value at address,, 1;d *J I hus,.irt would mean, the value at the addre*

can be collected in a variable by saying,

""","rn"ji,

j=&i; But rcmembcr that J is not an ordinary variable like any other int€ger variable. lt is a variable, which contains the address of another variable (t in this case)

llcre is a program that dcmonshates the relationships we t ccn discussing.

I

Program

3./

maino

it space in mernory' Once again, the following mcmory map would illusts?te the contents of I and J. Since J is a variable the compiler must provide

(

inl i= 3; int 'j ;

j=&i;

E'.-l 6485

3276

pdntt ( '\nAddE$ of i %u', di ) : = printf ('\nAddEss of i %u'. i ): = o/ou', Printf ( '\nAddress ofj = ai) ;

pdntt("\nvalueotj=%d'.

:'

i) pdntf ( 'hvatue of i %d", i: = pdntf ( 'hvalue of j o/od,. .{ &i ) I = ('\nvalueof Printf i = %d'

i

l) "'

Figure 1.2

,o

.

ij,

have

(Jnderstanding Pointers In C

6

The output ofthc above program would be:

AddEssoli=6485 Addressofi=6485 AddEssofl=3276 Value ofl = 6485 Valu6 ofl = 3

Chapter 1 : An Introdaction to pointers

concept of pointer caD be further extended. pointer we know is a vadable, which contairc address of another variaUte, Niw thii variable itself could be another pointer. Thus, we now have a pointer., whicb.contains another pointer.s address. The following example should make this point clear.

f

Prcgram

{ iiqt

thrcugh thc above program caretulln taking hclp of the memory locations of and J shom ea isr. This program summarires everything we have discusscd so far. If you don't understand thc'program's output, or the meoning of ihe *( &l ), re'read the last few pages. oxpregsions &1, &J, rl ard Evcidring wc say about poilters ftom hcr€ onwards will dcpcNd on your understanding ofthcse exprcssions thoroughly.

Wo*

t

Look at the following dcctarations,

lloat 's

;

:

I

and 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 two iacts togethir and say-poiotels are variables that contain since addrcsses ai;;lwaysE;G;mBEiies !way would always co!!Bi!

Hcrc,

rlphr, ch

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 );

lnt'alpha; ohar 'ch

4'l

maino

Valueoli=3 Valu6 of i= 3

The declaration llgat *Ejqes not mean lhat s is going [o cooBln a fl oati-ng-point valqq. value. Similarly, char *ch means that --aterisi-oIa'hoating-point 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

@

7

prinf ( lnhvdus ofj %u', j); = pdnf ( Walus of k r %u', k ); printf ( '\nvalue oti %d', t)j = pdntf( lnvaluo ofi =/od',.(&j))j pdnf (hvalue of = %d", J );

i

pdnf( lnvalueofi

=

%d',,* );

The output ofthe above program would be: Addressoti=6485 Addre6sori=6485 AddEssofi=6485

AddEssofj=3276'

Understanding Pointers In C

8 Address

ofj=

3276

this, one mrely requires to extend the just in case...

Addressolk=7234

ofj=

Value

6485

The Jargon of Pointers

Valueofk=3276

Valueoli=3 Valueofi=3 Value of i= 3 Valu6ofi=3

Consider the following program segment:

inta=35; inl 'b

The following memory tDop would help you prcgram prints dle above outpul.

ir

tmcing out how the

J

k

3

6485

3216

3276

1234

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 for you. All the statemenls are fying to establish t:he srfle fact: tlBl since b oontains address ofanint-it's an int Dointer, ,ikewise, hao b contained an address of a flort it would have beoome a flolr

Figurc 1.3 Obs€rvc how the variables l, J and k have been declarcd,

inti; int

-l

i

-k

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 a pointer. 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 H€re, I is an ordinary ldt,

I

:

b=&a;

I

6485

lnl

definition of a Pointer' But

pointer. with the same argument if we have three Doiflter variableg first containing addrcss oian array, second contai;ing ad&ess ol,a structure and third containing address of a fuflction then It woulo be appropliate to call these ai an array pointer, a structure poinler and a fiinction pointe! respectively.

char, int zad.Jlod, Pointers Considei the followiog program:

f

P@gran main( )

5'/

{

charc,'cc; int i,

'ii;

Chapter 1: An Introductia to Pointers float

a,'aa;

'A I i=54;

c=

ascii value of A gets stored in c

t/

EI

a= 3.14;

lE;;l:;7l

1004

ii= &i

3.14

7006 7007 7008 7009

2009

i

aar&ai pdntf \Address contained in cc = %u", cc ) i plintf '\nAddr€ss conbined in ii = %u", ii ) ; pdntt '\nAddl8ss ontained in aa = %u', aa ) i p ntf "ivalue of c = %c', 'cc ) ; pdntf lnvalue of i = %d', 'ii ) ; printf 'Vrvaluo of a = o/ol, "aa ) ;

@ 1962

Figue

) And herc is the output,

,

Vslue ofc = A

i:

ii

m8l 7602

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 I and a rcspectively. This is because il and a& haye been dcclarcd as itrt and llort pointers respectively. Since il is an itrt pointer, *ll must fetch ar lrt. Similally, since aa is a flort pointer *ar must fetch a lloat.

,

Address conhined in cc = 1004 Addr€ss contain€d ln il = 2008 Address c.ntalned in aa = 7006

Valui of

t1

54

Valueofa=3.140000

Note that in the prltrtf( )s the addresses of chrr, lnt ard lhe no't all have been prioted using the fomat specifier 7ou, Sometimes the address miy tum out to be a number smaller than 32767. ln such 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 = &a ofthe first blte, 2008 itr il (refer Figurc 1.4). Similarly, forE bytes (7006) out'of stores only the address of the flrst byte occupied by the float variable a.

"

Do you &ink the following program would work? And what would be its puttr ui?

f

ftogram

if it

does

6'/

main( )

{

inli=54; float a =

3.,l4;

char'ii, 'aa

;

,13

ii= ( char . )&i;

aa=(char.)Aa; pdntf ( lnAddress conhined in ij = %u', ii ) i in aa = %u', aa ) ; pdntf ( lnvalue at fre address conhined in ii o/od',

prinf ( lnAddrcss onhined

)

:

Understanding Pointers In C

12 p

ntf ( "hvalue at lhe addrcss contained in aa = %d',

Chapter

l:

An Introduction to Pointers

13

(

'aa ) ;

inta=10i

)

irt

and aa have been declared as chsr poioters. Still rhe 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

Note that here

swapv(a,b);

pdntf(tla=%d",a); printf('bb=%d',b); ) swapv ( int x, inl y )

{

pdntf(\u=%d",x)i

a float pointer.

Passing .dddresses to Functions Aryu.ments arc generally passcd to fulctions in one of the two

inlt;

t=x; x=y; y=t;

Moral is, ifyou vdsh to acoess an integer value stored in a variable using 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 in

Printf

G) Bending the values of the arguments (b) sending the addresses ofthe arguments

v= 10 a=10 b=20

the called function. With this method, ohanges rnade to tlre fotmal argume[ts irr the called function have no effect oo the values ofthe sqtual argum€nts in the calling function.

following Eogram illustrates the 'Call by value'

r

= %d", y

)'

The output ofthe above program will be:

x=20

In the first method the 'value' of each 4crzal atgumetf in the calling functiol is oopied into aonespondirg forr al argumcnt of

(\y

)

waysr

z

20;

ll

printed through the first two prtntf( )'s. However, the prcgram falte$ at the next two prttrtf( )'s. This is so since ll is a character pointsr *ll gives value at .d&ess 2008 ard not lhe one presetrt at 2008 ad 2009. Similarly, *ra gives the value at 7006 and not the one contained in 7006, 7007, 7008 and 7009.

r p.J,l,ff

b=

Note that values

of s

and

b

exchanging the values of x and y.

remain unchanged even after

In the secold method (call by reference) the addresses of actual arguments in the calling futlction are copied into fonnal arguments ofthe called function. This means that using the fomal argumeflts in the called funotion, we can make changes in thJ actual

arguments

of the calling function. The following program

illushates this fact.

Understanding Pointers In C

14

f

Progtam 8 main( )

./

inta= 10; intb= 20l

areapei ( int r, ioat 'a, float *p )

swapr (&a, &b ) ; pdntf ( "\na = o/od" ,a);

printf('\nb=%d" ,b);

-y *x, swapr ( int int

)

{

t=-li )

The output ofthe above program would be:

a=20 b=10

Using 'call by reference' intelligently we can make a function retum more than one value at a time, _which is not possible ordinarily. This is shown in the program given below. /. Program 9'/ )

{ int radius

'a = 3.14'r'r; 'p = 2'*3.14' r;

And here is the output... Enter radius of a circle 5 Area = 78.500000 Perimeter = 31.400000

inlt;

main(

15

areaperi (radius, &area, &perimeter ) i printf ( 'Area = %f, area ) ; printf ( '\nPerimeter = %f', pedmeier)j

{

i

Chapter 1: An Introduclion to Pointers

i

float area, perimeter j

printf("\nEnter radius ofa circle " )j scanf ("%d", &radius ) ;

Here, we are making a mixed call, in the sense, we are passing the value of radius but addresses of area and perimeter. And siDce we are passing the addresses, any change that we make in values stored at addresses oontained in the variables a and p, would mako the chaflge effective even in main( ). That is why when the conhol retums fiom the function areaperi( ) we are able to ourpul the valuos ofiare! and perimeter.

Thus, we have been able to rctum two valuos from a called firnction. This helps us to overcome the limitation of the return statement, which can rctum only one value ftom a function at a lime

Functions Returning Pointers The way functions retum an int. a float. a double or any other.lala tlpe, it can even retum a pointer. Howevei, to make a funcrion retum a pointer it has to be explicitly mentioned in the calling

function as well as

in th€ function definition. The

program illustrates this.

following

16

Understanding Pointers In C

Chapler

main0 { int

-fun0 ;

An Introdu( tiott to Pointers

17

Solved Problems

/* Program 10-t

int'p;

L

/" prototype declaration */

P=fun0;

lAl

What will be the output oflhc following programs:

(1)

main0

t

printf ( '\n% u",p); printf ( "\n%d",-p);

int *iun( ) /- function defnilion */

int i= -5, j= -2; junk (i, &j); printf ( '\ni = %d

j=

i,l );

%d",

junk ( int i, int tj ) (

t inti=20; relurn(&i);

l- I li

)

This progmm shows how a pointer can be rctumed from

) a

funotion. Note that the prototlpe declaration tetls the compiler that fun( ) is a function which receives nothing but returns an integer pointer. The first prlntf( ) would output the address contained in p (address of l). Can you guess what the second prlntf( ) would output? No, it won't p nt 20. This is because, when the control comes back from fun( ), I dies. So sven if we have its ad&ess in p we can't access I since it is aheady dead. If you want I to survive and *p to give 20 then make sure that you deolare i as stafic as shown below: static int i = 20

;

Output

-5j Explanation One doubt immediately oom€q to the mind----can we use same variable names in differcnt functions? Yes, by all means, without absolutely any conflict. Thus, the two sets of i and J are two totally different sets of variables. While calling the function junk( ) the value ofl and the address ofj are passed to it. Natumlly, in ) i is declared as an ordinary int, whereas. j is declared as a pointer to an int.

ju*(

Even though the value of i is changed to 25 in junk( ), this ohange will not be refl€cted back in main( ). As against this, since j's address is being passed to junk( ), any change in Jutrk( ) gets reflected back in maitr( ). Hence -J- *j, which evaluates to 4 is reflected back in main( ).

18

Understanding Pointers In C

(2)

Chapler 1: An Introiluction to Pahtters

#include "stdio.h' main( )

While fiading out size of NULL, we are truly sDeakine findiog out size of 0. This is an htieger, hence- its'size ii

{ int a, b

19

rcported

=5;

a=b+NULL; printf('%d',a);

as

2 bytes.

Even though the string

-'

is empty

it

still contains character, '\0'. Hence its size arrrrs out to be I bvte,

)

(4)

Output

the

main0 {

floata=7.999999;

5

float'b,'c; b=&al

Explanatioa

c=b;

NULL

printf ( tu%u %u %u', &a, b, c ; ) printf (tl%d %d 96d 96d., a.( Aa

has beea defined

.I

in ',stdio.h,' as follows:

),.b,'c );

#define NULL 0

Output

Heroe, duiing peprocessiog

NUff *,in be rrplaced

resulting into 5 getting stored irr

(3)

r.

bv o,

4200

42N4N0

0 24576.318115

#include 'stdio.h'

maioo (

-)

printf ( '%d %d', sizeof ( NULI),

Output 21

Explanotiot

Explaaatioa !*zeof(.. ) ) ;

b oontains the addrcss ofvariable r. Since a is a floaq b must be a lloat pointer. The same address is then assigtred to c. Therefore c has also been declared as a f,oat pointe.. The fiIst prtntf( ) prirfs the address of a in three differcnt ways. No problem therc. What is supdsing is the output of the second printf( ). Through this pritrtf( ) we are attempting to print 7.999999 by. applying pohler operalors on a, b and c. a, *(&a), *b, *c all yield 7-999999 but when'they are prinred using yod, printf( ) blows it up as the ouq,ut above would justiry.

Understanding Pointers In C

20

Chapter

So always remember to use 9/"f to print floating point values. Don't rely on printf( ) to truncate a float value to an integer du ng pinting by using a yod. Vice versa also it is t[ue. The

printf("%f',i): mainO (

main0 (

int.c; c=check(10,20); printf("hc=%u',c);

int 'c

pdntf(tuc=%u.,c);

intj)

) int 'che6k ( int i, int j

int.p, rq ;

p=&i; q=&j; if(i>=45) retum (p

j

inl 'check ( in! int ) ; c = check (10, m );

)

(

iil. ;";;;;. A';

)

inti=7;

check ( int i,

retum (q )

(6) ;

)

Output

main( )

t

tloat.jamboee ( fod.); float P = 23.5, 'O

q=&p; pdntf (

Enor message: Non ponaue pointer assignment in main

The rcason for the eror is simple. The integers being passed to check( ) arc collected in i and j, and then their addresses

tlq

,

bebre cdt

q=jamborBe(&p); printf (

E)tpltiafion

)

)

);

else

2l

;;tu;

are a Iittle unreliable.

,

An Introduction to pointers

are assigred to p aDd q. The[ in the next statement the conditional operato$ test the value of i against 4j, anJ either the adtlress stored in p or the adjress ,t""J f"t appeaE that this address would be collected in c in maijt t and then would be printed out. Ard tb"* li". lirnction check( is not capable of retumins an inteser pololer. All that it ca! reEm is an ordinary intefer. Thus j"ust declaring c as an iDteger pointer is qot sufficient. We must make the following modificaaioru in the progmm to make it work properly.

following statements wouid not print 7.000000. Don't be suryrised ifyou get some odd value. In that sense y"d and ohf

(s)

l:

\q

afler ca[ = %u., q ) ;

tloal 'jamboree ( foat

t=t+1:

= 96u', q ) ;

t

)

Unders tatding Point ers rBtum (

r)

W

Chapter

l:

An Innoduction to pointers

Explatatioa

;

)

( tpb )++

OutPut

(2) !r th€ followinS gogrm add a stat€.ri€ot in the fi[roiion fu( ) such tllat ad&ess oft gels stored h l.

q bebtB call = silg8 q aier call = 5502

L

main0 {

Explatation ' means q

). q has be€a d€clarEd as a trott pointer' lt capable of holding the addtess of a flori ;; of p' a ltoal is stored ia q and rrt-rnf, o = Cr'm "aat""" th" p"iotf( ) This is the value of q il.i.,{'i"i-urt-*t li"Erle 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 stucture variable y. Now &om fun( ), we wish to access the members of

In the expression ( ( rtruct r * ) 0 ), 0 is being t)?€gasted into pointer to rtruct .. This explessiorl is pretending that there is a vrriable of t)?e slruct r at address 0. The expression & ( ( ( struct a * ) 0 ) -> y ) gives the addr€ss of sttuctur€ variable y. But this is aot the base address ofthe shuoture c. Hence we haye typecasM it using struct c *. Using lhis address we can access the member J of the slructule vadable y. Finally, aft€r taking the address of member j, we have t)?ecasted it using char * to make the subuaction po$sible. The statement to the dght of the '-' operator is straighdorward. On subtraotiotL we get the offset of member j of structure variable y. Now using offset the base address is calculated thrcugh the following statement. address = (struct

b')

((

char. )& (p

-> j

)- offset ) ;

Understanding Pointers In C

200

Chapter 4: Pointers and Structures

j

In the above statement & ( p > j ) gives the addrcss of member of structue variable y. Subtracthg offse1 fiorn this yields the addross of stuotule variable x. Using this address, lve have stoEd the 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 storc similar data in memory, While the elements of an array occupy contiguous memory looations, those of a linked list are not conshained to be stored in adjacent locations. The individual elements are siored "somewhere" ill memory, rather like a family dispeNed, but still bound together, The order of the elements is maintailed by explicit lirks between them. For instance, the marks obtained by differeilt students car be stored in a linked tist as shown in Figure 4.5.

and the Next pad is a poi[ter to the next node. The Iast node indicates that this is the last [ode in the list.

201

NULL in the

There are several operations that we can think of performing on linked lists. The following pro$am shows how to build a linked Iist by adding new nodes at the beginning, at the end or in the middle of the linked list. It also contains a funotion disphy( ) which displays all the nodes present in the linked list and a function deleae( ) which can delere any node in lhe linked list. co through the program carefully, a step at a time.

f f

Program 53

'i

Prcgram lo maintain a linked #include 'alloc.h"

f

list'/

$ructure containing a data part and link pad */

struct node

( int data ; slruct node 'link

Data Nctt

i

)l main0

{

Figue 4.5 Observe that the linked list is a collection of elements called nodes, eaoh of whioh stores two items of infomation-an eleme( ofthe list and a link. A link is a poifter or an addrcss that indicates explicitly the location of the node containing the successot of lhe list element. In Figue 4.5, the arows rcpresent the links. The Data pait of each oode cotrsists of the marks obtained by a student

stuct node *p

;

p = NULL

empty linked

;f

pdnf('hNo. of elements append(&p,1); append(&p,2); append(&p,3): append(&p,4); append ( &p, 17 ) ;

cllsc( ) ; display ( p

);

addalbeg (&p, 999 )

;

list:i

ln the Linked

List:

%d", count ( p ) )

;

Chapter 4: Pointer.s and Structures

Understanding Pointers In C

202

while (temp -> link != NULL ) temp = 1sO -, 1;n* ,

addalbeg ( &p, 888 addatbeg ( &p, 777

f

(p ) ;

display

a)

addaftor(p,7,0 )i addafter(p,2, 1);

r)

addafter ( p, 1, 99 )

delets ( &p, 888 ) deletB ( &p, 'l ) i

ount

(p));

;

slrucl node lemp

p)

add new node '/ temp = malloc( sizeof ( structnode ) )

);

*temp,

'q

'r;

(,

dala

-

num '

temp ;

=

f

adds a new node afrer the specilied number of nodes addafier ( slruct node 'q, inl loc, int num )

"

pg;-117',t*",st

)

is empty, cleate first

node'/

{ stuct node Iemp, 1

= malloc ( sizeof ( struct node )

lemp lemp "> data = num '

temp>link=NULL' -q=temp;

I

)

;

'(

temp=q;

f

skip lo desked portion'/ tor ( i= 0; i< loc ; i+t ) lemP =

;

go to last

f node'i

;

inti;

{

else

;

)

(

I

;

temp>link='q

ddds a node al'ttre snd ofe llnked lisl'1 *q, lnt num app€nd ( struct node )

temp:.'q

'/

I in the linked llst= %d', count (

bmp

'

;

adds a new node at the beginning of the llnksd list addalbeg ( sfuct node 'q, int num )

l if

-q if ( ==

link = NULL

;

f

);

pdntf('\nNo. olelements

temP =

;

{

display(p)i

-q

data = num

)

printf ( '\nNo. of Elements in th€ Linksd List = y!d',

struct node

'i

lemp>link=r'

,}

dlsplay(p);

delete (&p, 10

add node at the end

r= malloc ( sizeof( struct node ))

t6,r, -, ,'n* '

if end of linked list is encountercd if ( temP == ;t1911 ;

'/

'/

203

204

Understanding Pointers In C

{

relum

)

tl]herc

pdntf (

I

are less than %d elements in list', loc )

;

{

node'/ rldata=num; r-> link = temp .> link; temp -> link = r;

c;

/* displays the contenb of display (structnode'q

) ( printf("\n")i

NULI)

while (temp l= NULL ) if (temp -> data == num )

-/

{

I

if node lo be deleted is lhe if (temP =='q 1

fEt

node in the linked

( 'q

list'/

f

= temp -> link i frEe the memory occupied by the node

free (temp )

'i

i

retum;

p ntf ( "%d ', q -> data ) ; q=q->tink;

)

I

f

deleles the intemediate nodes in the linked else

/'counts the numberot nodes prBsent in the linked count ( strudt node

intc

;

temp=.q;

he lhked list

/' traverse the entire linked while (q l=

stuct node .old, 'temp

'/

;

){

{

retum

) debtes lhe speciied node from the linked list delete (strucl node "q, inl num )

insert new r = malloc ( sizeof ( stucl node ) )

)

;

f

f

{

Structures

Chapter 4: Pointers and

=

'q

)

{

list'/

old -> link = temp -> link nee ( lemp ) j

Etum

0;

/' traverEe the entirc linked list'/

) { q=q->link; c++ ; ) while ( q != NULL

list./

;

;

) )

f

fave$e the linked list till the last node is reached

'/

else

{ old = temp

temp

)

;

=le"

oH points to the prcvious node */ -' /'go b the next node */

f

"n*

'

list'/

205

Underslanding Pointers In C

206

ntf ('\nElement

o/od

207

would fail, since *q (i.e. p is non-NULL). Now temp is made to point to the first node in the list through the statement

)

p

Chapter 4: Pointers and Structures

notfound', num

);

)

temp =

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 first node 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 list When no node has been added to the list, p has been set to NULL to indicate that the list is emptY.

'q

;

Then usitrg temp we have traversed tbrough the entire linked list usitrg the stat€metrts:

)

lini != NULL ) while ( temp temo = tsm, -> link j The position of the pointers before and after traversing the linked list is shown in Figure 4.6

The append( ) function has to deal with two sihrations:

(a) (b)

The node is being added to an empty list. The node is being added at the end ofar existing list.

p telnp

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

t

E I

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. Note that *q is nothing but equal to P. In the other case, when the linked list is trot ernpty, the condition if

(-q == xg11-

1

node being added

Figue 4.6 Each time through the loop the statement iemp = temp -> link makes temp point to the next node in the list. When temp reaches the last node the condition temp -> link !: NULL would fail. Once outside the loop we allocate space for the rew node through the statement

Understanding Pointers In C

208

r= malloc (sizeof{struct node

the right hand side lelds 400. This address is now stored in temp. As a result, temp starts poinling to the nod€ present at address 400. In effeot the statement has shifted t€mp so that it has started

));

..Onoe the spaoe has boen allocated for the new node its data part is stuffGd \rith num and the link part with NtlLL. Note that this node is now going to be the last Node in the list.

that now remains to be done is connecting the previous last node with the new last node. The previous last node is being pointed to by temp aod the new last node is being pointed to by r. They are conn€cted through the statement A11

temp "> link = r

I

this link gets established There is often a confusion as to how the statement temp = temp

->

link

us

makes temp point

to the next node in the list. Let

pointing to the next node in the lisr. Let us now undeNtand th. addatbeg( ) functioD. Suppose there are already 5 nodes in the list and we wish to add a new node at the beginning of rhis existing linked list. This situation is show in Figure 4.8.

rE Before Addition

underctand this with the help of an example, Suppose in a linked list containing 4 nodes temp is pointing at the first node. This is shown ill Figure 4.7.

temp

EC I,T.*l f,-f,ool ET,;] I;F*{ 150

After Addition

910

Figure 4.8 Figure 4.7

Imtead of shov/ing the links to the next node I have shown the addresses of the next Ilode in the link part of each node. When we execute the statement temp = tgmp -> link

For adding a new node at the beginning, frrstly space is allocated for this node and data = num

Now we need lo make ihe titrk pan of this node point lo the existing first Itode. This has be€lt achieved through the statement

Understanding Pointers In C

210

temp ->

link:1

(which is same as 'q) to

'

the

211

ext node arld then deleted the earlier

node.

Lastly, this now node must be made the fiI5t node in Ore list. Thi$ has been attained tkough the stateme 'q

Chapter 4: Pointers and Strucnres

= temp ;

If the node io be deleted is atr i ermediate node, then rhe posirion ofvafious pointers atrd links before and after the deletion is shown in Figue 4.9.

function pemits us to add a new node after a specilied number ofnode in the linked list.

The addafter(

)

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. The positiofl ofpointers once the control rcaches outsidc the for loop is shown in the Figue 4.10(a), Now space is allooated for lhe nodc to be 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 3 and 4. This is achieved through the statements

nodc to ba dcleted - 99

Beforc Del€tton

r.> link = t€mp -> link; temp -> link = r i The filst statement mskes link part ofnode contaiuing 99 to point to the node containing 4. The second staternent ensues that the lillk part ofnode containing 3 points to the node containing 99. On execution of the sccond statement the earlier link between 3 and 4 is severed. So now 3 no longer points to 4, it points to 99. The disptay( ) and count( ) functions are straiSht forward. I leave them for you to understand.

'Ilat

brings us to the last functio! in the prcgram i.e. dclete( ). Io this function through the while loop, we have traveNed thrcugh the entirc linked list, checking at each node, whether it is the node to be deleted. If so, we have checked if the rode being deleted is the first node in the linked list. Ifit is so,,we have simply shifted p

temp

J i

_eJ_l _ _

After Deledon

mt noa" -l+ geh deleted

Figure 4.9

The rddafter(

) fihction pemits us to add a new

node after a

specified number ofnode in the linked lisr. To begin wirh, through a loop we skip the desircd number ofnodes after which a new nod6 is to be added. Suppose we wish to add a new node containing data as 99 after the 3d node in the list. The

212

Chapter 4: Pointers and Structures

Understanding Pohtters In C

2t3

position ofpointeis once the contol reaches outside the for loop is shown in the Figure 4. I 0(a).

LiDk€d list of floats

Linked list ofnames

i

__-L

l*l

I

(.) Bcfore Inrertion

LiDled list

of

Structrcs / Records

N st n.is for NULL fb) Alter Insertion

Fisue 4.10 and a wrcng implession that beginners carry is that a linked list is used only for stodng integers. However, a linked list can virtually be used for storing any similar data. For example, there can exlst a linked list of floats, a linked list of names, or even a linked list ofrecords, where each record contains name, age and salary of an employee. These linked lists are shown in the follor/ing figure.

A oommon

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 f

kogram

54'l

Program for adding and deleting nodes from an ascending order linked list

'/

#inclde 'alloc.h'

Understanding Pointerc In C

214 stucl node ( inl dab

Chapter 4: Pointers and Slructures

'rt
dala > num )

;

struot rbd€

link

{

;

);

'q

=r;

('q)>link=bmp;

main( )

)

(,

-

ebo

sfud node'p; p , 11911 ; f smE{y ttnk€d tbt r/

,(

f. hat eE6 fie enliE linlsd llst

tp Edd(&p,5); add(&p,1); add(&p,6)i add(&p,4)i add(4p,7);

rcw node

while (

unp

.> llnk = tsmp

)

link

blrptllnl=r' ot Blanr€nb

h Llnkod Ust

= 96d', coufl[ (

) bmP =

51, -,

,nl( ,

f

go

b fi6 mxt

)

) ) dipbys fi6 conbnE ot ho llnkod lbt ./ dbday ( stnd nodo 'q )

f

display(p); of sl€monts in Unked Ust = 96d', munt ( P ) ) ;

{

)

f

adds node b an ascending odei llnked lisi *q, lnt num add ( slruct node )

pnnf ( 1D') ;

f

'/

ha\€6e tle BnliIB linfed

lM'/

while ( q != NULL )

{

{ struct node 1, 'temP = 'q r = malbc ( sizeol ( r -> dala = num ;

.

lB M;

p) );

dsl6b ( &p, 9 )

tNo.

'/

l= NULL )

bmp.> ltnk = NULL ))

{

d.let€(4p,7) dslsts(&p,4) dsloto(&p,5)

printt (

tle po€lton b lns€n

il ( bmp .> data llnk .> data > num ll

clrsc( ) i

dlsplay(p); ptlntf('hNo.

s€arch

{

r

.

h

stl$t

Ptinf('9{d',q}dab); q=q>link;

;

nodE ).) ;

)

)

node

'/

234

Understanding Pointers In C

f

stucture reprBsenling a nod8 of lhe doubly linked list sIuct dnode

Chapter 4: Poinlers and Struch.res prinf ( "hNo. oI elements

'/

f

adds a new node at the end of the doubly linked list d_append ( strucl dnode 's, int num )

struct dnode 'prev j lnt dala ; dnodB

'

nsxt

slruct dnode 'r, 'q = 's

f

main0

{

P

= NULL

d_append

d_append

if

I

{

i

empty doubly linked

;

$e

ir('s 'p

'/

{

;

);

struct dnods

d_ount ( p ) ) ;

)

{ stucl

in lhe DLL = %d\n',

linked list h empty == NULL )

'/

fcreate a new node '/ 's = malloc (sizeof ( structdnode ) )

list'/

;

's))prEv=NI,JLL; 's ) .> data

&p,11)j &p,21);

= num

'

's))next=NULL' ) else

clrsc( ) j

(

d-display(p); plintf ( lnNo. of elemenb in the DLL %dvt', d_count ( p = ))

I

traveGe the linked list till the last node is Bached while ( q -> next l. NULL )

;

q=q">next;

d_addabes (&p, 33 ) j d*addalb€g ( &p, 55 )

;

f

d_display(p); printf ( 'hNo, of elemenls d_addafrer ( p, 1, 4000 ) d_addafrer ( p, 2, 9000 )

'/

add a new node at he end r= malloc ( sizeol( siructdnode ) )

in the DLL = %dvr,,

;

r)data=num;

d_ount ( p ) ) ;

r -> next = NLrLL ;

rlprev=q;

;

q->next=ri

;

)

d-display(p); pdntf ( '\nNo. of Blements in the DLL = %d\n', d-count ( p ));

f

d_delete ( &p, 51 )

;

adds a new node at the b€gining of the linked *s, int num d-addatbeg ( stuct dnode )

d_deleb (&p, 21 )

;

{

d-disday (p );

structdnode.q

f

;

c.eate a new node

'/

list'/

'/

23s

.28t

Chapter 5: Pointers and Data Structures 280 add &first 1 ) add &flsl 2 add &lirst 3 add &first 4 add &lirst, 5 add &frst 6 ) add &first 7 )

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 flexibility in allowing the items to be rearanged efficiently. This flexibility is gained at the expense of quiok access to aay aIbitary item in the

list. clIsc( ) ;

Irr this chaptq we would write pro$ams to perfom

more find out also We would list, complicated operations on the linked polynomials and ho\l. linked lists catr be used to matltain manipulate them. Let us begin with merging of two linked lists.

pdnil('Firstlinked list :' ) ; display(frst); pdnf ('hNo. ofelements in Linked List: %d' , count (first

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

Pmgram 60 '/ PIogEm to merg8 h o llnked llsb, Estlicting lhe common denents occur only onc€ '/ #lnclude 'alloc,h'

f

&sec.nd,4 ) &second, 5 ) &second, 6 )

; ; i

; ; ;

pdntf ( h\nsecond linked list : " )

;

b

merge

(liM, second, &thid

)

;

prinf('V nThe concatenated list i " ) ; display ( lhird ) ; pdntf ("hNo. of elements in Linked List: %d', count (third ) ) j )

int data

;

suuct node 'link

f

adds node to an ascending oder linked add ( struct node "q, int num )

;

);

{ main( )

{

add add

;

display ( s8cond ) ; printf ('\nNo. of elements in Linked List: %d" , count ( second ))

slruct node

(

&s€cond, 8 ) &second, I ) &se{ond, 3 )

add add &second, 7 )

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

add add add

node'llEl 'second, 'tlid ; irst = second : thitd = NULL ; f empty struct

linked

lisb'/

))j

stlct

node 'r,

lemp

=

*q

;

list'/

i

Understanding Pointers In C

282

r = malloc ( sizeof (

r-> data = num

slruct node ) )

pdntf ( '%d ', q

;

I

if list is empty or if new node is to be inserled before the lirst node if( 'q == NULL ll (-q ) -> data > num )

(

'q ) -> link

./

data )

) )

f

counts ttle number of nodes present in the linked list count ( struct node ' q )

tq=r; (

)

q=q_>link;

i

= lemp

{

;

)

'/

intc=0;

else

f

(

traverse lhe entire tinked tht while (q != NULL )

f faveBe the enlire linked list to search the position to insefi he new node '/ while (temp l= NULL ) t

{

(temp.> data temp

)

< num && (temp -> link ->

link == NULL

)

dah > num ll

Etum c

r.>

link = temp.> link temp -> link = r '

retum

i

) temP = 1660

-,1,n* fgo b nexl node'/

)

temp -> link =

stuct node 'z ;

r'

z = NULL

)

f

I

f

displays the contents of the linked list display ( struct node'q )

pintf("b') (q

'/

;

if both lisls are empty

ir(p

'/

== NULI &&q == NULL )

relum

;

f

l= NULL )

tsaveFe Mh linked lists tilllhe e loop is teminated while ( p != NULL &8 q t= NULI

nd. lf end of any one list is Eached

'/

;

faverse the entire linked list

while

t

tm linked lists, resld,rting the common elements to occur only once in fEfnal list '/ merye ( stnrcl nod€'p, slrucl node,q, slruct node -s ) me4es he

{

r-> link = NULL;

f

:

)

f

i

;

)

{

{

q=q)link; c++

if

./

-/

)

{

f

if node being added h the if ( 's == NULL )

lirst

node

'/

Undersnnding Pointers In C

284

Chapter 5: Pointers and. Data Structures z=z->link; z>data=p)data;

's = malloc ( sizeof ( struct node ) ) ;

z='sj

P=Pllink;

)

)

else

f

{ z -> link = malloc (sizeof (struct node

z:

));

z->.link;

(

'/

z-> link = malloc (sizeof(struct node ))

z=z)link;

if(p->datadata=pldatai p=

p.> llnk

-1 6316 = q -> dala

q=q->link; .'

(

;

;

) z-> link = NULL;

i

)

)

else

In this program, as usual, we begin by building a structure

to accommodate the data and link, whioh togeth€! represent a node. We have us€d pointers lirst, Becotrd and thlrd to point to the three linked 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 lirst and other by the pointer secotrd. Finally, the merge( ) function is called to merg6 the two lists into one. This m€rged list is pointed to by tlre poider third. While merging the two lists it is assumed that the li$ts themselves are in ascending order. While building the two lists the add( ) function makes sure that when a node is added the elements in tlle lists are maintained in ascending order, While merging the two lists the merge( ) firnctions accounts for the possibility of any ofthe two lists being empty,

(

if(q->data