Unit 2 · Lesson 520 minAcademic review pending

A variable that holds an address

A pointer stores where a value lives rather than the value itself. Two operators — & and * — are all you need to move between the two.

Choose explanation

After this lesson

You should be able to

  • Declare a pointer and make it point at an existing variable.
  • Use & to take an address and * to reach the value at that address.
  • Explain why a pointer has a type.
01

Address versus value

Every variable lives at some numbered location in memory. Think of a hostel: the room number is the address and the student inside is the value. A pointer is a variable that stores a room number rather than a student.

& means give me the address of. * in an expression means give me the value at. They undo each other: *&marks is just marks.

Reaching one variable two ways
int marks = 87;
int *p;          /* p can hold the address of an int */

p = &marks;      /* p now points at marks           */

printf("%d\n", marks);   /* 87 — the value          */
printf("%d\n", *p);      /* 87 — the value, via p   */

*p = 95;                  /* change marks through p  */
printf("%d\n", marks);   /* 95                      */
02

The star means two different things

In int *p; the star is part of the declaration — it says p is a pointer to int. In *p = 95; the star is the indirection operator — it says go to the address in p and use what is there. Same symbol, different jobs, and confusing them is the usual source of pointer bewilderment.

Read declarations from the variable outwards: p is a pointer, to an int. Written as int *p rather than int* p, the star visually attaches to p, which is where it belongs — int* a, b; declares one pointer and one plain int, which surprises almost everyone.

03

Why a pointer needs a type

An address alone does not say how many bytes to read or how to interpret them. int *p promises that four bytes starting there are an int; double *q promises eight bytes are a double. The type is how *p knows what to fetch.

Print an address with %p, not %d. An address is not an int and the sizes need not match.

Try it yourself

Declare an int and a pointer to it. Print the value directly, print it through the pointer, change it through the pointer, and print it directly again.

Need a hint?

You need & exactly once, when you first aim the pointer.

Check the worked solution

The last printf proves the point: count was never assigned to directly after initialisation, yet it reads 60. That is the whole idea of indirection, and it is what makes the next lesson's output parameters possible.

#include <stdio.h>

int main(void)
{
    int count = 42;
    int *p = &count;

    printf("Direct:        %d\n", count);   /* 42 */
    printf("Through p:     %d\n", *p);      /* 42 */
    printf("Address of it: %p\n", (void *) p);

    *p = 60;

    printf("Direct again:  %d\n", count);   /* 60 */

    return 0;
}

Quick check

After int a = 3; int *p = &a; *p = 8; what is a?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

Pointers and the Indirection Operator

Maps to course outcome CO5.