0% found this document useful (0 votes)
67 views12 pages

Chapter 6 New

Download as doc, pdf, or txt
Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1/ 12

Chapter 6

Pointers The "Address Of" Operator


When you declare a variable in your programs, the computer reserves unused memory for that variable. This piece of memory is referenced by the variable name and must be unique. But what if we wanted to know the memory location for a certain variable?! We could ust use the & operator, otherwise known as the !address of! operator. "opy, compile and run this small program#
#include <stdio.h> int main() { int number = 0; printf("The address of the return 0; % ariable called number is 0!"p#n"$ &number);

$ote that the !address of! operator returns a he% number, hence the &% is added to tell the user that the following number is he%. 'ecall the way we used the !address of! operator in scanf&
scanf(""d"$ &!);

(ou can translate this to mean !take the inputted integer and take it to the address of the variable called % and store it!.

Left and Right Values


)lso known as l*values and r*values respectively. l*values can be on either side of the assignment operator where as r*values only appear on the right. +emory addresses and variable names are both l*values and r*values. Why? Because you can do this#
int 'idth = (; int number = 'idth; int )address; ,- .nitiali/e the pointer -, address 0 1number2
"opyright 3ogic 4ption 5vt. 3td.

)n integer like 67 is an r*value. Why? Because you can do this...


int len*th = +,;

... but not this#


+, = len*th;

Pointers
5ointers are variables which contain the memory address of another variable. When you declare a pointer, you state its type, then the 89'9:9'9$"9 operator, ), followed by the pointer name ;which must be names following those set of rules for naming variables<. To initiali/e the pointer to point to the contents of another variable, you use the !address of! operator. 9%ample#
#include <stdio.h> int main() { int ! = +0; int )pointer-to-!; pointer-to-! = &!; ,- int -pointer=to=% 0 1%2 is a simplified way -, printf;!The address of % is &%>p and the data it holds is >d?n!, 1%, -pointer=to=%<2 return &2 @

8onAt forget not to leave a space after the deference character!

Pointers and Arrays


!Why should we use pointers?!!!. (ou could simplify things a little by not using pointers. But the usefulness of pointers began to kick in when it came to arrays. 4ne less obvious fact is that the name of an array is a pointer, simply because the name points to the first element of that array. Try and picture this# when you initiali/e an array ;of si/e 6&, lets say<, the computer picks a row of 6& "4$B9"CT.D9 unused memory slots and stores the values in them. The name of the array refers to the base of the array, that is, the very first memory slot of that array ;which holds the first element<.
"opyright 3ogic 4ption 5vt. 3td.

Pointers Arithmetic
Bo the name of an array is a pointer. Bo what?! Well, we can make use of pointers if we perform pointer arithmetic. Buppose we have a pointer to an integer variable. Then if we increment it by 6, it would point to another variable in the computerAs memory. When we increment it by 6, it tells the computer to move forward 7 bytes ;or however big an integer is< to another memory slot. )nd decrementing works too. Bo do the arithmetic assignment operators. But wait a minute, remember that an array takes up consecutive memory slots. That means that if we increment a pointer, it points to the ne%t element in the array! 3ikewise, if we decrement a pointer, it points to the previous element. Take a look at this#
#include <stdio.h> int main() { int )ptr; int arra./nts0+01 = {+$,$($2$3$4$5$6$7$+0%; ptr = arra./nts; printf("The pointer is pointin* to the first arra. element$ 'hich is "d.#n"$ )ptr); printf("8et9s increment it.....#n"); ptr::; printf(";o' it should point to the ne!t element$ 'hich is "d.#n"$ )ptr); printf("<ut suppose 'e point to the (rd and 2th& "d "d.#n"$ )(ptr:+)$ )(ptr:,)); ptr:=,; printf("=o' about s>ippin* the ne!t 2 to point to the 6th? The 6th is "d.#n"$ )(ptr:=2)); ptr@@; printf("Aid / miss out m. luc>. number "d?B#n"$ )(ptr::)); printf("<ac> to the 6th it is then..... "d.#n"$ )ptr); % return 0;

