Anda di halaman 1dari 14

C Pointers Fundamentals Explained with Examples Part I

by Himanshu Arora on December 5, 2011

Anybody who is working on Linux environment (not ust deve!o"ers#, shou!d understand the $undamenta!s o$ % "rogramming !anguage and write some basic % "rogram& 'his artic!e is "art o$ our ongoing series on % "rogramming !anguage& 'he conce"t o$ "ointers is one o$ the most "ower$u! $undamenta!s o$ %(%)) !anguage& 'hrough "ointers a deve!o"er can direct!y access memory $rom his(her code which makes memory re!ated o"erations very $ast& *ut, as a!ways, with great "ower comes great res"onsibi!ity& A deve!o"er has to very care$u!!y make use o$ "ointers in order to avoid some "rob!ems that can be nightmare to debug& +n this artic!e we wi!! study the very basic conce"t o$ "ointers with exam"!es in % !anguage&

What are Pointers?


Di$$erent $rom other norma! variab!es which can store va!ues, "ointers are s"ecia! variab!es that can ho!d the address o$ a variab!e& ,ince they store memory address o$ a variab!e, the "ointers are very common!y said to -"oint to variab!es.& Lets try to understand the conce"t&

As shown in the above diagram/

A norma! variab!e 0var1 has a memory address o$ 1001 and ho!ds a va!ue 50& A pointer variable has its own address 2023 but stores 1001, which is the address o$ the variab!e 0var1

How to Declare a Pointer?


A "ointer is dec!ared as /
<pointer type> *<pointer-name>

+n the above dec!aration / 1& "ointer4ty"e / +t s"eci$ies the ty"e o$ "ointer& +t can be int,char, $!oat etc& 'his ty"e s"eci$ies the ty"e o$ variab!e whose address this "ointer can store& 2& "ointer4name / +t can be any name s"eci$ied by the user& 5ro$essiona!!y, there are some coding sty!es which every code $o!!ows& 'he "ointer names common!y start with 0"1 or end with 0"tr1 An exam"!e o$ a "ointer dec!aration can be /
char *chptr;

+n the above dec!aration, 0char1 signi$ies the "ointer ty"e, ch"tr is the name o$ the "ointer whi!e the asterisk 061 signi$ies that 0ch"tr1 is a "ointer variab!e&

How to initialize a Pointer?


A "ointer is initia!i7ed in the $o!!owing way /
<pointer declaration(except semicolon)> = <address of a variable> OR <pointer declaration> <name-of-pointer> = <address of a variable>

8ote that the ty"e o$ variab!e above shou!d be same as the "ointer ty"e&('hough this is not a strict ru!e but $or beginners this shou!d be ke"t in mind#& 9or exam"!e /
char ch = 'c'; char *chptr = ch; !!initiali"e OR char ch = 'c'; char *chptr; chptr = ch !!initiali"e

+n the code above, we dec!ared a character variab!e ch which stores the va!ue 0c1& 8ow, we dec!ared a character "ointer 0ch"tr1 and initia!i7ed it with the address o$ variab!e 0ch1&

8ote that the 0:1 o"erator is used to access the address o$ any ty"e o$ variab!e&

How to se a Pointer?
A "ointer can be used in two contexts& %ontext 1/ 9or accessing the address o$ the variab!e whose memory address the "ointer stores& Again consider the $o!!owing code /
char ch = 'c'; char *chptr = ch;

8ow, whenever we re$er the name 0ch"tr1 in the code a$ter the above two !ines, then com"i!er wou!d try to $etch the va!ue contained by this "ointer variab!e, which is the address o$ the variab!e (ch# to which the "ointer "oints& i&e& the va!ue given by 0ch"tr1 wou!d be e;ua! to 0:ch1& 9or exam"!e /
char *ptr = chptr;

'he va!ue he!d by 0ch"tr1 (which in this case is the address o$ the variab!e 0ch1# is assigned to the new "ointer 0"tr1& %ontext 2/ 9or accessing the va!ue o$ the variab!e whose memory address the "ointer stores& %ontinuing with the "iece o$ code used above /
char ch = 'c'; char t; char *chptr = ch; t = *chptr;

