I can declare:
int (*ap)[N];
So ap
is pointer to int array of size N. Why is this ever useful? If I pass it to function, what useful thing it can do with it that it could not do with just a normal pointer to the array's contents?
C FAQ say:
2.12: How do I declare a pointer to an array?
Usually, you don't want to.
A normal array stores values of variables, and pointer array stores the address of variables. Usually, arrays can store the number of elements the same size as the size of the array variable. A pointer variable can store the address of only one variable at a time.
The main difference between Array and Pointers is the fixed size of the memory block. When Arrays are created the fixed size of the memory block is allocated. But with Pointers the memory is dynamically allocated.
Pointers are used to store and manage the addresses of dynamically allocated blocks of memory. Such blocks are used to store data objects or arrays of objects. Most structured and object-oriented languages provide an area of memory, called the heap or free store, from which objects are dynamically allocated.
A pointer to an array can be used to dynamically allocate a multi-dimensional array N, where N-1 dimensions are known. Below creates a Nx3 array.
int (*ap)[3];
ap = malloc(N * sizeof(*ap));
/* can now access ap[0][0] - ap[N-1][2] */
@Adam E/Cruachan, This is not the same thing as a pointer to a pointer. ap is a single pointer to a block of memory containing three consecutive integers. ap++ will advance the pointer address to the next block of three integers. for int **pp;
, pp points to an integer pointer, each of which can point to an integer anywhere in memory.
+-----+ +------+ +-----+
ap ---> | int | vs. pp ---> | int* | -> | int |
| int | +------+ +-----+
| int | pp+1 -> | int* | -\
+-----+ +------+ \ +-----+
ap+1 -> | int | : : -> | int |
| int | +-----+
| int |
+-----+
: :
If you increment the pointer, it will then point to the start of the next group of N elements.
This is not a big deal and it's use is up to the developer.
Generally, the only time you'll see a pointer to an array (T (*a)[N]
) is as a function parameter, where a
is meant to be a 2d array:
void foo(int (*a)[N], size_t count)
{
size_t i;
for (i = 0; i < count; i++)
a[i][j] = ...;
...
}
void bar(void)
{
int arr[M][N];
foo(arr, M);
}
Note that for a function parameter declaration, int a[][N]
is equivalent to int (*a)[N]
, but this is only true for function parameter declarations:
void foo (int a[][N], size_t count) {...}
Pointers to arrays are generally not as useful as pointers to the base type, since you need to know the array size to properly declare a pointer to it (a pointer to a 10-element array of int is a different type from a pointer to a 20-element array of int). Personally, I haven't found much use for them in 20-some-odd years of programming.
Remember that in most contexts, an array expression (such as arr
above) will have its type implicitly converted from "N-element array of T" to "pointer to T" (except when the array expression is an operand of sizeof
or &
, or the array is a string literal being used as an initializer in a declaration). In this case, the type of arr
in the call to foo is implicitly converted from "M-element array of N-element array of int" to "pointer to N-element array of int".
Given the declaration T a[M][N]
, all of the following expressions will evaluate to the same location (the address of the first element in the array), but the types will be different as shown below:
Expression Type Implicitly converted to ---------- ---- ----------------------- a T [M][N] T (*)[N] a[0] T [N] T * &a T (*)[M][N] &a[0] T (*)[N] &a[0][0] T *
It's not useful, really. But sometimes pointers to arrays are used e.g. in Microsoft Windows API - I've seen a lot of this stuff there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With