Skip to content
Laviyx Learn

Try

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.

Beginner7 min readUpdated
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#

C
#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;
}
Output
inside: 100
outside: 5

The 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":

C
#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;
}
Output
x = 7, y = 3

This 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:

C
#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;
}
Output
20 40 60
sum = 120
  • int values[] and int *values mean the same thing as parameters.
  • Inside the function, sizeof values gives 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:

C
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):

C
#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;
}
Output
min 3, max 88

Practice#

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
C
#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;
}
Output
47 / 5 = 9 remainder 2
average = 18.00

Key takeaway#

Finished this lesson?