9

So I want to give an example:

int *pi; // pi is a pointer that points to an integer
const int *cpi; // cpi is a pointer that points to a constant integer
char *pc; // pc is a pointer to a char 

How can I read these:

char **x; //x is a pointer to a char pointer?
char *y[];
char **z[];

Thanks.

haccks
  • 104,019
  • 25
  • 176
  • 264
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
  • 7
    [cdecl.org](http://cdecl.org) – Bill Lynch Apr 12 '15 at 15:41
  • @BillLynch Not really correct I think. Should not this be char *titles[] equal to char **titles; ? – Koray Tugay Apr 12 '15 at 15:45
  • 3
    http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c – Bill Lynch Apr 12 '15 at 15:52
  • @BillLynch And, so?? – Koray Tugay Apr 12 '15 at 15:53
  • @KorayTugay If it's a declaration with an initializer, as in `char *title[] = { "Title1", "Title2" };`, then "declare titles as array of pointer to char" is correct. If it's a function parameter, then the declaration would still state "array of pointer to char" because array notation was used, even though the array decays into a pointer, so it's still correct. –  Apr 12 '15 at 15:54
  • `char *titles[]` and `char ** titles` are two different types. They're not the same. That link describes a few ways in which they are different. – Bill Lynch Apr 12 '15 at 15:54
  • 1
    @BillLynch: Depends where it is placed. In a function's parameter list `T * t[]` is equal to `T ** t`. – alk Apr 12 '15 at 15:56
  • @alk: And the code in the question has semicolons after each declaration. So they are declarations and not function arguments. – Bill Lynch Apr 12 '15 at 15:56
  • @BillLynch; What if I want to write a program like `cdecl.org`? – haccks Apr 12 '15 at 16:08
  • @haccks I think he is looking for a link to answer that :) – Koray Tugay Apr 12 '15 at 16:20

4 Answers4

15

cdecl.org is often linked to such questions. No doubt that it make easier to decipher any complex declaration, but at the same time it just provide an abstracted information. Being a C or C++ programmer one should know how to decipher complex declaration manually. Spiral Rule help to some extent but fails in some cases. This answer will help programmers to decipher any complex declaration manually.


Remember these two simple rules:

  1. Always read declaration from the inside out.
  2. When there is a choice, always favor [] and () over *.

The first rule simply states that, locate the variable that is being declared and start deciphering the declaration from it.

For second rule, if * precedes the identifier and [] or () follows it, then the identifier represents an array or function (respectively), not a pointer.

Example 1:

char *y[5]; 
  • Variable/identifier is y.
  • * precedes y and follows [].
  • y must be an array.

Combining above deciphering will result in: y is an array of 5 pointers to char.

Also note that you can always use parentheses to override the normal priority of [] or ().

Example 2:

void (*pf) (int);
  • Variable/identifier is pf.
  • *pf is enclosed in parenthesis, it must be a pointer.
  • () follows *pf, means pf must points to a function.
  • Since () encloses int, function must expects an argument of type int.

So, pf is a pointer to function that expects an int argument and returns nothing.

Now, what would you get after deciphering the following declaration

int *(*a[5])(void);  

?

Answer:

a is an array of pointers to functions that expects no argument and returning pointer to int.


Note: Note that both of

char *y[];
char **z[];  

will cause compilation error if they are not declared as arguments of a function. If they are function's argument then char *y[] is equivalent to char **y and char **z[] is equivalent to char ***z.
If that's not the case, then you need to specify the dimension as I did in my first example.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
5

Some example C declarations taken from the HELPPC utility (by David Jurgens) that saved my (programming) life back in the nineties (online version of the utility here: http://stanislavs.org/helppc )

int i;                  i as an int
int *i;                 i as a pointer to an int
int **i;                i is a pointer to a pointer to an int
int *(*i)();            i is a pointer to a function returning a
                          pointer to int
int *(*i[])();          i is an array of pointers to functions
                          returning pointers to an int
int *i[5];              i is an array of 5 pointers to int
int (*i)[5];            i is a pointer to an array of 5 ints
int *i();               i is a function returning a pointer to an int
int (*i)();             i is a pointer to a function returning int
int *(*(*i)())[5]       i is a pointer to a function returning a
                          pointer to an array of 5 pointers to an int
mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
0

y is an array of pointers to char, z is an array of pointers to pointer to char. x is a pointer to pointer to char

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Why do you think `y` is an array of pointers to `char`? To me, it look like `y` is not an array. – haccks Apr 12 '15 at 16:26
0
char **x; //x is a pointer to a pointer to char
char *y[]; // y is an array of pointers to char
char **z[]; // z is an array of pointers to pointers to char
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • in general, the easiest way to read such expressions is to start at the right end and read to the left end – user3629249 Apr 12 '15 at 16:00
  • 1
    @KorayTugay, the definition of 'x' does not indicate that there will be multiple characters nor that the multiple characters will be terminated with a NUL byte. However context may show that to be true. – user3629249 Apr 12 '15 at 16:02
  • 1
    `y` is not an array of `char` pointers. It will cause compilation error. Same for `z`. – haccks Apr 12 '15 at 16:06