C Pass By Reference
Pass By Value
In the previous chapter, you learned how to pass values to a function as parameters.
When you do this, the function gets a copy of the value. This is called pass by value. If the function changes the copy, the original variable does not change:
Example
void addTen(int x) {
x = x + 10;
}
int main() {
int myNum = 5;
addTen(myNum);
printf("%d\n", myNum); // 5
return 0;
}
Try it Yourself »
The function adds 10 to x, but x is only a copy of myNum. So myNum is still 5.
This is how it works: when you call addTen(myNum), the value of myNum (5) is copied into the parameter x. x is a new variable that only exists inside the function, and it is removed when the function is finished (you will learn more about this in the Scope chapter).
This is what the memory looks like while addTen() runs:
This is not a problem. It is how C normally works, and it is often exactly what you want: the function can use the value, but it cannot change your variables by accident.
If the function needs to give a result back, it can use return:
Example
int addTen(int x) {
return x + 10;
}
int main() {
int myNum = 5;
myNum = addTen(myNum);
printf("%d\n", myNum); // 15
return 0;
}
Try it Yourself »
Use pass by reference (below) only when a function must change the original variable directly, or give back more than one result.
Pass By Reference
Sometimes you want a function to change the original variable. To do this, give the function the memory address of the variable, instead of a copy of its value. This is often called pass by reference:
Example
void addTen(int *x) {
*x = *x + 10;
}
int main() {
int myNum = 5;
addTen(&myNum);
printf("%d\n", myNum); // 15
return 0;
}
Try it Yourself »
Compared to the pass by value example, three things are different:
- The parameter is a pointer (
int *x). It stores the memory address ofmyNum. - The function call uses
&to pass the memory address:addTen(&myNum) - Inside the function,
*xismyNumitself, so*x = *x + 10;changesmyNumto15.
This is what the memory looks like while addTen() runs:
This is exactly how scanf() works: in scanf("%d", &myNum), you give scanf() the memory address of myNum, so it can store the number that the user types there.
Note: Arrays work this way automatically. When you pass an array to a function, the function gets the memory address of the first element, not a copy of the array (see Pointers and Arrays). So a function can change the elements of an array, without using &.
Swap Two Variables
In the Change Values chapter, you learned how to swap the values of two variables with a third variable. With pointers, you can put the swap in a function:
Example
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5;
int y = 10;
swap(&x, &y);
printf("x is %d, y is %d\n", x, y); // x is 10, y is 5
return 0;
}
Try it Yourself »
Without pointers, the function would only swap its own copies, and x and y would not change.
Real-Life Example
A function can only return one value. With pointers, a function can give back more than one result.
This function finds both the lowest and the highest age in an array:
Example
void minMax(int ages[], int length, int *min, int *max) {
*min = ages[0];
*max = ages[0];
for (int i = 1; i < length; i++) {
if (ages[i] < *min) {
*min = ages[i];
}
if (ages[i] > *max) {
*max = ages[i];
}
}
}
int main() {
int ages[] = {20, 22, 18, 35, 48, 26, 87, 70};
int lowest, highest;
minMax(ages, 8, &lowest, &highest);
printf("Lowest age: %d\n", lowest);
printf("Highest age: %d\n", highest);
return 0;
}
Try it Yourself »
Example Explained
- The function takes four parameters: the array (
ages), its length (8), and two pointers (int *minandint *max). *minand*maxboth start with the first age in the array (20).- The loop checks the rest of the ages. If an age is lower than
*min, it becomes the new lowest age. If it is higher than*max, it becomes the new highest age. - In
main(),&lowestand&highestpass the memory addresses of the two variables, so the function stores the results directly in them. - After the function call,
lowestis18andhighestis87.