I due sono solo parzialmente equivalenti. La differenza è che:
static char daytab[2][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}
};
dichiara un array bidimensionale, che comprende l'parte spazio per l'array e assicurando che daytab
riferimenti quella memoria. Tuttavia:
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}
};
... dichiara solo un puntatore. Quindi stai provando a inizializzare un puntatore con un inizializzatore di array, che non funziona come previsto. Non c'è array; non c'è memoria riservata per un array. Quello che succede invece è che il primo numero nel tuo inizializzatore è assegnato al puntatore daytab
, e il compilatore genera un avvertimento per farti sapere che hai specificato molti valori aggiuntivi che sono appena scartati. Poiché il primo numero nel tuo inizializzatore è 0
, stai semplicemente impostando daytab
su NULL
in modo piuttosto dettagliato.
Quindi, se si desidera eseguire questa sorta di inizializzazione, utilizzare la prima versione - decade allo stesso tipo di puntatore che si dichiara esplicitamente nella seconda versione, quindi è possibile utilizzarlo allo stesso modo. La seconda versione, con il puntatore dell'array, è necessaria quando si desidera allocare dinamicamente l'array o ottenere un riferimento a un altro array già esistente.
Così si può fare questo:
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
... e poi usare ptr
e arr
intercambiabile. O questo:
static char (*ptr)[3] = NULL;
ptr = malloc(2 * sizeof(*ptr));
... ottenere una allocato dinamicamente matrice a 2 dimensioni (non un array di puntatori ad array 1D, ma una matrice 2D reale). Ovviamente, non è inizializzato in quel caso.
L'"equivalenza" delle due varianti significa semplicemente che l'array 2D, quando decede da un puntatore al suo primo elemento, decade al tipo di puntatore dichiarato nella seconda variante. Una volta che la versione del puntatore è effettivamente puntata su un array, i due sono equivalenti. Ma la versione di array 2D imposta la memoria per l'array, dove la dichiarazione del puntatore non ... e al puntatore può essere assegnato un nuovo valore (puntato su un diverso array) in cui la variabile di array 2D non può.
In C99 si può fare questo, anche se (se non static
almeno):
char (*daytab)[13] = (char [][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}
};
spazio Pila? Se è statico, entra nella sezione dei dati. –
@BrianGordon corretto ... Ho dimenticato la "statica" durante la digitazione di quella parte (penso ... è stato tanto tempo fa). – Dmitri
e quindi si può accedere al puntatore in questo modo '(* (daytab + leap)) [i]' (per quanto riguarda l'esercizio) – Vladimir