Arrays and pointers
Table of contents
Arrays and pointers are closely related in C.
Consider this array:
int values[] = {10, 20, 30, 40, 50};
In most expressions, the array name gives the address of its first element:
values
This is the same address as:
&values[0]
We can therefore use the array name to initialise a pointer:
int *value_pointer = values;
The pointer now targets the first element of the array.
Accessing array elements
Dereferencing the pointer accesses the first element:
*value_pointer
This is equivalent to:
values[0]
Adding one to the pointer moves it to the next element:
*(value_pointer + 1)
This accesses:
values[1]
In general:
values[index]
is equivalent to:
*(values + index)
Square brackets are normally easier to read and what we will focus on in the course, but the pointer form helps explain how array indexing actually works.
Passing an array to a function
When an array is passed to a function, the function receives a pointer to its first element.
For example:
int sum_array(const int values[], size_t length)
The parameter:
const int values[]
can also be written as:
const int *values
The function does not receive the complete array as a copy.
Passing the length
A pointer tells the function where the array begins, but not how many elements it contains. We must pass the length separately:
#include <stdio.h>
int sum_array(const int values[], size_t length);
int main(void)
{
int values[] = {10, 20, 30, 40, 50};
size_t length = sizeof(values) / sizeof(values[0]);
int total = sum_array(values, length);
printf("Total: %d\n", total);
return 0;
}
int sum_array(const int values[], size_t length)
{
int total = 0;
for (size_t i = 0; i < length; i++) {
total = total + values[i];
}
return total;
}
The caller calculates and passes the length:
sum_array(values, length);
Inside sum_array(), values is a pointer. This means that:
sizeof(values)
would give the size of the pointer, not the size of the original array!
Modifying an array
A function can modify the original array:
void double_array(int values[], size_t length)
{
for (size_t i = 0; i < length; i++) {
values[i] = values[i] * 2;
}
}
Calling:
double_array(values, length);
changes the elements in the caller’s array.
If the function should only read the array, use const:
int sum_array(const int values[], size_t length)
This allows the function to read the elements but prevents it from changing them. Not essential, but it is good practice.
The main points to remember are:
- an array name normally gives the address of its first element
- array indexing is closely related to pointer arithmetic
- a function receiving an array does not know its length
- pass the array length as a separate parameter
- use
constwhen the function should not modify the array