C Notes
Understand how arguments are passed to functions in C: pass by value vs pass by reference (using pointers). Learn when to use each approach with practical examples and common patterns.
How arguments are passed to functions is one of the most important concepts in C programming. C uses pass by value as its default mechanism — meaning functions receive copies of the arguments, not the originals. However, by passing pointers, you can achieve pass by reference behavior, allowing functions to modify the caller's variables. Understanding this distinction is critical for avoiding bugs and writing efficient code.
Pass by Value (Call by Value)
When you pass a variable to a function in C, the function receives a copy of the value. Any changes made to the parameter inside the function do NOT affect the original variable.
#include <stdio.h>
void doubleValue(int x) {
x = x * 2; // Modifies the local COPY only
printf("Inside function: x = %d\n", x);
}
int main() {
int num = 10;
printf("Before call: num = %d\n", num);
doubleValue(num); // Passes a COPY of num
printf("After call: num = %d\n", num); // Original unchanged!
return 0;
}Before call: num = 10 Inside function: x = 20 After call: num = 10
Notice that num remains 10 after the function call. The function only modified its local copy (x), not the original.
Why Swap Fails with Pass by Value
This is the classic demonstration:
#include <stdio.h>
void swapFail(int a, int b) {
int temp = a;
a = b;
b = temp;
printf("Inside swapFail: a=%d, b=%d\n", a, b);
}
int main() {
int x = 5, y = 10;
printf("Before: x=%d, y=%d\n", x, y);
swapFail(x, y); // Only swaps the copies!
printf("After: x=%d, y=%d (unchanged!)\n", x, y);
return 0;
}Before: x=5, y=10 Inside swapFail: a=10, b=5 After: x=5, y=10 (unchanged!)
Pass by Reference (Using Pointers)
To modify the caller's variables, pass their addresses (pointers). The function then accesses the original variables through dereferencing:
#include <stdio.h>
void doubleValue(int *x) {
*x = *x * 2; // Modifies the ORIGINAL through pointer
printf("Inside function: *x = %d\n", *x);
}
int main() {
int num = 10;
printf("Before call: num = %d\n", num);
doubleValue(&num); // Passes ADDRESS of num
printf("After call: num = %d\n", num); // Original IS changed!
return 0;
}Before call: num = 10 Inside function: *x = 20 After call: num = 20
Swap That Actually Works
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
printf("Before: x=%d, y=%d\n", x, y);
swap(&x, &y); // Pass addresses
printf("After: x=%d, y=%d (swapped!)\n", x, y);
return 0;
}Before: x=5, y=10 After: x=10, y=5 (swapped!)
Comparison Table
| Aspect | Pass by Value | Pass by Reference (Pointer) |
|---|---|---|
| What's passed | Copy of the value | Address of the variable |
| Can modify original? | No | Yes |
| Syntax in call | func(x) | func(&x) |
| Syntax in definition | func(int x) | func(int *x) |
| Memory usage | Creates a copy | Only copies the address (4/8 bytes) |
| Safety | Safer (can't corrupt) | Less safe (can modify anything) |
| Performance (large data) | Slower (copies all data) | Faster (only copies pointer) |
When to Use Each Approach
Use Pass by Value When:
- The function only needs to READ the value
- The original should NOT be modified
- The data is small (int, float, char)
Use Pass by Reference When:
- The function needs to MODIFY the original variable
- Returning multiple values from a function
- Passing large structures (to avoid expensive copies)
- The function needs to allocate memory for the caller
Returning Multiple Values via Pointers
Since C functions can only return one value, pointers let you "return" multiple results:
Min = 5, Max = 92 17 / 5 = 3 remainder 2
Passing Arrays to Functions
Arrays are ALWAYS passed by reference in C — the array name decays to a pointer to its first element:
Before: 1 2 3 4 5 After: 2 4 6 8 10
Passing Structures
By default, structures are passed by value (entire copy). For large structs, pass by pointer for efficiency:
Alice Johnson, Age: 20, GPA: 3.5 Student: Alice Johnson (3.8 GPA)
const Pointers — Read-Only References
Use const to pass by reference for efficiency while preventing modification:
Total: $52.24 Length: 11
Practical Example: Sorting with Pass by Reference
Before sorting: 64 34 25 12 22 11 90 After sorting: 11 12 22 25 34 64 90
Interview Questions
Q1: Does C support pass by reference?
Technically, no — C only has pass by value. However, by passing pointers (addresses), you achieve the same effect as pass by reference. The pointer itself is passed by value (a copy of the address), but through it, you can access and modify the original variable. True pass by reference (using & in parameters) exists in C++ but not C.
Q2: Why does swapping fail without pointers?
Without pointers, the function receives copies of the values. Swapping the copies has no effect on the original variables because the copies are local to the function and destroyed when it returns. With pointers, the function accesses the original memory locations and swaps the actual values stored there.
Q3: Are arrays passed by value or reference in C?
Arrays are effectively passed by reference. When you pass an array to a function, the array name decays into a pointer to its first element. The function receives this pointer (by value), but since it points to the original array's memory, modifications through it affect the original array.
Q4: What is the purpose of const in function parameters?
const in parameters (like const int *ptr) promises that the function won't modify the data pointed to. It provides documentation of intent, enables compiler optimizations, catches accidental modifications, and allows passing both const and non-const arguments. It's especially useful for read-only functions like search and print.
Q5: How do you return multiple values from a function in C?
Three approaches: (1) Pass pointers to variables where results should be stored (most common); (2) Return a struct containing multiple fields; (3) Use global variables (not recommended). Example: void minMax(int arr[], int n, int *min, int *max).
Summary
- C uses pass by value by default — functions get copies, originals are unchanged
- Pass by reference is achieved by passing pointers (addresses with
&) - Use
*to dereference pointers inside the function to access/modify originals - Arrays are always passed by reference (decay to pointers automatically)
- Use
constpointers for read-only reference passing (efficiency + safety) - Pass large structures by pointer to avoid expensive copying
- Multiple return values are achieved through pointer parameters
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Function Arguments in C - Pass by Value vs Pass by Reference.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, functions, function, arguments, function arguments in c - pass by value vs pass by reference
Related C Programming Topics