3

What is the difference between

char *array[10];

and

char (*array)[10]; ?

By my understanding,

  • Case 1:
    • array is declared as an array of character arrays of size 10.
    • This is because [] has higher precedence than *.
  • Case 2:
    • array is declared as a pointer to a character array of size 10.
    • This is because () and [] have the same precedence and they are evaluated from left-to-right. Then the * operator is evaluated.

Is my understanding correct? Even if it is correct, I get incredibly confused. Can someone please explain the difference a little more clearly?

Anish Ramaswamy
  • 2,326
  • 3
  • 32
  • 63
  • Now the question. The first is not an array of character arrays. It is simply an array of pointer-to-char. For the second, [`()` and `[]`](http://en.cppreference.com/w/c/language/operator_precedence) do indeed have the same precedence as operators, but it is more than that here. these are declarative statements. The parens are used to separate `array` from `[]`, while marrying it to `*`. It sounds like you're pretty close in understanding. – WhozCraig Apr 01 '13 at 05:34

5 Answers5

9

When trying to interpret C's types, switch the [...] (or group of [...][...]...) with the thing to its left, then read right to left. Thus

char *array[10] -> char *[10]array =

"array is an array of 10 pointers to char"

And

char (*array)[10] -> char [10](*array)

"array is a pointer to an array of 10 chars"

So in the first case, array is 10 contiguous pointers, each of which points to a char (which might be a single char, or a sequence of chars such as a string), whereas in the second case, array is a single pointer, to an array of 10 contiguous chars.

You can do something similar with function types, switching the parameter list with the thing to its left. For example,

char* (*f[10])(int*) -> char* (int*)(*[10]f)

"f is an array of 10 pointers to functions taking a pointer to int argument and returning a pointer to char".

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
  • Oh wow. This definitely clears away that fog of confusion! Would this kind of interpretation work for _all_ C declarations? – Anish Ramaswamy Apr 01 '13 at 05:50
  • @AnishRam No, in `int a[3][5]` you don't break `[3][5]` apart, you keep them together as a whole. – Alexey Frunze Apr 01 '13 at 05:54
  • @AnishRam Pretty much (I've added an edit to deal with Alexey's nit). You can extend it to function declarations ... move the parenthesized argument list to the left the same way as moving the array designator. – Jim Balter Apr 01 '13 at 05:57
  • @JimBalter You can have a group of `()` as well if a function returns a pointer to a function that returns a pointer to a function... – Alexey Frunze Apr 01 '13 at 06:03
  • @AlexeyFrunze, I understand enough C to have figured that much out :D. I'm sure that there will be a few corner cases where this will not work (now I do not know why I asked if this would work for all declarations... ahh the confusion!). Thanks for pointing out one! – Anish Ramaswamy Apr 01 '13 at 06:03
  • @AlexeyFrunze Yes, you can, and you can do the same sort of thing with that, moving the parameter list to the left. – Jim Balter Apr 01 '13 at 06:06
3

The first one is probably better referred to as an array of character pointers.

Reading complex pointer definitions can be made easier by recognizing a sort of trick to it. I read this article which helped me out a ton. There is another one that looks nice as well.

Jorge Israel Peña
  • 36,800
  • 16
  • 93
  • 123
1

In the first case array is an array of 10 pointers to a char, if it's not a function parameter as in void some_function(char* array[10]). If it is a function parameter, then it's a pointer to a pointer to a char.

In the second case you have an invalid declaration. See the compilation error here.

In the second case array is a pointer to an array of 10 chars.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • The second case was a typo! I edited the post now. Sorry! Also, in the first case, when you say `array` is an array of 10 pointers, I'm not sure I understand. Does this mean `*` gets evaluated before `[]`? – Anish Ramaswamy Apr 01 '13 at 05:33
  • If you used `*array[0]` in an expression, `array[0]` would evaluate first (as `*(array + 0)`) and then would evaluate `*`, resulting in `*(*(array + 0))`. – Alexey Frunze Apr 01 '13 at 05:39
  • I knew that. I'm just getting quite confused with those declarations. Thanks for your help though! – Anish Ramaswamy Apr 01 '13 at 06:00
1

char *array[10]; is an array of 10 char pointers.

example:

char *array[10] = {"Hello", "Hai"};

where as char (*array)[10]; is a pointer to an array of 10 char.

second one can point to char arr[10];

example

array = &arr;

C pointer to array/array of pointers disambiguation

Community
  • 1
  • 1
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
0

check the "Unscrambling C declarations" section in Deep C Secrets or "Complicated declarations" in K&R...

Darshan Shah
  • 57
  • 1
  • 7