Eust as with normal arithmetic, you should know the effects pre*incrementing and pre* decrementing have, as opposed to post*incrementing and post*decrementing. )nd watch those brackets! (ou can also change array elements using pointers#
"opyright 3ogic 4ption 5vt. 3td.

#include <stdio.h> int main() { char )ptr; char arra.Chars061 = {9D9$9r9$9i9$9e9$9n9$9d9$9s9$9#09%; ptr = arra.Chars; printf("The arra. reads "s.#n"$ arra.Chars); printf("8et9s chan*e it..... "); )ptr = 9f9; printf(" no' it reads "s.#n"$ arra.Chars); printf("The (rd character of the arra. is "c.#n"$ )(ptr:=,)); printf("8et9s chan*e it a*ain..... "); )(ptr @ +) = 9 9; printf(";o' it reads "s.#n"$ arra.Chars); return 0; %

Passing Arrays to Functions


Bometimes itAs inconvenient and inefficient to pass lots of arguments to functions. Gowever, if the arguments are of the same type, we can store them in an array and then pass the array to the functions. "heck this out#
#include <stdio.h> int add;umbers(int fi e;umbers01); ,- declare function -, int main;< H int arrayIJK2 int i2 printf;!9nter J integers separated by spaces# !<2 for;i0& 2 iLJ 2 iMM< scanf;!>d!, 1arrayIiK<2 printf;!?nThere sum is# >d!, add$umbers;array<<2
"opyright 3ogic 4ption 5vt. 3td.

return &2 @ int add$umbers;int five$umbersIK< ,- define function -, H int sum 0 &2 int i2 for;i0& 2 iLJ 2 iMM< sumM0five$umbersIiK2 return sum2 @

$otice that the si/e of the array is blank in both the function declaration and definition * the compiler works it out for you. )lso, when you call the function, pass on the name of the array * that is, the address of the first element of that array.

Passing Multidimensional Arrays to Functions


This is similar to passing 68 arrays but, in the function declarations you must specify all the dimension si/es ;but the leftmost one is optional<. 9%ample#
#include <stdio.h> oid printErra.(int arra.01021); ,- declare function -, int main;< H int arrayIFKINK 0 H&,6,7,F,N,J,O,P,Q,R,6&,66@2 print)rray;array<2 @ void print)rray;int arrayIKINK< ,- define function -, H int i, 2 for;i0& 2 iLF 2 iMM< H for; 0& 2 LN 2 MM< printf;!>7d !, arrayIiKI K<2 printf;!?n!<2 @ return &2 @

"opyright 3ogic 4ption 5vt. 3td.

Passing Pointers to Functions


5assing entire arrays to functions is a little inefficient. Bo passing pointers to functions is much efficient. .tAs similar to passing arrays, as youAll see#
#include <stdio.h> int add;umbers(int )pointer-to-arra.); ,- declare function -, int main;< H int arrayIJK2 int i, -array5ointer2 array5ointer0 array2 printf;!9nter J integers separated by spaces# !<2 for;i0& 2 iLJ 2 iMM< scanf;!>d!, array5ointerMi<2 printf;!?nThere sum is# >d!, add$umbers;array5ointer<<2 return &2 @ int add$umbers;int -pointer=to=array< ,- define function -, H int sum 0 &2 int i2 for;i0& 2 iLJ 2 iMM< sumM0-;pointer=to=array M i<2 return sum2 @

)gain, be careful with your pointer arithmetic and your usage of the dereference operator. (ou can only get better with practice.

Arrays of Pointers
4kay, this is when things get comple%. .tAs possible to have an array of pointers, which is ust an array with variables that contain memory addresses of other variables. Try and figure out this#
#include <stdio.h> int main() { int intErra.0(1 = {+$,$(%;
"opyright 3ogic 4ption 5vt. 3td.

int i; int )ptr+; ptr6 0 int)rray2 ,- initiali/e a pointer -,

int -pointer)rrayIFK 0 H ;ptr6< , ;ptr6M6<, ;ptr6M7< @2 for;i0& 2 iLF 2 iMM< H printf;!The address of int)rrayI>dK is &%>p.....?n!, i , pointer)rrayIiK<2 printf;!..... and holds the value >d.?n!, -pointer)rrayIiK<2 @ return &2 @

