Pointers
The idea C is famous for: a variable that holds the address of another. Less scary than its reputation.
- Explain what an address and a pointer are
- Use
&to take an address and*to follow a pointer - Write a function that changes its caller's variables
Memory is one long row of bytes, and every byte has a number: its address. Every variable lives at some address. A pointer is simply a variable whose value is an address - it "points at" another variable. That is the whole idea; the rest is syntax.
Addresses with &
The & operator gives you the address of a variable. (You have already used it with scanf: &number told scanf where to write.) Addresses print with %p, and they will be different every time you run the program:
1#include <stdio.h>
2
3int main(void) {
4 int age = 30;
5 printf("age holds %d\n", age);
6 printf("age lives at %p\n", (void *)&age);
7 return 0;
8}Declaring and following a pointer
1#include <stdio.h>
2
3int main(void) {
4 int age = 30;
5 int *p = &age; // p holds the address of age
6
7 printf("%d\n", *p); // follow p: prints 30
8
9 *p = 31; // write through p
10 printf("%d\n", age); // age changed: prints 31
11 return 0;
12}30 31
Two different jobs for * - this is where most confusion comes from:
- In a declaration,
int *pmeans "p is a pointer to an int". - In an expression,
*pmeans "the thing p points at" - this is called dereferencing.
So *p = 31; does not change p at all. It goes to the address stored in p and writes 31 there - into age.
Why pointers: changing the caller's variables
Remember that functions get copies of their arguments. To let a function change the caller's variable, pass its address instead - the function gets a copy of the address, and a copy of an address still leads to the same place:
1#include <stdio.h>
2
3void swap(int *a, int *b) {
4 int temp = *a;
5 *a = *b;
6 *b = temp;
7}
8
9int main(void) {
10 int x = 1, y = 2;
11 swap(&x, &y);
12 printf("x = %d, y = %d\n", x, y);
13 return 0;
14}x = 2, y = 1
This is exactly how scanf works, and it is also how C functions "return" more than one value: the caller passes addresses for the results to be written into.
NULL
NULL is a special pointer value meaning "points at nothing". It is useful as a "no result" marker, and it is what you should set a pointer to when it has nothing valid to point at yet. Dereferencing NULL is undefined behavior - usually an immediate crash ("segmentation fault"). Check before you follow a pointer that might be NULL.
Pointers and arrays
An array name used in an expression turns into ("decays to") a pointer to its first element - which is why passing an array to a function passes an address. You can do pointer arithmetic: p + 1 points at the next element, not the next byte, because the compiler knows the element size. In fact, a[i] is defined as *(a + i).
1#include <stdio.h>
2
3int main(void) {
4 int values[] = {10, 20, 30};
5 int *p = values; // same as &values[0]
6
7 printf("%d\n", *p);
8 printf("%d\n", *(p + 1));
9 printf("%d\n", p[2]);
10 return 0;
11}10 20 30
Key takeaways
A pointer holds an address.
&xis the address ofx;*pis the value p points at.Pass addresses (
swap(&x, &y)) when a function must change its caller's variables.Initialize pointers (to a real address or
NULL), never dereferenceNULL, and never keep the address of a local variable after its function returns.
Lesson quiz
6 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write real C
These run for real. Write the program, press Run tests, and read what the compiler tells you - learning to read compiler messages is half of learning C.
Two results at once
Write void min_max(const int values[], int length, int *min, int *max) that stores the smallest and largest element through the two pointers. main reads a count and that many numbers, calls your function, and prints the results.
For 5 then 3 9 -2 7 4, the output is min=-2 max=9.
- Mixed values
- One value
Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Sign in to ask questions, help other learners, and earn XP for taking part.
Loading posts…