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.