Pointers into other frames Ready
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

Passing an address

C always passes arguments by value: the function gets copies. To let a function change a variable of the caller, pass the variable's address (&x) and declare the parameter as a pointer (int *p). The function then writes through the pointer (*p = …) straight into the caller's memory. This is how C does "call by reference" — and why scanf needs &.

void twice(int *p)        // p receives an address
{
    *p = *p * 2;          // changes the caller's variable
}

int x = 5;
twice(&x);                // send the address of x
printf("%d", x);         // 10
By value vs by address
void f(int n) void f(int *p)
Call f(x) f(&x)
The function gets a copy of the value a copy of the address
Can it change x? No Yes: *p = …
Typical use inputs outputs, swap, big data
Example square(x) scanf("%d", &x)

Call by reference

  1. The caller writes &x to send where x is.
  2. The parameter is a pointer: void f(int *p).
  3. Inside, *p is the caller's x: read it or assign to it.
  4. Changing p itself (p = …) does not affect the caller — only *p does.
  5. Arrays are always passed this way (Module 26): a[i] in the function is the caller's element.

Several results

  1. return gives back only one value.
  2. For more results, pass the address of a variable for each one.
  3. The function fills them: *quotient = a / b; *remainder = a % b;
  4. These are called output parameters.
  5. Many library functions work this way, e.g. scanf fills the variables you pass.

Rules for safe pointers

  1. Never return the address of an ordinary local variable — it dies with the frame.
  2. Returning the address of a static, a global or malloc'd memory is fine.
  3. Use const int *p for a parameter the function must only read.
  4. Check pointer parameters for NULL when a caller might pass NULL.
  5. Watch the precedence: (*p)++ increments the value; *p++ moves the pointer.
Walkthrough

Minimum and maximum in one call, and a running total

Every line, explained.

1 #include <stdio.h>
2
3 void minMax(const int a[], int n, int *min, int *max) Two output parameters.
4 {
5 *min = *max = a[0]; Start both at the first element.
6 for (int i = 1; i < n; i++) {
7 if (a[i] < *min) *min = a[i];
8 if (a[i] > *max) *max = a[i];
9 }
10 }
11
12 void addTo(int *total, int amount)
13 {
14 *total += amount; Changes the caller's variable.
15 }
16
17 int main(void)
18 {
19 int v[] = {7, 2, 9, 4};
20 int lo, hi; Filled by minMax.
21 minMax(v, 4, &lo, &hi);
22 printf("min %d, max %d\n", lo, hi); Prints min 2, max 9
23 int sum = 0;
24 addTo(&sum, 5);
25 addTo(&sum, 10);
26 printf("sum %d\n", sum); Prints sum 15
27 return 0;
28 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Forgetting the & in the call

✗ Wrong
swap(x, y);       // sends values
✓ Right
swap(&x, &y);

The function expects addresses. With values, the compiler warns and the program writes to random memory.

Changing the pointer instead of the value

✗ Wrong
void reset(int *p) { p = 0; }    // p = NULL
✓ Right
void reset(int *p) { *p = 0; }   // the int becomes 0

Without * you only change the local copy of the address.

*p++ instead of (*p)++

✗ Wrong
void inc(int *p) { *p++; }   // moves p
✓ Right
void inc(int *p) { (*p)++; }

++ binds tighter than *: *p++ means *(p++). The brackets make it increment the value.

Returning the address of a local

✗ Wrong
int *make(void) { int n = 5; return &n; }
✓ Right
int make(void) { return 5; }   // or malloc / static

n disappears when make returns; the caller gets a dangling pointer.

Using an output parameter before it is set

✗ Wrong
int q;
printf("%d", q);   // garbage
divide(17, 5, &q, &r);
✓ Right
int q, r;
divide(17, 5, &q, &r);
printf("%d", q);

q gets its value inside divide — read it only after the call.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

void f(int *p) { *p = 7; } — int x = 1; f(&x); What is x?

Question 2

Why does scanf("%d", &n) need the &?

Question 3

void g(int *p) { (*p)++; } — int x = 4; g(&x); g(&x); What is x?

Question 4

Which is the safe one to return from a function?

Question 5

How can one function give back a quotient AND a remainder?

Assessment

Pointers & Functions quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.