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.
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.
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.
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 */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.
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?
Why this lesson exists
Syllabus mapping
Pointers and the Indirection Operator
Maps to course outcome CO5.