$ote that pointerErra. was intiali/ed with F memory addresses of the array containing F numbers, followed by print out some info. $otice that pointerErra.0i1 is a reference to an array element ;and so returns an element< where as )pointerErra.0i1 tells the computer that pointerErra.0i1 is a pointer and should return the value that is being pointed to. )lso, as youAll see in the ne%t section, strings are also character pointers. Bo you can have an array of strings. But to do this you must have a pointer to an array of pointers. 3etAs look at this e%ample#
#include <stdio.h> oid printFtrin*s+(char ))pointer); ,- declare function -, int main;< H char -pointer)rrayINK 0 H !+onday morning! , !O)+! , !Bunrise! , !'aining!@2 printBtrings6;pointer)rray<2 return &2 @ void printBtrings6;char --pointer< ,- function definition -, H int i2 for;i0& 2 iLN 2 iMM< printf;!>s?n!, pointerIiK<2 @ pointerErra.

is a pointer to an array of char pointers. Bo, in some ways, pointerErra. points P

"opyright 3ogic 4ption 5vt. 3td.

twice * once to the array, and within the array, each string is being pointed to. This is why 7 deference operators are placed in the parameters part of the function declaration and definition. But instead, if you pass a char pointer ;in other words, an array element< as your argument.....
#include <stdio.h> oid printFtrin*s,(char )pointer); ,- declare function -, int main;< H char -pointer)rrayINK 0 H !+onday morning! , !O)+! , !Bunrise! , !'aining!@2 printBtrings7;pointer)rrayI&K<2 printBtrings7;pointer)rrayI6K<2 printBtrings7;pointer)rrayI7K<2 printBtrings7;pointer)rrayIFK<2 return &2 @ void printBtrings7;char -pointer< ,- function definition -, H printf;!>s?n!, pointer<2 @

..... youAd have to use one dereference operator in the function declaration and definition. This is because that an array element only points to one memory location and that is that of a string. $otice we had to call function N times to print out all the words.

Pointing to Functions
When it came to Windows programming, we have to initiali/e a pointer to a function. Bimple really, take a look at this#
#include <stdio.h> int add(int !$ int .); ,- declare function -, int main;< H int %0O, y0R2 int ;-ptr<;int, int<2 ,- declare pointer to function-, ptr 0 add2 ,- set pointer to point to !add! function -,

printf;!>d plus >d equals >d.?n!, %, y, ;-ptr<;%,y<<2 ,- call function using pointer -, return &2
"opyright 3ogic 4ption 5vt. 3td.

@ int add;int %, int y< ,- function definition -, H return %My2 @

Eust remember to enclose the function pointer with brackets when declaring it. $otice that only the argumentsA types are included in the parameters in the pointer declaration, )nd adding variable names in there is optional, so this would still compile#
int ()ptr)(int !$ int .);

4r even this#
int ()ptr)(int a$ int b);

)lso, the type of the pointer has to match that of the function itAs pointing to.

Memory Allocation
(our computerAs memory is a resource * it can run out. The memory usage for program data can increase or decrease as your program runs. Cp until this point, the memory allocation for your program has been handled automatically when compiling. Gowever, sometimes the computer doesnAt know how much memory to set aside ;for e%ample, when you have an unsi/ed array<. To use the N functions discussed in this section, you must include the stdlib.h header file.

malloc()
This is one of the functions you can use to allocate memory dynamically. .t takes one argument * the number of bytes you wish to allocate. .t returns a void pointer if the allocation was successful, other a $C33 pointer is returned. (ou can use this fact to terminate a program, should malloc fail.

free()
When youAve finished with the allocated memory ;for e%ample, after printing out an array<, you can free it with this function. .t takes one argument * the pointer to the allocated memory. GereAs an e%ample that uses malloc and free#
#include <stdio.h>
"opyright 3ogic 4ption 5vt. 3td.

#include <stdlib.h> int main() { int number; int )pointer; int i; printf("=o' man. numbers 'ould .ou li>e displa.? "); scanf(""d"$ &number); pointer = (int))malloc(number)siGeof(int)); ,- allocate memory -, ,- need to coerse * pointer is of type int- but void pointer returned by malloc -, if;pointer!0$C33< H for;i0& 2 iLnumber 2 iMM< -;pointerMi< 0 i2 for;i0number 2 iS& 2 i**< printf;!?n >d!, -;pointerMnumber*i<<2 ,- print out in reverse order -, free;pointer<2 ,- free allocated memory -, return &2 ,- /ero for !success! -, @ else H printf;!?n+emory allocation failed * not enough memory.?n!<2 return 62 ,- one of abnormal program termination -, @ @

3et me take this opportunity that you have to coerse the void pointer returned from malloc into an int) ;or whatever type< because both sides of the assignment operator must be of the same type.

calloc()
This is another function that allows you to allocate memory. .t takes 7 arguments * the number of variables you want memory for, and the si/e of the variablesA type. 3ike malloc, calloc returns a pointer if the allocation is successful, else it returns a $C33 pointer. )lso, the memory allocated using calloc is always initiali/ed to /ero, where as with malloc, the initial value could be anything. 9%ample#
#include <stdio.h> #include <stdlib.h>
"opyright 3ogic 4ption 5vt. 3td.

