Skip to content
FollowtheDamnCode

Call by Value vs Call by Reference

Why a swap function needs pointers.

5 minute read

Big idea

C passes copies into functions. To let a function change the caller's variables, pass their addresses instead β€” that's how swap works.

The problem

Here's a swap function that doesn't work:

Fix the bug: swap should really swap
#include <stdio.h>

void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

int main(void) {
    int x = 1, y = 2;
    swap(x, y);
    printf("x=%d y=%d\n", x, y);
    return 0;
}
output
x=2 y=1

Run and edit it in the app.

swap got copies of x and y. It swapped its copies perfectly β€” then the copies were thrown away. That's call by value.

The fix: pass addresses

Give swap the addresses, and have it write through them:

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

swap(&x, &y);

C still passes copies β€” but now they're copies of addresses, and a copy of an address still leads to the original house. This is how C does call by reference.

Watch the two side by side

Returning more than one result

return gives back one value. Pointer parameters let a function hand back several β€” this is exactly why scanf needs &:

Minutes and seconds, two results at once
#include <stdio.h>

void split_time(int total, int *minutes, int *seconds) {
    *minutes = total / 60;
    *seconds = total % 60;
}

int main(void) {
    int m, s;
    split_time(135, &m, &s);
    printf("%d:%02d\n", m, s);
    return 0;
}
output
2:15

Run and edit it in the app.

%02d pads with a zero to two digits, so 5 seconds prints as 05.

Think of it like

Photocopying a form vs. giving someone your original. Scribble on a photocopy and your original is untouched (by value). Give them the address of your filing cabinet, and they can change the real thing (by reference).

πŸ•·οΈ Spidey-sense: Telling Aunt May "I'll be home at 6" doesn't change her clock. Giving her the address of the clock does. …She was not happy when I reset it.

Key terms

  • Call by value β€” The function gets copies; the caller's variables can't change.
  • Call by reference β€” The function gets addresses and can change the caller's variables. In C you do it with pointers.
  • Output parameter β€” A pointer parameter the function writes a result into.

Check yourself

Why doesn't void swap(int a, int b) swap the caller's variables?

How do you call void swap(int *a, int *b) on x and y?

Why does scanf need &?