Unit 3 · Lesson 218 minAcademic review pending

Passing an array to a function

An array argument is passed as an address, so a function can change the caller's array — the one big exception to pass by value.

Choose explanation

After this lesson

You should be able to

  • Write a function that takes an array and its length.
  • Explain why an array parameter behaves differently from an int parameter.
  • Use const to promise that a function will not modify an array.
01

The array does not get copied

Passing an int copies it. Passing an array does not — what actually travels is the address of the first element. The function works on the caller's own array, so any change it makes is permanent.

This is not an inconsistency invented to confuse you. Copying a 10,000-element array on every call would be slow and would need somewhere to put it, so C passes the address instead.

No & anywhere, yet the caller's array changes
void scale(int data[], int n)
{
    for (int i = 0; i < n; i++)
        data[i] = data[i] * 2;
}

/* in main */
int marks[3] = {10, 20, 30};
scale(marks, 3);
/* marks is now {20, 40, 60} — main's array really changed */
02

The length must travel separately

Because only an address is passed, the function has no idea how long the array is. sizeof inside the function measures a pointer, not the array. So you must pass the length as a second parameter — every array function in C does this, including the standard library ones.

int data[] and int *data mean exactly the same thing in a parameter list. The bracket form documents your intent better, so prefer it when the parameter really is an array.

03

const says 'I will not touch it'

Because array parameters are dangerous by default, mark read-only ones const. const int data[] tells the compiler to reject any assignment to data[i] inside the function, turning a possible silent bug into a compile error.

It also documents the interface. A reader seeing const knows the call is safe without reading the function body, which is the same benefit pass by value gives for plain variables.

const turns a possible bug into a compile error
double average_of(const int data[], int n)
{
    int total = 0;

    for (int i = 0; i < n; i++)
        total += data[i];
    /* data[i] = 0;  <- would not compile, thanks to const */

    return (double) total / n;
}

Try it yourself

Write two functions over an array of marks: one that returns the average without changing anything, and one that adds five grace marks to every element, capped at 100.

Need a hint?

One of them should take const, and one must not.

Check the worked solution

The const on average_of is doing real work: it is a compiler-checked promise that this function cannot be the cause if the marks ever change unexpectedly. add_grace deliberately omits const because modifying is its whole purpose, and the cap prevents grace marks pushing a 98 past the maximum.

#include <stdio.h>
#define SIZE 5

double average_of(const int data[], int n);
void   add_grace(int data[], int n, int grace);

int main(void)
{
    int marks[SIZE] = {72, 45, 98, 38, 66};

    printf("Before: %.2f\n", average_of(marks, SIZE));
    add_grace(marks, SIZE, 5);
    printf("After:  %.2f\n", average_of(marks, SIZE));

    return 0;
}

double average_of(const int data[], int n)
{
    int total = 0;
    for (int i = 0; i < n; i++)
        total += data[i];
    return (double) total / n;
}

void add_grace(int data[], int n, int grace)
{
    for (int i = 0; i < n; i++) {
        data[i] += grace;
        if (data[i] > 100)
            data[i] = 100;
    }
}

Quick check

Why must you pass an array's length as a separate parameter?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

Using Array Elements as Function Arguments · Array Arguments

Maps to course outcomes CO4, CO5.