In C/C++, arrays and pointers have similar semantics, except on type information.
As an example, given a 3D array
An element at location  can be accessed as “buffer” or *( *( *(buffer + 2) + 1) + 2).
Observe the following declaration
T *p; // p is a pointer to an object of type T
When a pointer p is pointing to an object of type T, the expression *p is of type T. For example buffer is of type array of 5 two dimensional arrays. The type of the expression *buffer is “array of arrays (i.e. two dimensional array)”.
Based on the above concept translating the expression *( *( *(buffer + 2) + 1) + 2) step-by-step makes it more clear.
- buffer – An array of 5 two dimensional arrays, i.e. its type is “array of 5 two dimensional arrays”.
- buffer + 2 – displacement for 3rd element in the array of 5 two dimensional arrays.
- *(buffer + 2) – dereferencing, i.e. its type is now two dimensional array.
- *(buffer + 2) + 1 – displacement to access 2nd element in the array of 7 one dimensional arrays.
- *( *(buffer + 2) + 1) – dereferencing (accessing), now the type of expression “*( *(buffer + 2) + 1)” is an array of integers.
- *( *(buffer + 2) + 1) + 2 – displacement to get element at 3rd position in the single dimension array of integers.
- *( *( *(buffer + 2) + 1) + 2) – accessing the element at 3rd position (the overall expression type is int now).
The compiler calculates an “offset” to access array element. The “offset” is calculated based on dimensions of the array. In the above case, offset = 2 * (7 * 6) + 1 * (6) + 2. Those in blue colour are dimensions, note that the higher dimension is not used in offset calculation. During compile time the compiler is aware of dimensions of array. Using offset we can access the element as shown below,
element_data = *( (int *)buffer + offset );
It is not always possible to declare dimensions of array at compile time. Sometimes we need to interpret a buffer as multidimensional array object. For instance, when we are processing 3D image whose dimensions are determined at run-time, usual array subscript rules can’t be used. It is due to lack of fixed dimensions during compile time. Consider the following example,
Where base is pointing large image buffer that represents 3D image of dimension l x b x h where l, b and h are variables. If we want to access an element at location (2, 3, 4) we need to calculate offset of the element as
offset = 2 * (b x h) + 3 * (h) + 4 and the element located at base + offset.
Generalizing further, given start address (say base) of an array of size [l x b x h] dimensions, we can access the element at an arbitrary location (a, b, c) in the following way,
data = *(base + a * (b x h) + b * (h) + c); // Note that we haven’t used the higher dimension l.
The same concept can be applied to any number of dimensions. We don’t need the higher dimension to calculate offset of any element in the multidimensional array. It is the reason behind omitting the higher dimension when we pass multidimensional arrays to functions. The higher dimension is needed only when the programmer iterating over limited number of elements of higher dimension.
A C/C++ puzzle, predict the output of following program
Thanks to student for pointing an error.
— Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Pointer to an Array | Array Pointer
- Multidimensional Arrays in C / C++
- Double Pointer (Pointer to Pointer) in C
- Pointers in C and C++ | Set 1 (Introduction, Arithmetic and Array)
- Dangling, Void , Null and Wild Pointers
- What is Array Decay in C++? How can it be prevented?
- What’s difference between “array” and “&array” for “int array” ?
- Function Pointer in C
- How to pass a 2D array as a parameter in C?
- How to dynamically allocate a 2D array in C?
- Difference between pointer and array in C?
- References in C++
- How does free() know the size of memory to be deallocated?
- Do not use sizeof for array parameters
- Why C treats array parameters as pointers?