Skip to content
Laviyx Learn

Try

C course menu

Pointers in C: Addresses, the & and * Operators, and NULL

A clear introduction to pointers in C: what memory addresses are, declaring pointers, the address-of operator & and the dereference operator *, changing a variable through a pointer, pointer types and sizes, NULL pointers, and the most common pointer mistakes.

Intermediate6 min readUpdated
On this page

Every variable lives somewhere in memory, and every location in memory has a numeric address. A pointer is a variable that stores an address. Pointers are what make C powerful: they let functions change your data, let you work with arrays and strings efficiently, and let you build structures such as linked lists.

Addresses and &#

The address-of operator & gives a variable's address. %p prints an address (cast to void *):

C
int age = 21;
printf("value:   %d\n", age);
printf("address: %p\n", (void *)&age);
Output
value:   21
address: 000000000061FE1C

The address is different on every machine and often on every run, so this block's output is only an example.

Declaring a pointer and dereferencing it#

int *p declares p as a "pointer to int". The dereference operator * goes to the address stored in the pointer and reaches the value there:

C
int age = 21;
int *p = &age;         /* p holds the address of age */

printf("%d\n", *p);    /* read through the pointer */
*p = 22;               /* write through the pointer */
printf("%d\n", age);   /* age itself has changed */
printf("%d\n", p == &age);
Output
21
22
1

The same symbol * does two different jobs:

WhereMeaning
In a declaration: int *p;p is a pointer to int
In an expression: *p = 5;The value at the address in p

Pointer types#

A pointer's type says what kind of value is at the address, so the compiler knows how many bytes to read and how to interpret them. All object pointers on a given platform are usually the same size (8 bytes on 64-bit systems), whatever they point to:

C
double price = 99.5;
char grade = 'A';
double *pp = &price;
char *pg = &grade;

printf("%.1f %c\n", *pp, *pg);
printf("%zu %zu\n", sizeof pp, sizeof pg);
Output
99.5 A
8 8

(The sizes shown are from a 64-bit system.)

NULL#

NULL is a special pointer value that points to nothing. Use it to mean "no object yet" and check for it before dereferencing:

C
#include <stdio.h>

int main(void) {
    int *p = NULL;
    if (p == NULL) {
        printf("p points to nothing\n");
    }
    int x = 5;
    p = &x;
    if (p != NULL) {
        printf("p points to %d\n", *p);
    }
    return 0;
}
Output
p points to nothing
p points to 5

Dereferencing NULL is undefined behavior; on desktop systems it normally crashes the program with a segmentation fault (an "access violation" on Windows).

Common pointer mistakes#

  • Uninitialised pointers: int *p; *p = 5; writes to a random address. Initialise every pointer, to NULL if nothing else.
  • Dangling pointers: pointing to a variable that no longer exists, such as a local variable of a function that has returned (Pointers and Functions).
  • Type mismatch: double *d = &some_int; is an error-prone conversion that GCC warns about.

Practice#

Practice exercise

Declare int a = 10, b = 20; and a pointer int *p. Point p at a, add 5 through the pointer, then point it at b and double b through it. Print a and b.

Show solution
C
#include <stdio.h>

int main(void) {
    int a = 10, b = 20;
    int *p = &a;
    *p += 5;
    p = &b;
    *p *= 2;
    printf("a = %d, b = %d\n", a, b);
    return 0;
}
Output
a = 15, b = 40

Key takeaway#

Finished this lesson?