Tamil Technicians – C Programming Course · Lesson 15
Call by Value vs Call by Reference – Simple Pointer Examples in Tamil
When you first start writing functions in C, one common confusion is:
“Why doesn’t my swap() function actually swap the values in main()?”
This confusion comes from not fully understanding
Call by Value vs Call by Reference style (using pointers).
In this lesson, we will explain these concepts in simple, technician-friendly English, suitable for Tamil learners:
- What “Call by Value” really means in C.
- Why C does not have true “Call by Reference” but we simulate it with pointers.
- How to write and understand pointer-based functions like
swap()andincrement(). - Clear diagrams and mental models to avoid confusion.
Important Truth: C Has Only Call by Value
Before we begin, one key point:
In C, all function arguments are passed by value. That means: C always passes a copy of each argument into the function.
Then why do many books say “Call by Reference” in C? Because we can pass the address of a variable (using pointers), and that allows the function to modify the original variable. This behaves like Call by Reference, so people use that phrase informally.
Call by Value in C – Copy Only
With Call by Value:
- The function receives a copy of the variable’s value.
- Any changes inside the function affect only the copy, not the original.
Example: Simple Increment (Call by Value)
#include <stdio.h>
void increment(int x) {
x = x + 1;
printf("Inside increment: x = %d\\n", x);
}
int main() {
int a = 5;
printf("Before call: a = %d\\n", a);
increment(a);
printf("After call: a = %d\\n", a);
return 0;
}
Output (typical):
Before call: a = 5
Inside increment: x = 6
After call: a = 5
Inside the function, x becomes 6, but a in main() is still 5,
because only a copy was modified.
Classic Problem: swap() That Doesn’t Work (Call by Value)
This is the famous beginner bug:
#include <stdio.h>
void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
}
int main() {
int a = 10, b = 20;
printf("Before swap: a = %d, b = %d\\n", a, b);
swap(a, b);
printf("After swap: a = %d, b = %d\\n", a, b);
return 0;
}
Output (surprise for beginners):
Before swap: a = 10, b = 20
After swap: a = 10, b = 20
x and y are copies of a and b.
We swapped only the copies, not the original variables.
Using Pointers to Simulate Call by Reference
To modify the original variables in a function, we must give the function access to their addresses. In C, addresses are stored in pointers.
Quick pointer refresher
&→ address-of operator (gives the address of a variable).*→ used in two ways:- In declaration:
int *p;means “pointer to int”. - In expression:
*pmeans “value at the address stored in p”.
- In declaration:
Think of a as a house.
The value (e.g., 10) is inside the house.
The address is like the house’s door number.
If you give someone the door number (address), they can go and change things inside.
swap() Using Pointers – Call by Reference Style
Let’s fix the swap example using pointers:
#include <stdio.h>
void swap(int *x, int *y) {
int temp = *x; // temp = value at address x
*x = *y; // value at x = value at y
*y = temp; // value at y = temp
}
int main() {
int a = 10, b = 20;
printf("Before swap: a = %d, b = %d\\n", a, b);
swap(&a, &b); // pass addresses of a and b
printf("After swap: a = %d, b = %d\\n", a, b);
return 0;
}
Output:
Before swap: a = 10, b = 20
After swap: a = 20, b = 10
Now it works. Why?
- We pass
&aand&b(addresses) to the function. - Inside
swap,xandyare pointers to those addresses. *xmeans “the variable at addressx” → effectivelya.*ymeans “the variable at addressy” → effectivelyb.
Pointer Example: Increment Original Variable
Here is another simple example showing Call by Value vs pointer-based Call by Reference style.
Call by Value version
void incValue(int x) {
x = x + 1;
}
Pointer (Reference style) version
void incRef(int *p) {
*p = *p + 1;
}
#include <stdio.h>
void incValue(int x) {
x = x + 1;
}
void incRef(int *p) {
*p = *p + 1;
}
int main() {
int a = 5, b = 5;
incValue(a); // a stays 5
incRef(&b); // b becomes 6
printf("a = %d (after incValue)\\n", a);
printf("b = %d (after incRef)\\n", b);
return 0;
}
Arrays & Functions – Naturally Reference-like
When you pass an array to a function, it already behaves in a reference-like way because the array name decays to a pointer.
Example: Double All Elements in an Array
#include <stdio.h>
void doubleArray(int a[], int n) {
int i;
for (i = 0; i < n; i++) {
a[i] = a[i] * 2;
}
}
int main() {
int marks[] = {10, 20, 30};
int n = 3, i;
doubleArray(marks, n); // no & needed
for (i = 0; i < n; i++) {
printf("%d ", marks[i]);
}
printf("\\n");
return 0;
}
Output: 20 40 60
The original array values are changed, because inside doubleArray,
a acts as a pointer to the original array.
Comparison Table – Call by Value vs Pointer-based Reference Style
| Feature | Call by Value | Pointer-based “Call by Reference” style |
|---|---|---|
| What is passed? | Copy of the value. | Copy of the address of the variable. |
| Can function modify original? | No (unless using globals). | Yes, via dereferencing pointer (*p). |
| Syntax in parameter | int x |
int *p |
| Syntax in call | f(a) |
f(&a) |
| Typical use | Simple calculations, reading-only values. | swap, increment, output parameters, modify arrays/structs. |
Common Mistakes with Call by Value & Pointers
-
Expecting normal parameters to change originals:
Forgetting that
int xis a copy, not the original. -
Forgetting & in function call:
Writing
swap(a, b)instead ofswap(&a, &b)when using pointer parameters. -
Forgetting * when assigning:
Writing
p = 10;instead of*p = 10;(which changes the pointed value). - Uninitialized pointers: Using a pointer without assigning it a valid address causes crashes or undefined behaviour.
-
Confusing address & value:
Printing
pvs*pwithout understanding which is needed.
& to get address, and * to go from address to value.
Learning Checklist (For Tamil Learners)
- I understand that C uses Call by Value for all arguments.
- I can explain why
swap(int x, int y)does not change caller variables. - I can write
swap(int *x, int *y)and call it correctly using&. - I know when to use normal parameters vs pointer parameters.
- I can trace simple pointer code and predict the output.
Suggested Featured Image Prompt
Use this prompt in your AI image generator for the TamilTechnicians.com thumbnail:
“Flat modern 16:9 illustration on a light background. On the left, a small diagram shows `main()` calling `swap(a, b)` with labels ‘Call by Value – copies only’, and the values 10 and 20 in two separate boxes that stay unchanged. On the right, another diagram shows `main()` calling `swap(&a, &b)` with labels ‘Pointer style – address passed’, and two boxes for `a` and `b` whose values 10 and 20 are crossed and swapped to 20 and 10. In the center bottom, a simple memory diagram shows a pointer `p` storing an address (an arrow pointing to a variable box). A South Indian / Tamil technician character stands near the diagrams holding a pointer stick, with small text labels ‘& = address’, ‘* = value at address’. At the top, bold title text: ‘Call by Value vs Call by Reference’ and smaller subtitle: ‘Simple Pointer Examples in C | Tamil Technicians’. Clean vector style, minimal colors, educational and high quality.”
FAQ: Call by Value vs Call by Reference Style in C
1. Does C support true Call by Reference?
No. C supports only Call by Value. But you can pass addresses (pointers) as arguments. This lets the function modify the original data, which behaves like Call by Reference, so people use that term informally.
2. Why do arrays seem to be passed by reference?
When you pass an array to a function, the array name decays to a pointer to its first element. So the function works with the original array memory. Technically it is still Call by Value (the pointer itself is passed by value), but the pointed data is shared.
3. When should I use pointers in function parameters?
Use pointer parameters when the function needs to modify variables in the caller (e.g., swap), return multiple results, modify arrays or structures, or when passing large data efficiently without copying.
4. Is using pointers dangerous?
Pointers are powerful but must be used carefully. Problems like using uninitialized pointers, dereferencing NULL, or writing to invalid memory can crash programs. With clear rules and simple patterns (like those shown in this lesson), they are safe and extremely useful.


