2013-04-10 23 views
5

Perché non è possibile indicare un char ** a array di stringhe C ??char ** vs char * c [] per accedere a un array di stringhe

int main(int argc, char *argv[]) { 

    char* c1[] = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //works fine 

vs

int main(int argc, char *argv[]) { 

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 
+6

I puntatori non sono array. –

risposta

6

ritengo la confusione qui deriva dalla convinzione che {"Hey","Hello"} è un array. Non è. Non è affatto un oggetto. È solo una sintassi di inizializzazione speciale che può essere utilizzata per inizializzare un array. Non è possibile utilizzarlo per inizializzare uno char** perché uno char** è un puntatore, non un array. Non crea automaticamente un oggetto array che è possibile convertire in un puntatore.

Forse lo stavi pensando come un elenco [...] in Python o un oggetto { ... } in JavaScript. Non è affatto così. Queste espressioni creano effettivamente oggetti di quel tipo e possono essere utilizzati ovunque in un'espressione che può prendere quegli oggetti.La sintassi che stiamo usando in C++ è solo una sintassi di inizializzazione.

Ad esempio, è potrebbe fare questo:

const char* array[] = {"Hey","Hello"}; 
const char** p = array; 

È, tuttavia, non può fare qualcosa di stupido come questo:

std::cout << {"Hey", "Hello"}[1]; 

Qui abbiamo fatto creato l'oggetto array in cui il i puntatori verranno archiviati. Solo allora possiamo convertire quell'array in un const char**.

+0

Molto chiaro..thanxxx – tez

1

Perché non è possibile puntare un char** di array di stringhe C?

Come hai detto, c1 è un array. Quindi devi dichiararla come un array di puntatori a char.

Dal "Hey" e "Hello" sono litterals stringa, ogni stringa c1[i] è indicando su una stringa anonimo. Ecco perché è possibile utilizzare i puntatori a char anziché gli array di char.

Per creare una serie di puntatori su char, tuttavia, non è possibile utilizzare uno char **.

2

modifica

char** c1 = (char *[]){"Hey","Hello"};

0

"char ** c1", dice compilatore che si tratta di un puntatore a un puntatore per il tipo char, è di tipo scalare (un valore).

inizializzazione con un elenco di valori funziona solo per i tipi di aggregazione.

+0

Non c'è ambiguità in 'char ** c1'. È un puntatore a un puntatore a 'char'. (Naturalmente, entrambi i puntatori di cui sopra potrebbero essere al primo elemento di un array.) –

+0

@James Kanze, sì, mio ​​errore. Cancellato – Arun

0
int main(int argc, char *argv[]) { 

    char** c1 = {"Hey","Hello"}; 
    printf("%s",c1[1]); 

} //error 

Nel codice sopra, si sta tentando di impostare un puntatore a un puntatore su un insieme di due stringhe. Dov'è lo spazio di archiviazione per i due puntatori che contengono rispettivamente l'indirizzo "Hey" e "Hello"? Da nessuna parte.

si potrebbe fare:

char *a = "Hey"; 
char *b = "Hello"; 
char *c[] = { a, b };  // This MAY not compile due to a and b not being compile time constants. 
char **c1 = c; 

(ho dividerlo in più variabili individuali di cui ha bisogno in realtà, ma penso che spiega ciò che è "sbagliato" con il codice abbastanza chiaramente).

Un altro esempio potrebbe essere se cambiamo il char * a int:

const int a = 1; 
const int b = 2; 

int c[] = { a, b }; 

int *c = { a, b }; // Doesn't work, there is nowhere to store a copy of a and b. 

E 'la stessa cosa, se non con numeri interi.