Call by Value vs Reference
Two ways to pass arguments
When you call a function and give it some data, C needs to decide how that data reaches the function. There are two mental models, and the difference between them decides whether the function can change your original variable or not:
- Call by value — the function gets a copy of the data. Your original is safe and unchanged.
- Call by reference — the function gets the address of the data, so it can reach back and change the original.
C uses call by value by default. Call by reference is done using pointers. Let's see both.
Call by value: works on a copy
Here the function receives a copy of a. Changing that copy does nothing to the original.
#include <stdio.h>
void change(int x) {
x = 100; // changes only the local copy
}
int main() {
int a = 5;
change(a);
printf("a = %d\n", a); // still 5
return 0;
}a = 5
Even though change set x = 100, the original a stayed 5 — because x was just a copy that disappeared when the function ended.
Call by reference: works on the original
Now we pass the address of a instead. The function receives it as a pointer and changes the value at that address.
#include <stdio.h>
void change(int *x) {
*x = 100; // changes the original via its address
}
int main() {
int a = 5;
change(&a); // pass the address of a
printf("a = %d\n", a); // now 100
return 0;
}a = 100
This time a became 100. The &a handed over a's address, and *x = 100 wrote directly into a's memory.
C is always call by value. "Call by reference" just means we pass a pointer (an address) by value — and because that address still points to the original, the function can change it.
The classic proof: swapping two numbers
This is the example every interviewer loves, because it shows the difference perfectly. First, the broken version with call by value:
#include <stdio.h>
void swap(int x, int y) { // copies only
int t = x; x = y; y = t;
}
int main() {
int a = 5, b = 9;
swap(a, b);
printf("a = %d, b = %d\n", a, b); // unchanged!
return 0;
}a = 5, b = 9
Nothing swapped — the function only shuffled its local copies. Now the working version with call by reference:
#include <stdio.h>
void swap(int *x, int *y) { // addresses
int t = *x; *x = *y; *y = t;
}
int main() {
int a = 5, b = 9;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b); // swapped!
return 0;
}a = 9, b = 5
By passing addresses, the function reaches the real a and b and swaps them for good. This single comparison is the heart of the topic.
Call by value vs call by reference
| Point | Call by value | Call by reference |
|---|---|---|
| What is passed | A copy of the value | The address (a pointer) |
| Original variable | Cannot change | Can change |
| Called with | change(a) | change(&a) |
| Received as | int x | int *x |
| Large data cost | Copies everything | Copies only an address |
When to use which
- Use call by value when the function only needs to read the data and should not touch the original.
- Use call by reference when the function must change the caller's variable, return more than one result, or handle large data efficiently.
Common mistakes
- Expecting a call-by-value function to change the original — it never can.
- Forgetting the
&when calling a reference function (passing the value instead of its address). - Forgetting the
*inside the function, so you change the pointer instead of the value it points to. - Passing the address of a local variable and using it after that function returns.
Write a function void addTax(float *price, float rate) that increases the price by a tax rate in place. Call it with the address of a price variable and confirm the original value changed.
Summary
- Call by value passes a copy — the original variable is never changed.
- Call by reference passes an address — the function can change the original.
- C is technically always call by value; reference is done by passing a pointer.
- Swapping two numbers works only with call by reference.
- Use reference to modify the caller's data or to pass large data efficiently.
Frequently Asked Questions
What is the difference between call by value and call by reference in C?
Does C really have call by reference?
Why does a swap function not work with call by value?
How do I pass a variable by reference in C?
& when calling, and receive it as a pointer using * in the function. For example call change(&a) and define void change(int *x){ *x = 100; }. Inside, *x reads and writes the original variable.