1. What is Call by Reference?
Technically, C *always* uses "Call by Value." However, we can simulate "Call by Reference" by using pointers. This is C's way of allowing a function to modify its original arguments.
Here is the most important rule:
In call by reference, instead of passing the value of a variable, you pass its memory address. The function's parameter is a pointer that stores this address.
2. How it Works (Memory)
This method requires two changes: one in the function call, and one in the function definition.
Imagine a = 10; in main at memory address 1000.
1.
In the Function Call: You
pass the address of
the variable using the address-of operator (&).
swap(&a, &b);
2.
In the Function Definition: The
parameters must be declared as pointers (using *) to hold these addresses.
void swap(int
*x, int
*y) { ... }
3.
What happens: The
address of a (1000)
is copied into the pointer x. Now, x "points to" a.
3. The Main Consequence
Because the function now has the address of the original variable, it can
use the dereference
operator (*) to go
to that address and change the original value.
·
The parameter x holds
the address of a.
·
The expression *x (read
as "the value at address x") is the
variable a.
By changing *x, you are
directly changing a.
4. Example: The "Correct" Swap
Here is the correct way to write the swap function. We pass the addresses, and the
function uses pointers to change the original values.
/* * Example 1: Call by Reference (The "Correct Swap") * The changes inside swap() WILL affect main().*/
#include <stdio.h>
// Prototype: The parameters are now POINTERS to integers
void swap(int *x, int *y);
int main() {
int a = 10;
int b = 20;
printf("[In main] Before swap: a = %d, b = %d\n", a, b);
// Call the swap function.
// We pass the ADDRESS of 'a' (&a).
// We pass the ADDRESS of 'b' (&b).
swap(&a, &b);
printf("[In main] After swap: a = %d, b = %d\n", a, b);
// The values are NOW 20 and 10!
return 0;
} /* * This function takes two pointers. * It modifies the values AT those addresses.*/
void swap(int *x, int *y) {
int temp;
// Read the value AT the address 'x' (which is 'a')
temp = *x; // Write the value AT address 'y' ('b') into the address 'x' ('a')
*x = *y; // Write the value from 'temp' into the address 'y' ('b')
*y = temp; printf(" [In swap] Swapped values...\n");
}Expected Output:
[In main]
Before swap: a = 10, b = 20
[In swap]
Swapped values...
[In main]
After swap: a = 20, b = 10
Analysis: It
worked! Because the swap function had the addresses of a and b, it was able to use *x and *y to reach back into main's memory and change the original values.
5. A Special Case: Passing Arrays
You may have noticed that when you pass an array to a function, you can modify it. Why?
Because in C, arrays are always passed by reference.
When you pass an array name (e.g., myFunction(arr)), you are not passing the whole
array. You are just passing a pointer
to the first element (as you learned in "Arrays with
Pointers"). The function receives the address of the start of the array, so any
changes it makes (e.g., arr[i] = ...) are
changing the original array in main.
This is why the following two function prototypes are identical:
void printArray(int arr[], int size);
void printArray(int *arr, int size);
Both mean "this function takes a pointer to an integer."
The [] notation is just
"syntactic sugar" to make it clearer that we expect an array.