views:

550

answers:

5

What is the difference between int *a[3] and int (*a)[3]?

+18  A: 

There is no difference between int a[3] and int (a)[3], they both declare a as an array of 3 ints. There is a difference between int *a[3] and int (*a)[3], the former declares an array of 3 pointers to int whereas the second declares a pointer to an array of 3 ints. The parenthesis make a difference here because in C brackets have a higher precedence than *.

Robert Gamble
+6  A: 

It seems like your asterisks are lost in the formatting...

int *a[3]

declares an array of 3 int*.

int (*a)[3]

declares a as a pointer to a vector of ints. This is really not much different from any other pointer, it just points to a somewhat more complicated type.

int foo[3];
int bar[3];
int (*vp)[3];
vp = &foo;
(*vp)[0] = 0;
CAdaker
+7  A: 

If you have any doubt, using this g++ trick is often handy:

#include <iostream>

template < class T > void describe(T& )
{
  // With msvc, use __FUNCSIG__ instead
  std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main(int argc, char* argv[])
{
  int *a[3];
  describe(a);

  int (*b)[3];
  describe(b);

  return EXIT_SUCCESS;
}

Compile it with g++ and run it, you'll get:

void describe(T&) [with T = int*[3]]
void describe(T&) [with T = int (*)[3]]

So, they are definitely NOT the same ! What you have is:

  1. an array of 3 pointers to int.
  2. a pointer to an array of 3 ints.
bltxd
never heard of __PRETTY_FUNCTION__. Thanks.
David Nehme
The question was about C, this is C++. Also, __PRETTY_FUNCTION__ is a g++ extension, it isn't standard. I think using cdecl as @FreeMemory suggested is much simpler.
Robert Gamble
With msvc, you can use __FUNCSIG__ which provides something similar.
bltxd
The output above doesn't explain anything. It's just the same syntax as the code, but without the `a` and `b` names.
Ropez
+8  A: 

Alternatively, you can use cdecl, which outputs the meaning of variable declarations in English.

cdecl> explain int*a[3]

declare a as array 3 of pointer to int

cdecl> explain int (*a) [3]

declare a as pointer to array 3 of int

FreeMemory
+3  A: 

There is an excellent article to be found at this URL on reading C type declarations. The author, Eli Bendersky, gives a simple method for reading the declarations. You start at the name of the variable and then move along the line pronouncing what you encounter as you walk along. The basic method is to start at the variable name and go right. I'll provide a simple overview, but I highly recommend you read the article.

  1. Start at the variable name and head right.
  2. If you hit a right paren ) or a semicolon ;, then turn back to where you started going right and then go left.
  3. If you encounter a left paren ( while going right, then you have encountered a function declaration, and what follows is its comma-separated list of arguments. Note: you will encounter a right paren at the end of the argument list. The above rule does not apply to this right paren.
  4. If you encounter a left bracket, read it as 'array'.
  5. After going left, when you hit a left paren (, then go back to the right paren where you last went right. Hop over that right paren, and then keep going repeat.
  6. [Repeat]

So, in applying this rule to your particular problem...

In the declaration, " int * a[3]; ", a is the variable name. So, it is read:

a is an array ([) of 3 elements ([3]) of pointers (*) to integers (int)

While in the declaration, " int (* a)[3]; ", a is the variable name. So, it is read:

a is a pointer (*) to an array ([) of 3 elements ([3]) of integers (int)

daveslab