Chapter 6 New
Chapter 6 New
Chapter 6 New
$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!.
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 @
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; %
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.
)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 -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.
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.
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 @ @
67