What is the difference between int *a[3]
and int (*a)[3]
?
views:
550answers:
5There is no difference between int a[3]
and int (a)[3]
, they both declare a
as an array of 3 int
s. 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 int
s. The parenthesis make a difference here because in C brackets have a higher precedence than *.
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;
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:
- an array of 3 pointers to int.
- a pointer to an array of 3 ints.
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
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.
- Start at the variable name and head right.
- If you hit a right paren
)
or a semicolon;
, then turn back to where you started going right and then go left. - 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. - If you encounter a left bracket, read it as 'array'.
- 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. - [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
)