A pointer is a variable that contains the memory address of another variable, called the pointee.
Creating Pointers
Pointers are declared as any other variable, except that an asterisk (*) is placed between the data type and the pointer’s name. The data type determines what type of memory it will point to.
int* p; /* pointer to an integer */
int *q; /* alternative syntax */
A pointer can point to a variable of the same type by prefixing that variable with an ampersand, in order to retrieve its address and assign it to the pointer. The ampersand is known as the address-of operator (&).
int i = 10;
p = &i; /* address of i assigned to p */
Dereferencing Pointers
The pointer now contains the memory address to the integer variable. Referencing the pointer will retrieve this address. To obtain the actual value stored in that address, the pointer must be prefixed with an asterisk, known as the dereference operator (*).
printf("Address of i: %p \n", p); /* ex. 0017FF1C */
printf("Value of i: %d", *p); /* 10 */
When writing to the pointer the same method is used. Without the asterisk the pointer is assigned a new memory address, and with the asterisk the actual value of the variable pointed to will be updated.
p = &i; /* address of i assigned to p */
*p = 20; /* value of i changed through p */
If a second pointer is created and assigned the value of the first pointer, it will then get a copy of the first pointer’s memory address.
int* p2 = p; /* copy address stored in p */
Pointing to a Pointer
Sometimes it can be useful to have a pointer that can point to another pointer. This is done by declaring a pointer with two asterisks and then assigning it the address of the pointer that it will reference. This way, when the address stored in the first pointer changes, the second pointer can follow that change.
int** r = &p; /* pointer to pointer */
Referencing the second pointer now gives the address of the first pointer. Dereferencing the second pointer gives the address of the variable, and dereferencing it again gives the value of the variable.
printf("Address of p: %p \n", r); /* ex. 0017FF28 */
printf("Address of i: %p \n", *r); /* ex. 0017FF1C */
printf("Value of i: %d", **r); /* 20 */
Null Pointer
A pointer should be set to zero when it is not assigned to a valid address. Such a pointer is called a
null pointer
. Doing this allows you to check whether the pointer can be safely dereferenced, because a valid pointer will never be zero.
int* p = 0; /* null pointer */
The constant NULL can also be used to signify a null pointer. NULL is typically defined as zero in C, making the choice of which to use a matter of preference. The constant is defined by several standard library files, including stdio.h and stddef.h.
#include <stdio.h>
/* ... */
int* p = NULL; /* null pointer */