You are on page 1of 11

COMPUTER PROGRAMMING Module 4 Pointers A simple variable in a program is stored in a certain number of bytes at a particular memory location, or address,

in the machine. Pointers are used in programs to access memory and manipulate addresses. The first things to do with pointers are to declare a pointer variable, set it to point somewhere, and finally manipulate the value that it points to. A simple pointer declaration looks like this: int *ip; The asterisk means that ip, the variable we re declaring, is not of type int, but rather of type pointer!to!int. Pointers "that is, pointer values# are generated with the $$address!of operator %, which we can also think of as the $$pointer!to operator. &e demonstrate this by declaring "and initiali'ing# an int variable i, and then setting ip to point to it: int i ( ); ip ( %i; The assignment e*pression ip ( %i; contains both parts of the $$two!step process : %i generates a pointer to i, and the assignment operator assigns the new pointer to the variable ip. +ow ip $$points to i, which we can illustrate with this picture:

i is a variable of type int, so the value in its bo* is a number, ). ip is a variable of type pointer!to!int, so the $$value in its bo* is an arrow pointing at another bo*. The contents!of operator * does not merely fetch values through pointers; it can also set values through pointers. &e can write something like *ip ( ,; which means $$set whatever ip points to to ,. Again, the * tells us to go to the location pointed to by ip, but this time, the location isn t the one to fetch from!!we re on the left!hand sign of an assignment operator, so *ip tells us the location to store to. The result of the assignment *ip ( , is that i s value is changed to ,, and the picture changes to:

What is a Pointer?

A pointer is a variable which contains the address in memory of another variable. &e can have a pointer to any variable type. The unary or monadic operator & gives the $$address of a variable . The indirection or dereference operator * gives the $$contents of an ob-ect pointed to by a pointer .

To declare a pointer to a variable do: int *pointer; NOTE: &e must associate a pointer to a particular type: .ou can t assign the address of a short int to a lon int, for instance. /onsider the effect of the following code: int * ( 0, y ( 1; int *ip; ip ( %*; y ( *ip; * ( ip; *ip ( 2; /onsider 3ig. 0. Assume for the sake of this discussion that variable * resides at memory location 044, y at 144 and ip at 0444. Note A pointer is a variable and thus its values need to be stored somewhere. 5t is the nature of the pointers value that is new.

!i " # Pointer$ %aria&les and Me'or( +ow the assignments * ( 0 and y ( 1 obviously load these values into the variables. ip is declared to be a pointer to an integer and is assigned to the address of * "%*#. 6o ip gets loaded with the value 044. +e*t y gets assigned to the contents of ip. 5n this e*ample ip currently points to memory location 044 !! the location of *. 6o y gets assigned to the values of * !! which is 0. &e have already seen that / is not too fussy about assigning values of different type. Thus it is perfectly le al "although not all that common# to assign the current value of ip to *. The value of ip at this instant is 044. 3inally we can assign a value to the contents of a pointer "*ip#. IMPORTANT: &hen a pointer is declared it does not point anywhere. .ou must set it to point somewhere before you use it. 6o ... int *ip; *ip ( 044; will generate an error "program crash77#. The correct use is: int *ip; int *; ip ( %*; *ip ( 044; &e can do integer arithmetic on a pointer: float *flp, *fl8; *flp ( *flp 9 04; 99*flp; "*flp#99; fl8 ( flp; NOTE: A pointer to any variable type is an address in memory !! which is a long integer address. A pointer is definitely +:T an integer. The reason we associate a pointer to a data type is so that it knows how many bytes the data is stored in. &hen we increment a pointer we increase the pointer by one $$block memory. 6o for a character pointer 99ch;ptr adds 0 byte to the address. 3or a float 99ip or 99flp adds < bytes to the address. /onsider a float variable "fl# and a pointer to a float "flp# as shown in 3ig. 1

!i " ) Pointer Arith'eti* Assume that flp points to fl then if we increment the pointer " 99flp# it moves to the position shown < bytes on. 5f on the other hand we added 1 to the pointer then it moves 1 +loat ,ositions i.e = bytes as shown in the 3igure. Passin ,ointers to !un*tion &hen / passes arguments to functions it passes them by value. There are many cases when we may want to alter a passed argument in the function and receive the new value back once to function has finished. / uses pointers e*plicitly to do this. 5n >call!by! reference>, instead of passing the value of a variable, the location number "or the address# of the variable is passed to a function. This will become >call!by!reference>. 5t is a way to pass address "reference# of variables to a function that then allows the body of the function to make changes to the value of the variables in the calling environment. ?et us try and write a function to swap variables around@ The usual function call: swap"a, b# &:+ T &:AB. Pointers provide the solution: Pass the address of the variables to the functions and access address of function. Thus our function call in our program would look like this: swap"%a, %b# The /ode to swap is fairly straightforward: void swap"int *p*, int *py# C int temp; temp ( *p*; D* contents of pointer *D *p* ( *py; *py ( temp; E Pointers and One -i'ensional Arra(s Pointers and arrays are very closely linked in /. /onsider the following:

int aF04G, *; int *pa; pa ( %aF4G; D* pa pointer to address of aF4G *D * ( *pa; D* * ( contents of pa "aF4G in this case# *D

!i " . Arra(s and Pointers To get somewhere in the array "3ig. 2# using a pointer we could do: *"pa 9 i# ( aFiG &AA+5+H: There is no bound checking of arrays and pointers so you can easily go beyond array memory and overwrite other things. / however is much more subtle in its link between arrays and pointers. 3or e*ample we can -ust type pa ( a; and aFiG i.e. %aFiG ( a 9 i. can be written as *"a 9 i#. instead of pa ( %aF4G

&e also e*press pointer addressing like this: paFiG ( *"pa 9 i#.

Iowever pointers and arrays are different: A pointer is a variable. We can do pa = a and pa++. An Array is not a variable. a = pa and a++ ARE ILLEGAL.

&e can now understand how arrays are passed to functions. When an arra( is ,assed to a +un*tion /hat is a*tuall( ,assed is its initial ele'ents lo*ation in 'e'or(. 6o: strlen"s# This is why we declare the function: strlen"%sF4G#

int strlen"char sFG#; An e8uivalent declaration is : int strlen"char *s#; since char sFG ( char *s. strlen"# is a standard library function that returns the length of a string. ?et s look at how we may write a function: int strlen"char *s# C char *p ( s; while "*p 7( $ #; p99; return p!s; E O,erations on Pointers Jynamic Kemory Allocation is a pretty uni8ue feature to / "amongst high level languages#. 5t enables us to create data types and structures of any si'e and length to suit our programs need within the program. &e will look at two common applications of this: dynamic arrays dynamic data structure e.g. linked lists

Kalloc, 6i'eof, and 3ree : The 3unction malloc is most commonly used to attempt to $$grab a continuous portion of memory. 5t is defined by: void *malloc"si'e;t,number;of;bytes# That is to say it returns a pointer of type void * that is the start in memory of the reserved portion of si'e number;of;bytes. 5f memory cannot be allocated a +L?? pointer is returned. 6ince a void * is returned the / standard states that this pointer can be converted to any type. The si'e;t argument type is an unsigned type. 6o: char *cp; cp ( malloc"044#; attempts to get 044 bytes and assigns the start address to cp. Also it is usual to use the si'eof"# function to specify the number of bytes: int *ip; ip ( "int *# malloc"044*si'eof"int##;

Some C compilers may re uire to cast t!e type of con"ersion. The "int *# means coercion to an integer pointer. /oercion to the correct pointer type is very important to ensure pointer arithmetic is performed correctly. It is good practice to use si#eof$% e"en if you &now t!e actual si#e you want '' it ma&es for de"ice independent $porta(le% code. si'eof can be used to find the si'e of any data type, variable or structure. 6imply supply one of these as an argument to the function. 6:: int i; struct /::AJ C float *,y,' E; typedef struct /::AJ PT; si'eof"int#, si'eof"i#, si'eof"struct /::AJ# and si'eof"PT# are all A//MPTAN?M 5n the above we can use the link between pointers and arrays to treat the reserved memory like an array. i.e we can do things like: ipF4G ( 044; or for"i(4;iO044;99i# scanf">Pd>,ip99#; &hen you have finished using a portion of memory you should always free"# it. This allows the memory freed to be aavailable again, possibly for further malloc"# calls. The function free"# takes a pointer as an argument and frees the memory to which the pointer refers. /alloc and Aealloc : There are two additional memory allocation functions, /alloc"# and Aealloc"#. Their prototypes are given below: void *calloc"si'e;t num;elements, si'e;t element;si'eE; void *realloc" void *ptr, si'e;t new;si'e#; Kalloc does not initialise memory "to 'ero# in any way. 5f you wish to initialise memory then use calloc. /alloc there is slightly more computationally e*pensive but, occasionally, more convenient than malloc. Also note the different synta* between calloc and malloc in that calloc takes the number of desired elements, num;elements, and element;si'e, element;si'e, as two individual arguments. Thus to assign 044 integer elements that are all initially 'ero you would do: int *ip; ip ( "int *# calloc"044, si'eof"int##; Aealloc is a function which attempts to change the si'e of a previous allocated block of memory. The new si'e can be larger or smaller. 5f the block is made larger then the old contents remain unchanged and memory is added to the end of the block. 5f the si'e is made smaller then the remaining contents are unchanged. 5f the original block si'e cannot be resi'ed then realloc will attempt to assign a new block of memory and will copy the old block contents. +ote a new pointer "of different value# will conse8uently be returned. .ou must use this new value. 5f new memory cannot be reallocated then realloc returns +L??.

Thus to change the si'e of memory allocated to the *ip pointer above to an array block of )4 integers instead of 044, simply do: ip ( "int *# calloc" ip, )4#; Pointers and Multi -i'ensional Arra(s &e should think of multidimensional arrays in a different way in /: A )* array is really a +* array, eac! of w!ose elements is itself an array Ience aFnGFmG notation. Array elements are stored row by row. &hen we pass a 1J array to a function we must specify the number of columns !! the number of rows is irrelevant. The reason for this is pointers again. / needs to know how many columns in order that it can -ump from row to row in memory. /onsiderint aF)GF2)G to be passed in a function: &e can do: f"int aFGF2)G# C.....E or even: f"int "*a#F2)G# C.....E &e need parenthesis "*a# since FG have a higher precedence than * 6o: int "*a#F2)G; declares a pointer to an array of 2) ints. int *aF2)G; declares an array of 2) pointers to ints. +ow lets look at the difference between pointers and arrays. 6trings are a common application of this. /onsider: char *nameF04G; char AnameF04GF14G; &e can legally do nameF2GF<G and AnameF2GF<G in /. Iowever Aname is a true 144 element 1J char array. access elements via

)-.row + col + (ase/address in memory. name has 04 pointer elements. NOTE: 5f each pointer in name is set to point to a 14 element array then and only then will 144 chars be set aside "9 04 elements#. The advantage of the latter is that each pointer can point to arrays be of different length. More on Multi0-i'ensional Arra(s and Pointers Qdefine A:&6 ) Qdefine /:?6 04 int multiFA:&6GF/:?6G; we can access individual elements of the array 'ulti using either: multiFrowGFcolG or *"*"multi 9 row# 9 col# 3or e*ample QincludeOstdio.hR void main"# C int *F2GF)G(C C0,1,2,<,)E, CS,,,=,T,04E, C00,01,02,0<,0)E E,*n; n(%*; printf">Un/ontent of 2rd row,1nd column ( Pd>,*"*"*91#90##; printf">Un/ontent of 1nd row,0st column ( Pd>,*"*"*90###; E :utput will be /ontent of 2rd row,1nd column (01 /ontent of 1nd row,0st column ( S To understand more fully what is going on, let us replace *"multi 9 row# with 1 as in: *"V 9 col#

+ow, from this we see that 1 is like a pointer since the e*pression is de!referenced and we know that *ol is an integer. Iere the arithmetic being used is of a special kind called >pointer arithmetic> is being used. That means that, since we are talking about an integer array, the address pointed to by "i.e. value of# 1 2 *ol 2 # must be greater than the address 1 2 *ol by and amount e8ual to si3eo+4int5. 6ince we know the memory layout for 1 dimensional arrays, we can determine that in the e*pression 'ulti 2 ro/ as used above, 'ulti 2 ro/ 2 # must increase by value an amount e8ual to that needed to >point to> the ne*t row, which in this case would be an amount e8ual to CO67 * si3eo+4int5. That says that if the e*pression *4*4'ulti 2 ro/5 2 *ol5 is to be evaluated correctly at run time, the compiler must generate code which takes into consideration the value of CO67, i.e. the 1nd dimension. Necause of the e8uivalence of the two forms of e*pression, this is true whether we are using the pointer e*pression as here or the array e*pression 'ulti8ro/98*ol9. Thus, to evaluate either e*pression, a total of ) values must be known: 0. The address of the first element of the array, which is returned by the e*pression 'ulti, i.e., the name of the array. 1. The si'e of the type of the elements of the array, in this case si3eo+4int5. 2. The 1nd dimension of the array <. The specific inde* value for the first dimension, ro/ in this case. ). The specific inde* value for the second dimension, *ol in this case. Pointers To 7tru*tures As a pointer points to an int, float etc, the pointer points to a struct "structured data type#. ?ike other pointers, structure pointers are declared by placing * in front of a structure variable s name. The declaration is shown in the following e*ample. static struct customer c0(. C 040,>george>E; struct customer *ptr; ptr(%c0; printf">Pd Ps>,ptr!Rid,ptr!Rname#; As the pointer points to the structure elements, a operator!R, called arrow operator is used. 5t cannot use ptr .id, as ptr is not a structure variable. The !R operator consists of the minus sign followed by a greater than sign. The arrow is used in place of the dot operator when you .are accessing a structure member through a pointer to the structure. The operator always needs a pointer to structure on the left hand side. Aemember, use the dot operator to access structure elements when operating on the structure itself. &hen you have a pointer to a structure, use the arrow operator. There are two primary uses for structure pointers, to pass a structure to a function using a call by reference and to create linked lists and other dynamic data structures that rely on dynamic allocation. 5t is possible to pass the address of the structure variable to a function. To find the address of a structure variable, place % operator before the structure s name. A structure can be declared outside the main function provided a pointer points to the structure, which is passed by a function, which is called in the main function. &hen a pointer to a structure is passed to a function, only the address of the structure is pushed on

the stack. This makes for very fast function calls. Passing a pointer makes it possible for the function to modify the contents of the. structure used as the argument. !un*tions Returnin Pointers As the way, functions return an int, a float, or any data type, the same way it return a pointer. To make a function return a pointer, it has to be e*plicitly mentioned in the calling! function as well as in the function declaration. Iere is an e*ample: main"# C int *p; int *func"#; p ( func:; E; int *func"# C int *(044; return "%*#; E 5n the above e*ample, an integer pointer can be returned from a function. The function returning pointers finds more useful while handling strings like copying a string to another, concatenating two strings etc.

Also,study pointer to pointer

You might also like