An array is simply a contiguous allocation of one or more elements of a given type.
int i; // a single element of type int
int j[100]; // an array of 100 elements of type int
The elements of an array are anonymous (we can't refer to them by name because they have no names). However we can access them by their offset address from the start of the array. The array name serves as a reference to the start of the array and will implicitly convert to a pointer:
int* p = j;
Each element of an array is offset by sizeof (type) bytes. However, the offset is known to the compiler so we do not need to specify it when accessing array elements, we only need to know the zero-based index of the element we wish to access:
int k = j[42];
Note that the suffix operator [] does not perform a range-check. It is up to the programmer to ensure the given index is in range. The array named j has 100 elements so all indices must be in the range 0 through 99. Access beyond the range of an array has undefined behaviour:
int m = j[100]; // undefined behaviour
Given j is a reference, we can also use pointer arithmetic to access elements:
int n = j + 42;
From this we can see that the following holds true:
j[42] 42[j]
It often surprises people to learn that j[42] and 42[j] are equivalent, however it's only because the suffix operator is sugar-coating for the underlying pointer arithmetic so the compiler sees 42 + j, not 42[j]. However, low-level trickery such as this has no place in production code.
The elements of an array are uninitialised at the point of instantiation. However we can use an initialiser to set initial values:
int j[5] = {5, 10, 15, 20, 25};
When we pass arrays to functions, the array implicitly converts to a pointer. This means information is lost in the exchange because the function cannot know how many elements are being referred to by the pointer. Thus we must pass the length of the array as a separate argument:
void f (int* arr, unsigned size) {
for (unsigned idx=0; idx<size; ++idx) {
arr[idx] = 0;
}
}
Given that arrays implicitly convert to pointers, variable-length arrays are treated exactly the same as fixed-length arrays, the only difference is that the programmer is responsible for allocating and releasing the memory:
void g (unsigned size) {
int* p = malloc (size * sizeof (int)); // allocate
f (p, size); // use
free (p); // release
}
Note that variable-length arrays cannot be initialised at the point of instantiation; they must be instantiated then initialised, as shown above.
Fixed-length arrays (where the length is known to the compiler) can be allocated in static memory, on the call stack or on the heap. Global arrays are best allocated statically while small local arrays are best allocated on the stack. Large local arrays should be allocated on the heap. Variable-length arrays must always be allocated on the heap.
Copyright © 2026 eLLeNow.com All Rights Reserved.