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 usefu
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.
I think the conclusion from this whole discussion is never. Nobody here really demonstrated a use for this construct where something else wouldn't work in a more comprehensible way.
Following code is a part of my article : Pointers and Arrays in C C++
You can check it out @ http://pointersandarrays.blogspot.com/
Pointers and 2D Arrays
Following code snippet illustrates how to declare and access a 2D array. Underneath 2D Array lies a single dimensional array. You will get be sure of this after playing with the following piece of code.
Code Snippet #4
#include<iostream&rt;
using namespace std;
int main()
{
cout<< "Understanding Pointers and 2 D Arrays"<<endl;
cout<< "----------------------\n"<<endl;
//Declaration of a 2D Array.
int tab[3][5];
//Total space required : 3*5 * sizeof(int) = 15 * sizeof(int)
//Funda : Since the amount of required space is known by compiler, contiguous 15 memory cells are allocated here.
//Hence the case is similar to a 1 D Array of size 15. Lets try this out!
//Array initialization using array name
for(int i=0; i<3;i++)
for(int j=0; j<5;j++)
tab[i][j]=i+2*j;
//Print array using array name
cout << "\nPrint array using array name ..."<<endl;
for(int i=0; i<3;i++)
{
for(int j=0; j<5;j++)
printf("%2d ",tab[i][j] );
printf("\n");
}
//Print array using a pointer. Proof of 1 D array being allocated
cout << "\nPrint array using a pointer. Proof of 1 D array being allocated ..." << endl;
int *tptr;
tptr = &tab[0][0]; // pointer tptr points at first element of the array.
for(int i=0; i<15;i++)
printf("%d ",*(tptr+i) );
tptr = &tab[0][0];
cout << "\nNotice that array is printed row by row in a linear fashion."<<endl;
return 0;
}
Output #4:
Understanding Pointers and 2D Arrays
Print array using array name ...
0 2 4 6 8
1 3 5 7 9
2 4 6 8 10
Print array using a pointer. Proof of 1 D array being allocated ...
0 2 4 6 8 1 3 5 7 9 2 4 6 8 10
Notice that array is printed row by row in a linear fashion.
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 *
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.