Passing an Array to a Function

Before we go further, let's talk about passing arrays to functions. Let's say we have two arrays: one has 10 elements, and another one has 5 elements:

int first[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int second[5] = { 10, 20, 30, 40, 50 };

We want to implement a function which will print all elements of an array, and use it to print these two arrays. How will this function definition look like? It's a void function (as described here) because it does not return anything, just prints the values, but what would it accept as a parameter?

Arrays are passed as pointers

We discussed that the array name, first or second in our case, can be "decayed" to a pointer to its 0-th element: it points to the same address in memory, but it has no idea about the number of elements in an array. This is what happens when an array is passed to a function: the function will know where in the memory the array starts, but won't know how big it is unless we pass its length in another parameter.

In other words, here is how we declare our print_array function. Note that we don't need to put any size between [ ], it will be ignored anyway.

void print_array(int arr[], int size) {
	...
}

Alternatively, we can make it clear that we are accepting a pointer. This is exactly equivalent to the above:

void print_array(int *arr, int size) {
	...
}

Choosing this or that is a matter of personal preference.

Please take a moment to implement it, and make sure it works:

#include <stdio.h>

void print_array(int *arr, int size) {
	/* your code here: print elements separated by one space, and \n */
}

int main() {
	int first[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int second[5] = { 10, 20, 30, 40, 50 };

	print_array(first, 10);
	print_array(second, 5);

	return 0;
}

It is very important to understand that the function accepting an array as a parameter has not way to know how many elements that array really has. For the first and second arrays above, all of the following calls will be valid:

print_array(first, 10);
print_array(first, 5);
print_array(second, 5);
print_array(second, 3);

Basically, we tell a function how many elements to take, but it has no way to know how many elements are indeed there. If we mess up and ask it to take more elements than we actually have, it might crash, or not–but it will read some garbage values from the memory for sure.

Want to see one example of the garbage? Try this:

print_array(second, 20);

Do you see what is printed? Depending on how arrays are arranged in the memory, it will go beyond the boundary of second, and will likely print elements of first. It won't crash here in the browser because of how the memory is implemented in WebAssembly, the runtime environment I use here for running your code, but it could crash if you use a "real" compiler, and try printing too many values. So... just don't do that; make sure you never go beyond the boundary of your arrays.

A function can change values of its array parameters

Since we pass arrays as pointers, the function can assign values to elements of arrays passed to it as parameters. As we discussed earlier, all parameters in C are passed by value, but since arrays are pointers, no one prevents us from doing this:

#include <stdio.h>

void f(int *arr, int size) {
	/* we don't use its size here at all */
	arr[0] = 42;
}

int main() {
	int arr[5] = { 1, 2, 3, 4, 5 };

	printf("arr[0] was %d\n", arr[0]);
	f(arr, 5);
	printf("arr[0] is %d\n", arr[0]);

	return 0;
}

Everything works as expected: arr was decayed to a pointer which was passed by value and has not changed, but the function dereferenced the pointer (arr[0] is the same as *arr) and changed the value of the 0-th element of the array.

Makes sense, right?

Now that we know how to pass an array to a function, we can do something serious! On the next pages we'll discuss some topics that are not directly related to C programming, but they are still very important: linear search, binary search, and the time complexity of the code. Stay tuned!