Abenaki
Abenaki

Reputation: 25

Do brackets have effect during array of pointers declaration?

Recently I was reading "The C programming language" text book by Brain and Dennis and encountered that there is a difference between the pointer array definitions shown below:

int (*a)[10];

int *a [10];

(https://i.sstatic.net/82lnWvfT.png)

In the text book it says like this:

From The C programming language text book

I couldn't quite understand the difference. If

 int (*a)[10];

defines a pointer to an array of 10 integers, what is the use of '*'. And what is the difference between

 int (*a)[10];

 int a [10];

(https://i.sstatic.net/kE2ruHVb.png)

Upvotes: 2

Views: 118

Answers (3)

John Bode
John Bode

Reputation: 123558

In both declarations and expressions, postfix [] and () have higher precedence than unary *, so *a[i] is parsed as *(a[i]) -- we're indexing into a and then dereferencing the result.

By contrast, with (*a)[i] we're dereferencing a and then indexing into the result.

Some code examples and pictures may help:

int x, y, z;
int *a[3] = { &x, &y, &z };

   +---+                 +---+ 
a: |   | a[0]  -----> x: |   | 
   +---+                 +---+   
   |   | a[1]  ---+ 
   +---+          |      +---+
   |   | a[2]  -+ +-> y: |   |
   +---+        |        +---+        
                |        
                |        +---+
                +---> z: |   |
                         +---+


   a[0] == &x // int * == int *
  *a[0] ==  x // int   == int

Contrast with:

int v[3];
int (*a)[3] = &v;

   +---+           +---+
a: |   | -----> v: |   | v[0]  
   +---+           +---+       
                   |   | v[1]
                   +---+
                   |   | v[2]
                   +---+

 a == &v // int (*)[3] == int (*)[3]
*a ==  v // int [3]    == int [3]

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311068

In this declaration

int a [10];

there is declared an array of 10 objects of the type int.

You can check the size of the array the following way

printf( "sizeof( a ) = %zu\n", sizeof( a ) );

If sizeof( int ) is equal to 4 then the above call of printf will output 40: the size of the whole array.

In this declaration

int (*a)[10];

there is declared a pointer to an array of 10 elements.

It to rename the identifier a to p then you can write taking into account the declaration of the array a above:

int a [10];
int ( *p )[10] = &a;

The size of the pointer p is equal to either 4 or 8 depending on the used system. You can check that using the following call of printf:

printf( "sizeof( p ) = %zu\n", sizeof( p ) ):

Dereferencing the pointer you can get the array as a single object pointed to by the pointer p. So if you will write

printf( "sizeof( *p ) = %zu\n", sizeof( *p ) );

you will get the size of the array a.

As for this declaration

int *a [10];

then it declares an array elements of which have the pointer type int *. It would be more readable to rewrite this line like

int * a [10];

Actually this declaration is equivalent to

int * ( a [10] );

Again you can use a call of printf like

printf( "sizeof( a ) = %zu\n", sizeof( a ) );

And the output will be equal to 40 or 80 depending on whether sizeof( int * ) is equal to 4 or 8.

To declare a pointer to this array you can write

int * a [10];
int * ( *p )[10] = &a;

Upvotes: 2

SteelFeather
SteelFeather

Reputation: 1680

This is how I interpret it to make it simple - Right Left rule (recursively). So for the first case

int (*a)[10];

a - nothing on the right due to closing parentheses. Now to the left says its a pointer. So far (*a) means a is a pointer. Now again going to the Right so an array[10] then left of type int. So to complete it - a is pointer to an array of int[10].

int *b [10];

b - to right a is an array of size 10 then to left of int pointers. So b is an array of int* of size 10.

You can verify by checking the size of a & b.

On my machine:

 size of a:8
 size of b:80

Upvotes: 1

Related Questions