Inicializando una matriz de punteros a punteros

Este ejemplo funciona bien:

static char *daytab[] = { "hello", "world" }; 

Esto no hace

 static char *daytab[] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; 

La forma en que lo veo es que el primer ejemplo crea una matriz que está llena de punteros a los dos literales de cadena (que a su vez son matrices). El segundo ejemplo, IMO, debe ser idéntico: cree una matriz y rellénela con punteros a las dos matrices de caracteres.

¿Podría alguien explicarme por qué el segundo ejemplo es incorrecto?

PS Probablemente puedas escribirlo así (no lo hayas probado):

 static char a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static char b[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static char *daytab[] = { a, b }; 

Pero eso parece demasiado trabajo :).

Esta:

 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 

Es sólo un inicializador de matriz. No crea una matriz. El primer ejemplo, cuando asignó un literal de cadena a un puntero, DID crea esas cadenas en almacenamiento estático (oculto para usted), y luego simplemente les asigna los punteros.

Básicamente, no hay forma de inicializar su char * con el inicializador de matriz. Debe crear una matriz real y asignarle esos números. Tendrías que hacer algo como:

 char a[][] = { {32, 30, 0}, {34, 32, 33, 0} }; // illegal 

Pero eso es ilegal.

Debe crear la matriz por separado y asignarlas a una matriz como su último ejemplo.

Tratar:

 static char daytab[][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; 

Esos no son char * ‘s. Ellos tampoco son char. Probablemente quieras:

 static int daytab[][13] ... 

Bueno, este hilo ya es un poco viejo, sin embargo, estaba lidiando con el mismo problema y encontré una manera de inicializar una serie de punteros a matrices, como esto:

 #include  using namespace std; int *a[] = { (int[]) { 0 } , (int[]) { 1 , 2 } , (int[]) { 3 , 4 , 5 } , (int[]) { 6 , 7 , 8 , 9 } }; main() { cout << a[0][0] << endl << a[1][0] << " " << a[1][1] << endl << a[2][0] << " " << a[2][1] << " " << a[2][2] << endl << a[3][0] << " " << a[3][1] << " " << a[3][2] << " " << a[3][3] << endl; } 

Y me sale la salida, comstackndo con gnu g ++

 0 1 2 3 4 5 6 7 8 9 

y comstackndo con intel icpc

 0 1 1 40896 32767 -961756724 0 32767 4198878 0 

Por lo tanto, la syntax parece ser correcta en principio, solo que el comstackdor de Intel no la soporta correctamente, probablemente debido a la falta de uso común de este estilo.


--- editar ---

Aquí también hay una versión C (según lo exigido):

 #include  int *a[] = { (int[]) { 0 } , (int[]) { 1 , 2 } , (int[]) { 3 , 4 , 5 } , (int[]) { 6 , 7 , 8 , 9 } }; int main() { printf( "%d\n" , a[0][0] ); printf( "%d %d\n" , a[1][0] , a[1][1] ); printf( "%d %d %d\n" , a[2][0] , a[2][1] , a[2][2] ); printf( "%d %d %d %d\n" , a[3][0] , a[3][1] , a[3][2] , a[3][3] ); } 

Lo probé con gcc y clang e imprime el resultado correcto. Por cierto La salida incorrecta del comstackdor de Intel fue un error del comstackdor.

 static char **daytab; daytab=(char**)malloc(2*sizeof(char*)); daytab[0]=(char*)(char[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; daytab[1]=(char*)(char[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

La syntax de su segundo ejemplo es la syntax de una matriz literal multidimensional.

Una matriz multidimensional no es una matriz de punteros a matrices.

Sería sorprendente si la syntax para una cosa fuera también la syntax para una cosa diferente, según el tipo que se declare.

En el primer ejemplo, como un literal de cadena se evalúa como un puntero en lugar de un valor de matriz, el valor se evalúa como una matriz de punteros. Dado que un literal de matriz se evalúa como un valor de matriz en lugar de un puntero, el segundo ejemplo es una matriz multidimensional: una matriz cuyos elementos son valores de matriz, no una matriz cuyos elementos son punteros a valores de matriz.

El siguiente código muestra las combinaciones de matrices multidimensionales, punteros a matrices, matrices de punteros y punteros a punteros. De estos tres, solo las matrices de punteros y punteros a punteros son compatibles entre sí:

 void multi_array (int x[][4], size_t len) // multidimensional array { for (size_t i = 0; i < len; ++i) for (size_t j = 0; j < 4; ++j) putchar( 'a' + x[i][j] ); putchar('\n'); } void ptr_array (int (*x)[4], size_t len) // pointer to an array { ... as multi_array } void array_ptr (int *x[], size_t len) // array of pointers { ... as multi_array } void ptr_ptr (int **x, size_t len) // pointer to pointer { ... as multi_array } int main() { int a[][4] = { { 1,2,3,4 } }; int b[] = { 1,2,3,4 }; int* c[] = { b }; multi_array( a, 1 ); multi_array( (int[][4]) { { 1,2,3,4} }, 1 ); // literal syntax as value ptr_array( &b, 1 ); array_ptr( c, 1 ); ptr_ptr( c, 1 ); // only last two are the same return 0; } 

Tenga en cuenta que su primer ejemplo no funciona, tampoco. Necesita ser:

 static const char *daytab[] = { "hello", "world" }; 

Tenga en cuenta la const .

Edit: Y por “no funciona”, me refiero a la mala práctica y propenso a los errores, que posiblemente sea peor.