<e see that in the !ast !ine above, we have used 061 be$ore the name o$ the "ointer& <hat does this asterisk o"erator do= <e!!, this o"erator when a""!ied to a "ointer variab!e name(!ike in the !ast !ine above# yie!ds the va!ue o$ the variab!e to which this "ointer "oints& <hich means, in this case 06ch"tr1 wou!d yie!d the va!ue ke"t at address he!d by ch"tr& ,ince 0ch"tr1 ho!ds the address o$ variab!e 0ch1 and va!ue o$ 0ch1 is 0c1, so 06ch"tr1 yei!ds 0c1& <hen used with "ointers, the asterisk 061 o"erator is a!so known as 0va!ue o$1 o"erator&

!n Example o" C Pointers


%onsider the $o!!owing code / %>D? /

#incl$de <stdio%h> int main(void) & char ch = 'c'; char *chptr = ch; int i = '(; int *intptr = i;

float f = )%'((((; float *fptr = f; char *ptr = *+ am a strin,*; printf(*-n ./c01 ./d01 ./f01 ./c01 ./s0-n*1 *chptr1 *intptr1 *fptr1 *ptr1 ptr); 2 ret$rn (;

>A'5A' /
3 %!pointers .c01 .'(01 .)%'(((((01 .+01 .+ am a strin,0

'o debug a % "rogram, use gdb& 'he above code covers a!! the common "ointers& 'he $irst three o$ them are very trivia! now to understand so !ets concentrate on the $ourth one& +n the $ourth exam"!e, a character "ointer "oints to a string& +n %, a string is nothing but an array o$ characters& ,o we have no staring "ointers in %& +ts the character "ointers that are used in case o$ strings too& 8ow, coming to the string, when we "oint a "ointer to a string, by de$au!t it ho!ds the address o$ the $irst character o$ the string& Lets try to understand it better& 'he string, 0+ am ,tring1 in memory is "!aced as /
)(() + )((' a )((4 m )((5 ; )((6 t )((7 r )((8 i )((9 n )((: , )()( -(

,ince characters occu"y one byte each, so they are "!aced !ike above in the memory& 8ote the !ast character, its a nu!! character which is "!aced at the end o$ every string by de$au!t in %& 'his nu!! character signi$ies the end o$ the string& 8ow coming back to the "oint, any character "ointer "ointing to a string stores the address o$ the $irst character o$ the string& +n the code above, 0"tr1 ho!ds the address o$ the character 0+1 ie 1001& 8ow, when we a""!y the 0va!ue o$1 o"erator 061 to 0"tr1, we intend to $etch the va!ue at address 1001 which is 0+1 and hence when we "rint 06"tr1, we get 0+1 as the out"ut& A!so, +$ we s"eci$y the $ormat s"eci$ier as 0Bs1 and use 0"tr1 (which contains the starting address o$ the string#, then the com"!ete string is "rinted using "rint$& 'he conce"t is that Bs s"eci$ier re;uires the address o$ the beginning byte o$ string to dis"!ay the com"!ete string,

which we "rovided using 0"tr1 (which we know ho!ds the beginning byte address o$ the string#& 'his we can see as the !ast "rint in the out"ut above&

Pointers as #tructure $b%ects


%onsider the $o!!owing code / %>D?/
#incl$de<stdio%h> str$ct st& int a; char ch; 2; int main(void) & str$ct st ob<; str$ct st *stob< = stob<->a = 6; stob<->ch = 'a'; printf(*-n ./d0 ./c0-n*1 stob<->a1 stob<->ch); ret$rn (; 2

ob<;

>A'5A'/
3 %!pointers .60 .a0

+n the above code, we have dec!ared a "ointer stob o$ ty"e 0struct st1& 8ow since the "ointer ty"e is a structure, so the address it "oints to has to be o$ a 0struct st1 ty"e variab!e(which in this case is 0ob 1#& >ther interesting "art is how structure e!ements are accessed using "ointer variab!e 0stob 1& Ces, <hen dea!ing with "ointer ob ects, its a standard to use arrow o"erator 4D instead o$ 0&1 o"erator(which wou!d have been used, had we used 0ob 1 to access the structure e!ements#& 'o conc!ude, +n this artic!e we studied the conce"t o$ "ointers in % $rom scratch and then s!ow!y bui!t u"on our understanding to more com"!ex to"ics !ike using "ointers as structure ob ects& 'his was a basic tutoria!, we wi!! cover more com"!ex "ointer conce"ts in the "art4++ o$ this artic!e& (5art 2/ Advanced % "ointers#&

C Pointer to Pointer& Pointer to Functions& !rra' o" Pointers Explained with Examples
by Himanshu Arora on Eanuary 23, 2012 +n % "rogramming !anguage, the conce"t o$ "ointers is the most "ower$u! conce"t that makes % stand a"art $rom other "rogramming !anguages& +n the "art4+ o$ this series we discussed the $undamenta! conce"ts around % "ointers& +n this artic!e, we wi!! try to deve!o" understanding o$ some o$ the re!ative!y com"!ex conce"ts& 'he $o!!owing are ex"!ained in this artic!e with exam"!es/ 1& 2& @& 2& %onstant "ointer and "ointer to constant& 5ointer to "ointer with an exam"!e Array o$ "ointers with an exam"!e 5ointer to $unctions with an exam"!e

() C Constant Pointer and Pointer to Constant


As a deve!o"er, you shou!d understand the di$$erence between constant "ointer and "ointer to constant&

C Constant pointer
A "ointer is said to be constant "ointer when the address its "ointing to cannot be changed& Lets take an exam"!e /
char ch1 c; char *ptr = ptr = c ch

+n the above exam"!e we de$ined two characters (0ch1 and 0c1# and a character "ointer 0"tr1& 9irst, the "ointer 0"tr1 contained the address o$ 0ch1 and in the next !ine it contained the address o$ 0c1& +n other words, we can say that +nitia!!y 0"tr1 "ointed to 0ch1 and then it "ointed to 0c1& *ut in case o$ a constant "ointer, once a "ointer ho!ds an address, it cannot change it& 'his means a constant "ointer, i$ a!ready "ointing to an address, cannot "oint to a new address& +$ we see the exam"!e above, then i$ 0"tr1 wou!d have been a constant "ointer, then the third !ine wou!d have not been va!id& A constant "ointer is dec!ared as /

<type-of-pointer> *const <name-of-pointer>

9or exam"!e /
#incl$de<stdio%h> int main(void) & char ch = 'c'; char c = 'a'; char *const ptr = ch; !! = constant pointer ptr = c; !! >ryin, to assi,n ne? address to a constant pointer% @ROABCCCC 2 ret$rn (;

<hen the code above is com"i!ed, com"i!er gives the $o!!owing error /
3 ,cc -@all constptr%c -o constptr constptr%cD +n f$nction EmainFD constptr%cD:D errorD assi,nment of read-only variable EptrF

,o we see that, as ex"ected, com"i!er throws an error since we tried to change the address he!d by constant "ointer& 8ow, we shou!d be c!ear with this conce"t& Lets move on&

C Pointer to Constant
'his conce"t is easy to understand as the name sim"!i$ies the conce"t& Ces, as the name itse!$ suggests, this ty"e o$ "ointer cannot change the va!ue at the address "ointed by it& Lets understand this through an exam"!e /
char ch = 'c'; char *ptr = ch *ptr = 'a';

+n the above exam"!e, we used a character "ointer 0"tr1 that "oints to character 0ch1& +n the !ast !ine, we change the va!ue at address "ointer by 0"tr1& *ut i$ this wou!d have been a "ointer to a constant, then the !ast !ine wou!d have been inva!id because a "ointer to a constant cannot change the va!ue at the address its "ointing to& A "ointer to a constant is dec!ared as /
const <type-of-pointer> *<name-of-pointer>;

9or exam"!e /
#incl$de<stdio%h> int main(void)

&

char ch = 'c'; const char *ptr = ch; !! = constant pointer 'ptr' pointin, to 'ch' *ptr = 'a';!! @ROABCCC Gannot chan,e the val$e at address pointed by 'ptr'% 2 ret$rn (;

<hen the above code was com"i!ed, com"i!er gave the $o!!owing error /
3 ,cc -@all ptr'const%c -o ptr'const ptr'const%cD +n f$nction EmainFD ptr'const%cD8D errorD assi,nment of read-only location E*ptrF

,o now we know the reason behind the error above ie we cannot change the va!ue "ointed to by a constant "ointer&

*) C Pointer to Pointer
'i!! now we have used or !earned "ointer to a data ty"e !ike character, integer etc& *ut in this section we wi!! !earn about "ointers "ointing to "ointers& As the de$inition o$ "ointer says that its a s"ecia! variab!e that can store the address o$ an other variab!e& 'hen the other variab!e can very we!! be a "ointer& 'his means that its "er$ect!y !ega! $or a "ointer to be "ointing to another "ointer& Lets su""ose we have a "ointer 0"1G that "oints to yet another "ointer 0"2G that "oints to a character 0ch1& +n memory, the three variab!es can be visua!i7ed as /

,o we can see that in memory, "ointer "1 ho!ds the address o$ "ointer "2& 5ointer "2 ho!ds the address o$ character 0ch1& ,o 0"2G is "ointer to character 0ch1, whi!e 0"1G is "ointer to 0"2G or we can a!so say that 0"2G is a "ointer to "ointer to character 0ch1& 8ow, in code 0"2G can be dec!ared as /
char *p' = ch;

*ut 0"1G is dec!ared as /


char **p) = p';

,o we see that 0"1G is a doub!e "ointer (ie "ointer to a "ointer to a character# and hence the two 6s in dec!aration& 8ow,

0"1G is the address o$ 0"2G ie 5000 06"1G is the va!ue he!d by 0"2G ie H000 066"1G is the va!ue at H000 ie 0c1

+ think that shou!d "retty much c!ear the conce"t, !ets take a sma!! exam"!e /
#incl$de<stdio%h> int main(void) & char **ptr = AHII; char *p = AHII; char c = 'd'; p = c; ptr = p; printf(*-n c = ./c0-n*1c); printf(*-n *p = ./c0-n*1*p); printf(*-n **ptr = ./c0-n*1**ptr); ret$rn (; 2

Here is the out"ut /


3 %!do$bleptr c = .d0 *p = .d0 **ptr = .d0

+) C !rra' o" Pointers


Eust !ike array o$ integers or characters, there can be array o$ "ointers too& An array o$ "ointers can be dec!ared as /
<type> *<name>.<n$mber-of-elements0;

9or exam"!e /

char *ptr.40;

'he above !ine dec!ares an array o$ three character "ointers& Lets take a working exam"!e /
#incl$de<stdio%h> int main(void) & char *p) = *Jimansh$*; char *p' = *=rora*; char *p4 = *+ndia*; char *arr.40; arr.(0 = p); arr.)0 = p'; arr.'0 = p4; printf(*-n p) = ./s0 -n*1p)); printf(*-n p' = ./s0 -n*1p'); printf(*-n p4 = ./s0 -n*1p4); printf(*-n arr.(0 = ./s0 -n*1arr.(0); printf(*-n arr.)0 = ./s0 -n*1arr.)0); printf(*-n arr.'0 = ./s0 -n*1arr.'0); ret$rn (; 2

+n the above code, we took three "ointers "ointing to three strings& 'hen we dec!ared an array that can contain three "ointers& <e assigned the "ointers 0"1G, 0"2G and 0"@G to the 0,1 and 2 index o$ array& Let1s see the out"ut /
3 %!arrayofptr p) = .Jimansh$0 p' = .=rora0 p4 = .+ndia0 arr.(0 = .Jimansh$0 arr.)0 = .=rora0 arr.'0 = .+ndia0

,o we see that array now ho!ds the address o$ strings&

,) C Function Pointers
Eust !ike "ointer to characters, integers etc, we can have "ointers to $unctions& A $unction "ointer can be dec!ared as /

10

<ret$rn type of f$nction> (*<name of pointer>) (type of f$nction ar,$ments)

9or exam"!e /
int (*fptr)(int1 int)

'he above !ine dec!ares a $unction "ointer 0$"tr1 that can "oint to a $unction whose return ty"e is 0int1 and takes two integers as arguments& Lets take a working exam"!e /
#incl$de<stdio%h> int f$nc (int a1 int b) & printf(*-n a = /d-n*1a); printf(*-n b = /d-n*1b); ret$rn (; 2 int main(void) & int(*fptr)(int1int); !! K$nction pointer fptr = f$nc; !! =ssi,n address to f$nction pointer f$nc('14); fptr('14); ret$rn (; 2

+n the above exam"!e, we de$ined a $unction 0$unc1 that takes two integers as in"uts and returns an integer& +n the main(# $unction, we dec!are a $unction "ointer 0$"tr1 and then assign va!ue to it& 8ote that, name o$ the $unction can be treated as starting address o$ the $unction so we can assign the address o$ $unction to $unction "ointer using $unction1s name& Lets see the out"ut /
3 %!fptr a = ' b = 4 a = ' b = 4

,o $rom the out"ut we see that ca!!ing the $unction through $unction "ointer "roduces the same out"ut as ca!!ing the $unction $rom its name& 'o conc!ude, in this artic!e we touched some o$ the advanced conce"ts re!ated to "ointers& 'here can be some interesting "rob!ems re!ated to "ointers, which we might cover in some $uture artic!e&

11

C Constant Pointers and Pointer to Constants Examples


by Himanshu Arora on Eune H, 2012 5ointers in % has a!ways been a com"!ex conce"t to understand $or newbies& +n this artic!e, we wi!! ex"!ain the di$$erence between constant "ointer, "ointer to constant and constant "ointer to constant& 'his artic!e is "art o$ the ongoing series on % "ointers/ "art 1, "art 2, "art @ (this artic!e#

Constant Pointers
Lets $irst understand what a constant "ointer is& A constant "ointer is a "ointer that cannot change the address its ho!ding& +n other words, we can say that once a constant "ointer "oints to a variab!e then it cannot "oint to any other variab!e& A constant "ointer is dec!ared as $o!!ows /
<type of pointer> * const <name of pointer>

An exam"!e dec!aration wou!d !ook !ike /


int * const ptr;

Lets take a sma!! code to i!!ustrate these ty"e o$ "ointers /


#incl$de<stdio%h> int main(void) & int var) = (1 var' = (; int *const ptr = var); ptr = var'; printf(*/d-n*1 *ptr); 2 ret$rn (;

+n the above exam"!e /


<e dec!ared two variab!es var1 and var2 A constant "ointer 0"tr1 was dec!ared and made to "oint var1 8ext, "tr is made to "oint var2& 9ina!!y, we try to "rint the va!ue "tr is "ointing to&

,o, in a nutshe!!, we assigned an address to a constant "ointer and then tried to change the address by assigning the address o$ some other variab!e to the same constant "ointer&

12

Lets now com"i!e the "rogram /


3 ,cc -@all constptr%c -o constptr constptr%cD +n f$nction EmainFD constptr%cD8D errorD assi,nment of read-only variable EptrF

,o we see that whi!e com"i!ing the com"i!er com"!ains about 0"tr1 being a read on!y variab!e& 'his means that we cannot change the va!ue "tr ho!ds& Hence we conc!ude that a constant "ointer which "oints to a variab!e cannot be made to "oint to any other variab!e&

Pointer to Constant
As evident $rom the name, a "ointer through which one cannot change the va!ue o$ variab!e it "oints is known as a "ointer to constant& 'hese ty"e o$ "ointers can change the address they "oint to but cannot change the va!ue ke"t at those address& A "ointer to constant is de$ined as /
const <type of pointer>* <name of pointer>

An exam"!e o$ de$inition cou!d be /


const int* ptr;

Lets take a sma!! code to i!!ustrate a "ointer to a constant /


#incl$de<stdio%h> int main(void) & int var) = (; const int* ptr = var); *ptr = ); printf(*/d-n*1 *ptr); ret$rn (; 2

+n the code above /


<e de$ined a variab!e var1 with va!ue 0 we de$ined a "ointer to a constant which "oints to variab!e var1 8ow, through this "ointer we tried to change the va!ue o$ var1 Ased "rint$ to "rint the new va!ue&

8ow, when the above "rogram is com"i!ed /


3 ,cc -@all constptr%c -o constptr constptr%cD +n f$nction EmainFD constptr%cD8D errorD assi,nment of read-only location E*ptrF

,o we see that the com"i!er com"!ains about 06"tr1 being read4on!y& 'his means that we cannot change the va!ue using "ointer 0"tr1 since it is de$ined a "ointer to a constant& 1@

Constant Pointer to a Constant


+$ you have understood the above two ty"es then this one is very easy to understand as its a mixture o$ the above two ty"es o$ "ointers& A constant "ointer to constant is a "ointer that can neither change the address its "ointing to and nor it can change the va!ue ke"t at that address& A constant "ointer to constant is de$ined as /
const <type of pointer>* const <name of pointer>

$or exam"!e /
const int* const ptr;

Lets !ook at a "iece o$ code to understand this /


#incl$de<stdio%h> int main(void) & int var) = (1var' = (; const int* const ptr = *ptr = ); ptr = var'; printf(*/d-n*1 *ptr); ret$rn (; 2

var);

+n the code above /


<e dec!ared two variab!es var1 and var2& <e dec!ared a constant "ointer to a constant and made it to "oint to var1 8ow in the next two !ines we tried to change the address and va!ue "ointed by the "ointer&

<hen the code was com"i!ed /


3 ,cc -@all constptr%c -o constptr constptr%cD +n f$nction EmainFD constptr%cD8D errorD assi,nment of read-only location E*ptrF constptr%cD9D errorD assi,nment of read-only variable EptrF

,o we see that the com"i!er com"!ained about both the va!ue and address being changed& Hence we conc!ude that a constant "ointer to a constant cannot change the address and va!ue "ointed by it&

12

Anda mungkin juga menyukai