Pointers in C |
Study your text (the Weiss book), Sections 6.1-6.5, pages 123-134.
"mental trick" - ampersand means address |
Consider:
Address example: address.c | |
---|---|
#include <stdio.h> int main() { int a = 13; int b = 45; printf("a = %i; address of a = %u \n", a, &a); printf("b = %i; address of b = %u \n", b, &b); } | |
Execution | |
% cc -o address address.c % address a = 13; address of a = 3221222552 b = 45; address of b = 3221222548 |
The star, *, is used for two purposes:
int * ptr = NULL; int * numPtr = NULL; char * chPtr = NULL;
By initializing pointers to NULL, you avoid accessing garbage and potentially doing bad things to important memory postitions. An error check can now be useful by the following
if (ptr == NULL) { //code for what you do when are pointing to nothing } else...
or
if (ptr != NULL) { //code for what you want to do } else...
After a pointer is defined, the operator will access what is stored in the memory position it points to.
int a = 4; int b = 5; int * ptr = NULL; ptr = &a; // this makes ptr "point to" the memory position designated a b = *ptr; // this assigns what is stored in the memory position "pointed to" by ptr to b. // so b == 4.
"mental trick" - star means storage Use the star to
|
int * a, b, c; // b and c are not pointers, they're integers!!! Properly, int * a, * b, * c; &num = ptr; // this tries to change the address of a variable ptr = num; // this tries to assign the value stored in num to ptr (which is an address) *ptr = tptr; // this tries to assign the address of tptr to the storage of ptr ptr = *tptr; // this tries to assign what is stored in tptr to a pointer
Pointer examples: pointers.c | |
---|---|
/* pointers.c: pointer examples */ #include <stdio.h> int main() { int x; /* x can hold an int */ int *xp; /* xp is a pointer to an int */ /* xp can hold the address of an int */ xp = &x; /* xp points to x; xp holds the address of x */ /* this uses the address of operator & */ /* at this point xp has a value, but x is not initialized */ *xp = 23; /* same as setting x = 23 */ /* *xp refers the the location given by x */ /* this uses the dereference operator * */ /* Notice that x == *&x always */ printf("x: %i\n", x); /* prints 23 */ printf("*xp: %i\n", *xp); /* prints 23 */ printf("*&x: %i\n", *&x); /* prints 23 */ (*xp)++; /* increments what xp points to, that is, x */ /* need parens above; *xp++ is *(xp++), increments the address */ printf("x: %i\n", x); /* prints 24 */ printf("*xp: %i\n", *xp); /* prints 24 */ printf("*&x: %i\n", *&x); /* prints 24 */ } | |
Execution | |
% cc -o pointers pointers.c % pointers x: 23 *xp: 23 *&x: 23 x: 24 *xp: 24 *&x: 24 |
Notice that
Pointers to pointers: ptop.c | |
---|---|
/* ptop.c: pointers to pointers */ #include <stdio.h> int main() { /* 53 == x <--- xp <--- xpp <--- xppp <--- xpppp */ int x; /* x is an int*/ int *xp = &x; /* xp is a pointer to an int*/ int **xpp = &xp; /* xpp is (a pointer to)2 an int*/ int ***xppp = &xpp; /* xppp is (a pointer to)3 an int*/ int ****xpppp = &xppp; /* xpppp is (a pointer to)4 an int*/ ****xpppp = 53; printf("%i %i %i %i %i\n", x, *xp, **xpp, ***xppp, ****xpppp); printf("%i %i %i %i %i\n", *&x, *&*xp, ***&xpp, *&*&x, ***&*&xpp, ***&*&*xppp); /* printf("%i\n", **&&x); ERROR */ } | |
Execution | |
% cc -o ptop ptop.c % ptop 53 53 53 53 53 53 53 53 53 53 |
Notice that one can always write &z for any variable z, however it is declared, giving the address of z. The resulting address is a constant, and it does not have an addrss, so that &&z is always illegal.