1

What is the logic motivating int (*arr)[5]; to declare arr as a pointer to an array of 5 elements, whereas int *arr[5] declares arr as an array of 5 pointers ? Especially given that * has low priority (unsure about this part since it isn't used as the dereferencing operator) ?

asked Oct 12, 2017 at 15:47
4
  • 4
    Consistency with the spiral rule Commented Oct 12, 2017 at 15:49
  • 2
    C declarators use essentially the same syntax that you would use to access the variable being defined. Commented Oct 12, 2017 at 15:50
  • Declares (without allocating) a pointer to an array of int(s). The pointer to the array must be dereferenced to access the value of each element. Commented Oct 12, 2017 at 15:56
  • I found it also pretty complicated, and I am not ashamed to use an intermediate typedef to avoid confusion. Commented Oct 12, 2017 at 16:05

3 Answers 3

3

In both declarations and expressions, postfix operators like [] have higher precedence than unary operators like *, so a declaration like

T *a[N];

is parsed as

T *(a[N]);

Thus

 a -- a is
 a[N] -- an N-element array of
 *a[N] -- pointer to
T *a[N]; -- T

If you want to declare a as a pointer to an array, then you need to explicitly group the * operator with a:

T (*a)[N];

Thus:

 a -- a is
 (*a) -- a pointer to
 (*a)[N] -- an N-element array of
T (*a)[N]; -- T

As luck would have it, you're far more likely to be using an arrays of pointers than pointers to arrays, so it makes sense that the "simpler" form of declaration results in that type.

answered Oct 12, 2017 at 17:06
Sign up to request clarification or add additional context in comments.

Comments

1

You've already stated the reason: * has lower precedence than []. So

int *a[5];

is

int *(a[5]);

meaning that a is an array first, and what it's an array of is pointers.

To me, this is a fine result. I declare arrays of pointers all the time, and int a[5] is convenient syntax. Trying to type int (*a)[5] feels very strange, but that's okay, because I never declare pointers to arrays (because they're virtually never useful).

answered Oct 12, 2017 at 16:38

Comments

0

What is the logic motivating int (*arr)[5];

It depends on the context. For example if you have a two-dimensional array then you can use a pointer of such a type as an iterator.

Here is a demonstrative program

#include <stdio.h>
int main( void )
{
 int a[2][5] = 
 {
 { 0, 1, 2, 3, 4 },
 { 5, 6, 7, 8, 9 }
 };
 for (int(*row)[5] = a; row != a + 2; ++row)
 {
 for (int *col = *row; col != *row + 5; ++col)
 {
 printf("%d ", *col);
 }
 putchar('\n');
 }
 return 0;
}

Or if you have a function that declares its parameter as a two-dimensional array as for example

void f( int a[][5], size_t n );

then the parameter implicitly is adjusted to pointer of the type int ( * )[5]

Take into account that if you have an array like this

int * a[5];

then a pointer to the array will look

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

While if you have an array like this

int a[5];

then a pointer to the array will look like

int ( *p )[5] = &a;
answered Oct 12, 2017 at 16:40

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.