Este ejemplo funciona bien:

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

Esto no:

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 manera en que yo veo es que en el primer ejemplo se crea una matriz que está lleno de punteros a los dos literales de cadena (que de por sí son matrices). El segundo ejemplo, la OMI, deben ser idénticos a crear una matriz y llenarlo con punteros a los dos arrays de char.

Podría alguien explicarme por qué el segundo ejemplo está mal?

P. S. Usted probablemente podría escribir algo como esto (no lo he 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 que se parece mucho trabajo :).

  • 4 respuestas, pero yo sólo veo una? ¿Cómo ven?
  • Eliminado por el autor.
  • He tenido que pasar el otro día. ASÍ que parece tomar un tiempo para explicar totalmente eliminados respuestas. Se asientan a la derecha de la cuenta «pronto».
InformationsquelleAutor Ree | 2009-03-03

6 Comentarios

  1. 4

    Este:

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

    Es sólo un inicializador de matriz. No crea por sí misma una matriz. El primer ejemplo, cuando se asigna un literal de cadena a un puntero, HIZO crear esas cadenas en almacenamiento estático (oculto), y, a continuación, que acaba de asignar los punteros a ellos.

    Así que, básicamente, no hay manera de inicializar su char* con la matriz de inicializador. Usted necesita crear una matriz, y asignar los números a ella. Lo que tendría que hacer algo como:

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

    Sino que es ilegal.

    Que usted necesita para construir la matriz por separado y asignar en una matriz como el ultimo ejemplo.

    • Nope. Si se especifica la segunda dimensión, la primera puede ser a la izquierda [], de manera que su ejemplo /char a[][12] = {«hola», «mundo»};/ es legal.
    • El primer ejemplo es perfectamente legal – no necesito crear explícita de punteros a cadenas de caracteres. Sin embargo, el problema es que en el SEGUNDO ejemplo.
    • ¿Por qué puedo dejarlos tanto en blanco en el primer ejemplo, pero no el segundo? Los literales de cadena son matrices y he matrices en el segundo ejemplo así?
    • Ahora que has editado tu respuesta, las cosas son mucho más claro ahora. Gracias.
  2. 3

    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 no son char tampoco. Probablemente te interese:

    static int daytab[][13] ...
    • Bueno, eso haría que cada elemento de la matriz principal de tamaño 13. Lo que si quiero tener punteros a arrays de diferentes tamaños? Como para char char – puede ser utilizado para los pequeños valores enteros, por lo que no es un problema aquí.
    • Si se especifica la segunda dimensión, la primera se define a través de una lista de inicializador.
    • Lo sentimos, tu respuesta no es en relación a mi comentario inicial. Si hago lo que usted dice, «que haría cada elemento de la matriz principal de tamaño de 13». Lo que yo busco es la inicialización de un array de punteros a arrays de DIFERENTES tamaños.
    • Usted no puede asignar arbitrariamente tamaño dimensiones – que se lleva a Perl y los de su calaña. Me estaba mostrando un de forma limitada en que se puede resolver el «esto no es» parte de su pregunta.
  3. 3

    Bueno, este hilo ya es un poco viejo, sin embargo yo estaba tratando con el mismo problema y encontrar una manera de inicializar un array de punteros a arrays, como este:

    #include <iostream>
    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 da la salida, al compilar con gnu g++

    0
    1 2
    3 4 5
    6 7 8 9

    y compilar con intel icpc

    0
    1 1
    40896 32767 -961756724
    0 32767 4198878 0

    Así, la sintaxis parece ser, en principio, correcta, sólo que el compilador de intel no correcly apoyo, probablemente debido a la falta de uso común de este estilo.


    — edit —

    Aquí es también una versión en C (como demandados):

    #include <stdio.h>
    
    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] );
    }

    He probado con gcc y de estruendo y se imprime el resultado correcto.
    Btw. el mal de salida del compilador de intel fue un bug del compilador.

    • OK, pero la pregunta es estrictamente C relacionados (ver etiquetas), de modo que hubiera sido mejor si el ejemplo no contienen el código de C++.
    • Además no es exactamente el mismo. Yo estaba buscando el mismo problema, pero tengo la necesidad de matrices para ser nombrado.
  4. 1
    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};
  5. 0

    La sintaxis de tu segundo ejemplo es la sintaxis de un literal de matriz multidimensional.

    Una matriz multidimensional no es un array de punteros a arrays.

    Sería sorprendente si la sintaxis para una cosa era también la sintaxis para una cosa diferente, dependiendo del tipo que se declara.

    En el primer ejemplo, porque un literal de cadena se evalúa a un puntero en lugar de una matriz de valor, el valor se evalúa como una matriz de punteros. Porque 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 de la matriz de valores, no es una matriz cuyos elementos son los punteros a la matriz de valores.

    El código siguiente muestra las combinaciones de matrices multidimensionales, los punteros a arrays, matrices de punteros, y los punteros a punteros. De estos tres, sólo las matrices de punteros y los punteros a punteros son compatibles el uno con el otro:

    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;
    }
  6. 0

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

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

    Nota la const.

    Edit: Y por «no funciona», me refiero a mala práctica y propenso a errores, que es sin duda peor.

Dejar respuesta

Please enter your comment!
Please enter your name here