5

Are

int (*x)[10];

and

int x[10];

equivalent?

According to the "Clockwise Spiral" rule, they parse to different C declarations.

For the click-weary:

The ``Clockwise/Spiral Rule'' By David Anderson

There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!

There are three simple steps to follow:

   1. Starting with the unknown element, move in a spiral/clockwise direction; 
          when ecountering the following elements replace them with the 
          corresponding english statements:

      [X] or []
          => Array X size of... or Array undefined size of... 
      (type1, type2)
          => function passing type1 and type2 returning... 
      *
          => pointer(s) to... 

   2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.

   3. Always resolve anything in parenthesis first! 
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • @crypto - Why did you update your question with exactly the answer I provided below? – Wayne Mar 25 '11 at 18:21
  • I assume the high vote comes from the fact that the question references the clockwise spiral rule. I am quite proficient in C and have never heard of it before. – blubb Mar 25 '11 at 18:22
  • @lwburk, I'm quoting ad verbatim from the hyperlink in my question, which was very much in place before the edit. –  Mar 25 '11 at 18:24
  • 3
    @crypto - Then I am confused about your confusion. If you already know they are different, then why are you asking whether they're different? Are you asking why "x is a pointer to an array of 10 ints" does not mean the same thing as "x is an array of 10 pointers to ints"? – Wayne Mar 25 '11 at 18:27
  • @lwburk, I felt it would be trite to state the obvious. –  Mar 25 '11 at 18:33
  • -1, I'm with @lwburk, not a high quality question. – user7116 Mar 25 '11 at 19:02
  • 1
    @crypto: If you know that they aren't equivalent, and everyone here verifies that they aren't equivalent, then I'm confused as to why you are claiming the question is unanswered? What obvious thing are you not stating? Unless we are all missing something, I'm inclined to give a -1 along with sixlettervariables. – BMitch Mar 25 '11 at 19:13
  • I suspect the issue is that OP is confused by "arrays are pointers" (false) and thus thinks "pointer to array of 10 ints" is the same thing as "array of 10 ints"... – R.. GitHub STOP HELPING ICE Mar 25 '11 at 19:59

5 Answers5

9

Follow this simple process when reading declarations:

Start at the variable name (or innermost construct if no identifier is present. Look right without jumping over a right parenthesis; say what you see. Look left again without jumping over a parenthesis; say what you see. Jump out a level of parentheses if any. Look right; say what you see. Look left; say what you see. Continue in this manner until you say the variable type or return type.

So:

int (*x)[10];

x is a pointer to an array of 10 ints

int x[10];

x is an array of 10 ints

int *x[10];

x is an array of 10 pointers to ints

Wayne
  • 59,728
  • 15
  • 131
  • 126
  • 1
    that is precisely equivalent to the "Clockwise Spiral" rule. My question is left unanswered. –  Mar 25 '11 at 18:17
  • 4
    @crypto - I'm confused. Why do you think your question is unanswered? – Wayne Mar 25 '11 at 18:22
8

They are not equal. in the first case x is a pointer to an array of 10 integers, in the second case x is an array of 10 integers.

The two types are different. You can see they're not the same thing by checking sizeof in the two cases.

6502
  • 112,025
  • 15
  • 165
  • 265
4

I tend to follow The Precedence Rule for Understanding C Declarations which is given very nicely in the book Expert C Programming - Deep C Secrets by Peter van der Linden

A - Declarations are read by starting with the name and then reading in 
precedence order.

B - The precedence, from high to low, is:
        B.1 parentheses grouping together parts of a declaration
        B.2 the postfix operators:
        parentheses () indicating a function, and
        square brackets [] indicating an array.
        B.3 the prefix operator: the asterisk denoting "pointer to".

C If a const and/or volatile keyword is next to a type specifier (e.g. int, 
        long, etc.) it applies to the type specifier. 
        Otherwise the const and/or volatile keyword 
        applies to the pointer asterisk on its immediate left.
Sadique
  • 22,572
  • 7
  • 65
  • 91
2

For me, it's easier to remember the rule as absent any explicit grouping, () and [] bind before *. Thus, for a declaration like

T *a[N];

the [] bind before the *, so a is an N-element array of pointer. Breaking it down in steps:

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

For a declaration like

T (*a)[N];

the parens force the * to bind before the [], so

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

It's still the clockwise/spiral rule, just expressed in a more compact manner.

John Bode
  • 119,563
  • 19
  • 122
  • 198
-4

No. First one declares an array of 10 int pointers and second one declares an array of 10 ints.

Scorpions4ever
  • 444
  • 4
  • 2
  • 3
    Nope, the first one is a pointer to an array of 10 ints (you'll hardly ever need such a pointer). an array of 10 int pointers would be `int *x[10]` – nos Mar 25 '11 at 18:08
  • I'm inclined to believe you are incorrect, the syntax for an array of 10 pointers is `int *x[10];` –  Mar 25 '11 at 18:10