C course menu
Function Parameters in C: Pass by Value, Pointers, Arrays and Returning Values
Understand how arguments are passed in C: pass by value and its consequences, changing the caller's variables through pointers, passing arrays with their length, const parameters, and returning several values from a function.
On this page
C passes every argument by value: the function receives a copy. This one rule explains how functions interact with the caller's data.
Pass by value#
#include <stdio.h>
void try_to_change(int x) {
x = 100;
printf("inside: %d\n", x);
}
int main(void) {
int value = 5;
try_to_change(value);
printf("outside: %d\n", value);
return 0;
}inside: 100
outside: 5The function changed its own copy; value in main is untouched.
Changing the caller's variable with a pointer#
To let a function change a variable, pass its address with &, and use * inside the function to reach the original. This is how C simulates "pass by reference":
#include <stdio.h>
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(void) {
int x = 3, y = 7;
swap(&x, &y);
printf("x = %d, y = %d\n", x, y);
return 0;
}x = 7, y = 3This is also why scanf("%d", &n) needs &: it must write into your variable. Pointers are explained fully in Pointers.
Passing arrays#
When you pass an array, the function receives a pointer to its first element, not a copy of the array. So the function can change the caller's array, and it does not know the array's length, which you must pass separately:
#include <stdio.h>
void double_all(int values[], int n) {
for (int i = 0; i < n; i++) {
values[i] *= 2;
}
}
int sum(const int values[], int n) {
int total = 0;
for (int i = 0; i < n; i++) total += values[i];
return total;
}
int main(void) {
int marks[] = {10, 20, 30};
double_all(marks, 3);
printf("%d %d %d\n", marks[0], marks[1], marks[2]);
printf("sum = %d\n", sum(marks, 3));
return 0;
}20 40 60
sum = 120int values[]andint *valuesmean the same thing as parameters.- Inside the function,
sizeof valuesgives the size of a pointer, not the array, so always pass the length.
const parameters#
const in a pointer or array parameter promises that the function will not modify the data. The compiler enforces it, and callers can see the function is safe to call:
int sum(const int values[], int n) {
values[0] = 0;
return n;
}GCC reports error: assignment of read-only location '*values'.
Returning several values#
A function returns at most one value. To give back more, use output parameters (pointers) or return a struct (Structures):
#include <stdio.h>
void min_max(const int a[], int n, int *min, int *max) {
*min = *max = a[0];
for (int i = 1; i < n; i++) {
if (a[i] < *min) *min = a[i];
if (a[i] > *max) *max = a[i];
}
}
int main(void) {
int data[] = {42, 7, 19, 88, 3};
int lo, hi;
min_max(data, 5, &lo, &hi);
printf("min %d, max %d\n", lo, hi);
return 0;
}min 3, max 88Practice#
Practice exercise
Write void divide(int a, int b, int *quotient, int *remainder) and use it to divide 47 by 5. Also write double average(const int a[], int n) and use it on {4, 8, 15, 16, 23, 42}.
Show solution
#include <stdio.h>
void divide(int a, int b, int *quotient, int *remainder) {
*quotient = a / b;
*remainder = a % b;
}
double average(const int a[], int n) {
int total = 0;
for (int i = 0; i < n; i++) total += a[i];
return (double)total / n;
}
int main(void) {
int q, r;
divide(47, 5, &q, &r);
printf("47 / 5 = %d remainder %d\n", q, r);
int nums[] = {4, 8, 15, 16, 23, 42};
printf("average = %.2f\n", average(nums, 6));
return 0;
}47 / 5 = 9 remainder 2
average = 18.00Key takeaway#
Finished this lesson?