Pass by Reference (Pointers)
C does not have true reference parameters the way C++ does (with int &a). Instead, C simulates "pass by reference" by passing a pointer — the memory address of a variable — as the argument. The function can then follow that pointer back to the original variable and modify it directly.
Fixing swap With Pointers
Recall the broken swap from the previous page: it swapped its own local copies and had no effect on the caller. Here is the corrected version.
swap that actually works
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a; // dereference: read the value a points to
*a = *b; // write through a's pointer
*b = temp; // write through b's pointer
}
int main(void) {
int x = 1, y = 2;
swap(&x, &y); // pass the ADDRESSES of x and y
printf("x = %d, y = %d\n", x, y);
return 0;
}x = 2, y = 1
What Changed, Exactly
The pass-by-value rule from the previous page still holds perfectly here — a and b are still copies, and they are still local to swap. The difference is what is being copied: instead of copying the integers 1 and 2, we copy the addresses of x and y. Those copied addresses still point at the exact same memory that x and y occupy, so dereferencing them with *a and *b reads and writes the real variables in main.
At the call site | In the function definition | Meaning |
|---|---|---|
|
| Pass the address of a variable |
| — | "Address of x" — produces a pointer to x |
— |
| "Value pointed to by a" — dereference to read/write the original |
The Syntax, Piece by Piece
At the call site, prefix the variable with
&(the address-of operator) to get a pointer to it:swap(&x, &y).In the function definition, declare the parameter as a pointer with
*:void swap(int *a, int *b).Inside the function body, prefix the pointer parameter with
*(the dereference operator) to read or write the value it points to:*a = *b;.
When You Need This Pattern
Pass-by-reference via pointers is the standard C technique whenever you need a function to:
Modify one of the caller's variables directly (like swap).
Return more than one value, by writing results through several output-parameter pointers.
Avoid copying a large struct or array just to read it, by passing a pointer to it instead (often combined with
constto promise the function will not modify it).
Returning multiple values via output parameters
#include <stdio.h>
// Computes both quotient and remainder, "returning" two values
void divide(int dividend, int divisor, int *quotient, int *remainder) {
*quotient = dividend / divisor;
*remainder = dividend % divisor;
}
int main(void) {
int q, r;
divide(17, 5, &q, &r);
printf("17 / 5 = %d remainder %d\n", q, r);
return 0;
}