Domanda

Questo esempio funziona bene:

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

Questo non:

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}
};

Il modo in cui lo vedo è che il primo esempio crea un array che è pieno di puntatori ai due letterali di stringhe (che sono essi stessi array). Il secondo esempio, IMO, dovrebbe essere identico: crea un array e riempilo con i puntatori ai due array di caratteri.

Qualcuno potrebbe spiegarmi perché il secondo esempio è sbagliato?

P.S. Probabilmente potresti scriverlo in questo modo (non l'ho testato):

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
};

Ma sembra troppo lavoro :).

È stato utile?

Soluzione

Questa:

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

È solo un inizializzatore di array. Non crea esso stesso un array. Il primo esempio, quando hai assegnato una stringa letterale a un puntatore, DID crea quelle stringhe nella memoria statica (nascosta a te) e quindi assegna loro i puntatori.

Quindi, fondamentalmente, non c'è modo di inizializzare il tuo carattere * con l'inizializzatore di array. È necessario creare un array reale e assegnargli quei numeri. Dovresti fare qualcosa del tipo:

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

Ma questo è illegale.

Devi costruire l'array separatamente e assegnarli in un array come il tuo ultimo esempio.

Altri suggerimenti

Prova:

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}
};

Quelli non sono caratteri *. Non sono neanche caratteri. Probabilmente vuoi:

static int daytab[][13] ...

Bene, questo thread è già un po 'vecchio, tuttavia avevo a che fare con lo stesso problema e ho trovato un modo per inizializzare un array di puntatori su array, come questo:

#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;
}

E ottengo l'output, compilando con gnu g ++

0
1 2
3 4 5
6 7 8 9

e compilazione con intel icpc

0
1 1
40896 32767 -961756724
0 32767 4198878 0

Quindi, la sintassi sembra essere in linea di principio corretta, solo che il compilatore Intel non la supporta correttamente, probabilmente a causa della mancanza di un uso comune di questo stile.


--- modifica ---

Ecco anche una versione C (come richiesto):

#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] );
}

L'ho provato con gcc e clang e stampa il risultato corretto. Btw. l'output errato del compilatore Intel era un bug del compilatore.

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 sintassi del secondo esempio è la sintassi per un array multidimensionale letterale.

Un array multidimensionale non è un array di puntatori ad array.

Sarebbe sorprendente se la sintassi di una cosa fosse anche la sintassi di una cosa diversa, a seconda del tipo dichiarato.

Nel primo esempio, poiché un valore letterale di stringa viene valutato su un puntatore anziché su un valore di array, il valore viene valutato come un array di puntatori. Poiché un valore letterale di array viene valutato come un valore di array anziché come un puntatore, il secondo esempio è un array multidimensionale - un array i cui elementi sono valori di array, non un array i cui elementi sono puntatori a valori di array.

Il codice seguente mostra le combinazioni di matrici multidimensionali, puntatori a matrici, matrici di puntatori e puntatori a puntatori. Di questi tre, solo matrici di puntatori e puntatori a puntatori sono compatibili tra loro:

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;
}

Nota che neanche il tuo primo esempio funziona. Deve essere:

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

Nota la const .

Modifica: e per " non funziona " intendo cattiva pratica e soggetta a errori, che è probabilmente peggiore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top