11

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.

zaharpopov
  • 16,882
  • 23
  • 75
  • 93
  • 3
    a pointer to a pointer to an int however IS useful. – Toad Jan 10 '10 at 19:25
  • I don't think I've ever needed to code using a pointer to an array in the 25+ years I've been programming in C. (I've only used triple pointers - SomeType ***var - a couple of times, and changed the code to avoid them as soon as I could.) – Jonathan Leffler Jan 10 '10 at 19:28
  • 1
    @reinier: sure but I didnot ask about that – zaharpopov Jan 10 '10 at 19:36
  • 1
    that's not a pointer to an array. thats an array of int pointers. an array is a pointer itself. – Dave O. Jan 10 '10 at 20:01
  • Such a variable is usually allocated on the stack, that's the reason a pointer to it could be quite dangerous. – Georg Schölly Jan 10 '10 at 20:37
  • 1
    @Dave, it is not an array of int pointers, it is a pointer to N ints. – Mark Tolonen Jan 10 '10 at 22:14
  • It is indeed a pointer to an array, and an array is *not* a pointer itself. – caf Jan 11 '10 at 00:18
  • @Dave's comment is proof of concept why comments too should have downvote on SO – zaharpopov Jan 11 '10 at 03:42
  • @Dave: At the risk of dogpiling, arrays and pointers are most emphatically **not** the same thing, and the declaration `int (*ap)[N]` defines `ap` as a pointer to an N-element array of int, not an N-element array of pointer to int. – John Bode Jan 11 '10 at 20:50

9 Answers9

14

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 |
         +-----+
           : :  
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
6

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.

Steve Emmerson
  • 7,702
  • 5
  • 33
  • 59
3

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 *
John Bode
  • 119,563
  • 19
  • 122
  • 198
2

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.

Adam Woś
  • 2,493
  • 20
  • 21
  • what for used in the win API ? – zaharpopov Jan 10 '10 at 19:36
  • You can google for '"pointer to array" inurl:msdn.microsoft.com'. Examples: http://msdn.microsoft.com/en-us/library/ms221359.aspx, http://msdn.microsoft.com/en-us/library/ms714816%28VS.85%29.aspx etc. – Adam Woś Jan 10 '10 at 19:39
  • @adam.wos: looked at these links - this doen'st look like real pointers to arrays in C, just pointers – zaharpopov Jan 11 '10 at 03:44
  • You're right in the strictest term. For them, "pointer to array" is a pointer to the first element, not a pointer to array as you said in the question. – Adam Woś Jan 11 '10 at 07:30
2

There are situations where you want to pass the memory location across programs. e.g a windows API might expect you to pass a pointer to data structure or an array where as you are programming in some other language, say c#. Windows API does not care how the target language handles array's, for windows API it is just a stream of bytes in memory and it will fill it, send it back to you. to avoid cross language type missmatch in some cases we use pointer to array rather than implicit array name as pointer. More over it is not guaranteed that the implicit array name is a long pointer, some compilers might optimize it to be a relative value withing segment. a pointer to an array guarantees that it is of the order of machine register size and you can point to a location anywhere in the available RAM.

scienty
  • 314
  • 1
  • 3
0

This will probably careen off into subjective/argumentative, but...

In my opinion, pointers to arrays are in the language because they fell into the language. There are pointers to every other declarable data type, so these are here too. I've never seen anyone get really useful work out of them. Hypothetically, they allow a prototype that demands an array and not a pointer to the element, but ...

bmargulies
  • 97,814
  • 39
  • 186
  • 310
-1

It seems pretty useless to me to do a pointer to an array. In C, an array is already a pointer to a block of that data type.

int (*ap)[N];
int **ipp;

are both the same data type (a pointer to a pointer to an Integer). The only difference there is that there is space for N integers allotted for ap.

There's no need to pass an array by a pointer to a function, like, for the purpose of changing the contents of the array within that function because it's already a pointer. As a general rule, I'd say it's unnecessary and just creates an additional need to dereference the pointer to get at the data in the array. But, I'm sure there's a program or algorithm somewhere that could find a legitimate use for it.

chaosTechnician
  • 1,640
  • 4
  • 18
  • 31
  • 1
    No, they are not the same data type. So you're saying that it's okay to do `ipp = ap;` and `ap = ipp;` (assuming that the pointers are pointing to somewhere useful)? – Alok Singhal Jan 10 '10 at 19:51
  • 1
    They are not the same. Try `++ap` and `++ipp` and see what you get. – Stephen Canon Jan 10 '10 at 20:08
  • 2
    Arrays **are not** pointers. An array *expression* may be implicitly converted to pointer type in most contexts, but that's not the same thing. In your example, `ap` and `ipp` are not compatible types; you could not assign the value of `ap` to `ipp` or vice versa (at least not without an explicit cast). – John Bode Jan 11 '10 at 14:35
-1

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.  

Mayank Jaiswal
  • 12,338
  • 7
  • 39
  • 41
-5

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.

zaharpopov
  • 16,882
  • 23
  • 75
  • 93