6&

int main() { double )calloc+$ )calloc,$ )malloc+$ )malloc,; int i; calloc+ = (double))calloc(($ siGeof(double)); ,- donAt forget to coerse -, calloc7 0 ;double-<calloc;F, si/eof;double<<2 malloc6 0 ;double-<malloc;F - si/eof;double<<2 malloc7 0 ;double-<malloc;F - si/eof;double<<2 if;calloc6!0$C33 11 calloc7!0$C33 11 malloc6!0$C33 11 malloc7!0$C33< H for;i0& 2 iLF 2 iMM< H printf;!calloc6I>dK holds >&J.Jf, !, i, -;calloc6Mi<<2 printf;!malloc6I>dK holds >&J.Jf?n!, i, -;malloc6Mi<<2 printf;!calloc7I>dK holds >&J.Jf, !, i, -;calloc7Mi<<2 printf;!malloc7I>dK holds >&J.Jf?n!, i, -;malloc7Mi<<2 @ free;calloc6<2 free;calloc7<2 free;malloc6<2 free;malloc7<2 return &2 @ else H printf;!$ot enough memory?n!<2 return 62 @ @

realloc()
Bay youAve allocated memory space for J variables, using a pointer like ptr. Then this would be an illegal statement#
)(ptr:3) = (,;

.t would still compile but the assigned value can be anything. This is because that memory slot has not been allocated. Think of it like this# the first memory slot if the one the pointerAs pointing to, i.e. )(ptr:0). Then you can go to the ne%t one, which is )(ptr:+) and so on. Bo )(ptr:2) is the last one. Bo if we wanted to allocate more memory so that we can write )(ptr:3), we can use realloc. This function takes 7 arguments. The first is a pointer, the second is the new total number of bytes ;itAs best to use the siGeof operator here like in the e%ample below<. )nd a void pointer is returned if successful, otherwise itAs a $C33 pointer.
"opyright 3ogic 4ption 5vt. 3td.

66

9%ample#
#include <stdio.h> #include <stdlib.h> int main() { int )ptr; int i; ptr = (int))calloc(3$ siGeof(int)); if(ptrB=;H88) { )ptr = +; )(ptr:+) = ,; )(ptr:,) = 2; )(ptr:() = 6; )(ptr:2) = +4; ,- -;ptrMJ< 0 F72 illegal -, ptr 0 ;int-<realloc;ptr, P-si/eof;int<<2 if;ptr!0$C33< H -;ptrMJ< 0 F72 ,- now itAs legal! -, -;ptrMO< 0 ON2 for;i0& 2 iLP 2 iMM< printf;!ptrI>dK holds >d?n!, i, -;ptrMi<<2 realloc;ptr,&<2 ,- same as free;ptr<2 * ust fancier! -, return &2 @ else H printf;!$ot enough memory * realloc failed.?n!<2 return 62 @ @ else H printf;!$ot enough memory * calloc failed.?n!<2 return 62 @ @

"opyright 3ogic 4ption 5vt. 3td.

67

You might also like