3

I study C language and I have some difficulty to understand pointers and arrays.

In tutorial that I read I have this row:

 char* arrP1[] = { "father","mother",NULL }; 

And my question is what is arrP1?

Is it array of pointers to the static strings:

enter image description here

Or it is pointer to the string array:

enter image description here

I am confused...what is arrP1?

Michael
  • 13,950
  • 57
  • 145
  • 288
  • Try using [the clockwise/spiral rule](http://c-faq.com/decl/spiral.anderson.html) and see what you get. – Some programmer dude May 17 '18 at 22:20
  • 2
    Also, the initializer list should be a pretty good hint, as it contains *pointers*. – Some programmer dude May 17 '18 at 22:22
  • @Someprogrammerdude: I think you might be missing something here. Normally you would see `char arrp1[]` or `char* arrp1`, both of which essentially mean the same thing. `char* arrp1[]` means something else. – Robert Harvey May 17 '18 at 22:24
  • 2
    @RobertHarvey I know what `char *arrp1[]` means. And `char *arrp1` and `char arrp1[] = { ... }` are semantically *very* different. – Some programmer dude May 17 '18 at 22:26
  • Only in the sense that the latter is initialized. – Robert Harvey May 17 '18 at 22:27
  • First interpretation is correct (except that the addresses are impossible). – zneak May 17 '18 at 22:27
  • https://stackoverflow.com/questions/859634/c-pointer-to-array-array-of-pointers-disambiguation?rq=1 – andypea May 17 '18 at 22:28
  • @andrew.punnett: Not comparable. Strings are arrays of char. – Robert Harvey May 17 '18 at 22:29
  • 1
    @RobertHarvey `char *x = "foo";` and `char x[] = "foo";` are semantically very different – M.M May 17 '18 at 22:31
  • @RobertHarvey `char *arrp1` is a pointer to (one or more) `char`s. It is exactly the size of a pointer, even if what it points to is not. OTOH, `char arrp1[] = {...}` is *actually* an array of `char`, not a pointer; its size is equal to the number of `char`s in the initialization. The latter can *decay* to a pointer, but is not the same thing. – Daniel H May 17 '18 at 22:31
  • @RobertHarvey E.g. `char arrp1[]` means nothing by itself without an initializer (except as the last member of a `struct`). Arrays in C *must* have a size, and if you don't have an initializer (or an explicit size) then that there isn't any size and the program is invalid. – Some programmer dude May 17 '18 at 22:31
  • Fair enough, I see what you guys mean. – Robert Harvey May 17 '18 at 22:33
  • `NULL` is not a string, it's a pointer. So what does the array in your second picture contain? Remember arrays cannot contain different kinds of things. – n. m. could be an AI May 17 '18 at 22:35

3 Answers3

3

arrP is an array of char * which in this case is an array of size 3, and you've assigned the pointers to c-style strings with initial values of {"father", "mother", NULL}, which themselves are character arrays that are null terminated. So, your first answer is correct.

samuelnj
  • 1,627
  • 1
  • 10
  • 19
2

To find answer for such declerations, you can use cdecl. It'll highly likely answer you.

declare arrP1 as array of pointer to char

However, there is a something that is called as spiral rule. It can also help you to read decleration. For example,

char *str[10]

         +-------+
         | +-+   |
         | ^ |   |
    char *str[10];
     ^   ^   |   |
     |   +---+   |
     +-----------+

-   str is an array of 10 elements
-   str is an array of 10, of pointers
-   str is an array of 10, of pointers, of type char
  • 1
    Note that the spiral rule is a simplification and many people [find it more confusing that helpful](https://stackoverflow.com/questions/16260417/the-spiral-rule-about-declarations-when-is-it-in-error). I prefer to go with "Start with the identifier, read from inside out, starting to the right (and of course obeying parentheses if there are any)". In `char *str[10]`, that gives `str`, then `[10]`, then `*`, then `char`, so `str` is an array of ten pointers to `char`. – Daniel H May 17 '18 at 22:40
  • _"Start with the identifier, read from inside out, starting to the right (and of course obeying parentheses if there are any)". In char *str[10], that gives str, then [10], then *, then char, so str is an array of ten pointers to char_ is what actually spiral rule is. @DanielH – Soner from The Ottoman Empire May 17 '18 at 22:46
  • In that case, as the first answer in the question I linked says, you redefine spiral. The shape you're following for `char **x[10][20][30]` looks nothing like a spiral. – Daniel H May 17 '18 at 22:47
  • ops, yes, that's right. It should be paid attention. Thanks for it. @DanielH – Soner from The Ottoman Empire May 17 '18 at 22:49
1

Not sure if this will help or make things more confusing but arrP1 can be both an array of char* and a char**, like so:

void foo1(char** arr) { cout << arr << endl; }
void foo2(char* arr[]) { cout << arr << endl; }

int main() {
  char *arr[] = {"a", "b"};
  cout << arr << endl;

  foo1(arr);
  foo2(arr);
  return 0;
}

The interesting thing (that I just found out myself) is that foo2 doesn't create a copy of the array on its stack, it's passed arr directly! All 3 cout print the same address.

Related SO Q&A

TV1989
  • 39
  • 6