Questa struttura
char **Data[70]={NULL};
è un array di 70 puntatori a puntatori a char. Il compilatore alloca i byte 70 * sizeof(char**)
per questo array, che presuppone che i puntatori a 32 bit siano 280 byte.
Se internamente si pensa a un "puntatore al carattere" come una stringa, che non è vero ma è abbastanza vicino, allora questo è un array di 70 puntatori alle stringhe. Per fare un po 'arte ASCII e far finta che avete assegnato e riempito alcuni valori ....
Array of One or more
char ** char *
+---------+ +---------+
| 0 | --> | ptr | --> "Hello, world"
+---------+ +---------+
| 1 |
+---------+ +---------+
| 2 | ----> | ptr2 | --> "Goodbye, cruel world"
+---------+ +---------+
| 3 |
+---------+ +---------+
| 4 | ------> | ptr3[0] | --> "Message 0"
+---------+ +---------+
... | ptr3[1] | --> "Message 1"
+---------+ +---------+
| 69 | | ptr3[2] | --> "Message 2"
+---------+ +---------+
Si potrebbe fare quanto sopra con codice come questo (i valori di ritorno di errore controllo malloc saltati):
char **Data[70]={NULL};
char **ptr, **ptr2, **ptr3;
ptr = (char **) malloc(sizeof(char *));
*ptr = "Hello, world";
Data[0] = ptr;
ptr2 = (char **) malloc(sizeof(char *));
*ptr2 = "Goodbye, cruel world";
Data[2] = ptr2;
ptr3 = (char **) malloc(10 * sizeof(char *));
Data[4] = ptr3;
ptr3[0] = "Message 0";
ptr3[1] = "Message 1";
...
ptr3[9] = "Message 9";
printf("%s\n", *Data[0]);
printf("%s\n", Data[2][0]);
printf("%s\n", Data[4][0]);
printf("%s\n", Data[4][1]);
...
printf("%s\n", Data[4][9]);
Pensateci in questo modo: ogni voce nell'array è un char **
. Ogni voce può puntare a una posizione arbitraria in memoria, detta posizione (s) è char *
e quindi essere in grado di puntare a un array di caratteri terminato da null aka "stringa".
Nota con attenzione la distinzione tra questo e quello che si ottiene quando si assegna una matrice 2D:
char *Data2[10][70]={NULL};
L'assegnazione dei Data2
sopra vi dà una matrice a 2 dimensioni di char *
puntatori, ha detto 2-d array di essere allocati in un singolo blocco di memoria (10 * 70 * sizeof(char*)
byte o 2800 byte con puntatori a 32 bit). Non è possibile assegnare i puntatori a posizioni arbitrarie in memoria con l'array a una dimensione di puntatori .
anche notare (di cui sopra dichiarazioni di Data
e Data2
) che il compilatore genererà il codice diverso per i seguenti riferimenti ad array:
Data[0][0]
Data2[0][0]
Ecco un altro modo di pensare a questo: Immaginate di avere diversi matrici di puntatori a stringhe:
char *table0[] = { "Tree", "Bench", "Stream" };
char *table1[] = { "Cow", "Dog", "Cat" };
char *table2[] = { "Banana", "Carrot", "Broccoli" };
char **Data[3];
Data[0] = table0;
Data[1] = table1;
Data[2] = table2;
Si dispone di un array di puntatori a "matrice di puntatore a carattere". Se ora si stampa il valore di data[1][1]
, pensare in questo modo: ottiene un puntatore all'array table1
. Quindi il valore table1[1]
equivale a "Dog"
.
la tua ottima risposta è stata spudoratamente collegata a questa risposta pet-peeve: http://stackoverflow.com/questions/423823/whats-your-favorite-programmer-ignorance-pet-peeve/484900#484900. evviva :) –
grazie per aver trovato il tempo di scrivere una così buona risposta. Questo chiarisce molto. Per quanto riguarda il tuo primo diagramma, come fai a sapere se il puntatore punta a un singolo puntatore (come ptr2) oa un array di puntatori, come ptr3 [0-2] Può essere sia come nel diagramma? Ad esempio, il tuo secondo diagramma è coerente. Grazie. –
Non c'è modo di sapere a cosa punta esattamente un puntatore char **. Potrebbe puntare a un'area di memoria di qualsiasi dimensione. Senza guardare il codice dove è assegnato, non c'è modo di sapere. – Eddie