What is the difference between char s[] and char *s?

  • first is 2 dimensional array of char
  • second is array of pointer to char
  • third is pointer to an array of char

While declaration was covered, perhaps differences in usage should also be pointed out:

char s[5][5]; --

  • s points to an area of allocated memory (heap if global, stack if local),
  • you may safely write up to 25 char values at s[0][0] .. s[4][4] (or at s[0] .. s[24]),
  • sizeof(s) == 25.

char *s[5]; --

  • s points to an area of allocated memory (heap if global, stack if local),
  • you may safely write up to 5 pointer values at s[0] .. s[4],
  • sizeof(s) == 40 (*).

char (*s)[5]; --

  • s does not point to any allocated memory -- it's merely an uninitialized pointer at this point,
  • you may safely write one pointer value at &s,
  • sizeof(s) == 8 (*).

(*) note: assuming a 64-bit architecture.


In C, it is better to speak out the declaration. Then, it becomes intuitive. For this, you follow the right-left convention. Here is how it goes:

char *s[5];

How do you speak it? For that you start at the right of the variable name s and then go to the left. So you start by saying "s is a/an", On the right, you see a [] and you say "s is an array ... ". And then you go to the left and see the *, and say "s is an array of pointers." And that is what it is. It si an array of 5 pointers. You can store different pointers in this array.

Now for the other one:

char (*s)[5];

You start the same way. "s is a/an", and then look at the (). Anything within the () is bound to s closer than anything outside. So the * is more closely bound with s than []. So You now say, "s is a pointer ..." and now you go out of the parenthesis and see the []. So you continue, "s is a pointer to an array". And that is exactly what it is. It is a pointer, which will point to the first element of an array.

Now follow the same logic and try to guess what the following will be:

int (*callme)(int a, int b)
int (*callme[10])(int a, int b)

Hint, the last one can be used to create lookup tables for functions.

Edit:

As mentioned in the comments, there is also a char in the beginning. I have never ben able to figure out an easy way of speaking this, but is generally clear from the context. For example, in the first example, the char defines the type of the array, while in the second example, it defines pointer. In the exercises I have posted, the int defines the type for the return values of the functions. Generally with definitions such as these, there will be exactly one item with the undefined type. And thats how I figure out where the type goes.