1

I want to declare an array of pointers to array of pointers to char and initialize it. But i couldn't declare and initialize it using the following way:

char *(*array[])[] = {
  { "car", "toy", "game" },
  { "go", "play", "read" }
};

Please write the correct form of my declaration and initialization? I get warning messages like "warning: brace around scalar initializer" and also "note: (near initialization for 'array[0]' )"

  • The initializer you have is an array of two arrays of three pointers to (read-only) characters. Optionally it could be an array of two arrays of three arrays of X characters (where X is large enough to fit the largest string). – Some programmer dude May 03 '19 at 16:22
  • Found a bug in https://cdecl.org/ -- `char *(*array[])[]` doesn't work because it doesn't handle the word array. `char *(*Array[])[]` does. https://cdecl.org/?q=char+*%28*Array%5B%5D%29%5B%5D%3B – Petr Skocik May 03 '19 at 16:33

2 Answers2

1

Before C99, you had to define the inner arrays separately:

#include <stdio.h>

int main() {
    const char *array_0[] = { "car", "toy", "game" };
    const char *array_1[] = { "go", "play", "read" };
    const char **array[] = { array_0, array_1 };
    int i, j;

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

With C99, you can now define and initialize the same object directly:

#include <stdio.h>

int main() {
    const char **array[] = {
        (const char *[]){ "car", "toy", "game" },
        (const char *[]){ "go", "play", "read" },
    };

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Of course this is more flexible than a 2D matrix: each inner array can have a different size, as in:

#include <stdio.h>

int main() {
    const char **array[] = {
        (const char *[]){ "car", "toy", "game", NULL },
        (const char *[]){ "go", "play", NULL },
        (const char *[]){ "read", NULL },
        NULL,
    };

    for (int i = 0; array[i]; i++) {
        for (int j = 0; array[i][j]; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Output:

car toy game 
go play 
read 

Note that I added the const keyword because string literals should not be modified, so pointers to them should be defined as const char *.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
0
char *(*array[])[] = {
    &(char*[]){"car","toy","game" },
    &(char*[]){"go","play","read" }
};

compiles without a warning.

It's not nested arrays, it's an array of pointers (&) to arrays of char* (char*[]`) so I don't think you can do without either compound literals or separate array objects to make array pointers out of.

(Don't forget that assigning to char* from string literals is kind of a bad practice as string literals are practically, though not formallychar const[], so usingchar const*instead ofchar *` would be preferable.)

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    Please don't encourage the OP... ;) – Some programmer dude May 03 '19 at 16:24
  • This does not work: `array` cannot be used as an array of arrays of pointers to `char`. `printf("%s ", array[i][j]);` produces an error: `arrarr.c:22:35: error: subscript of pointer to incomplete type 'const char *[]'` – chqrlie May 03 '19 at 18:07