2010-10-29 15 views
9

Queste due righe di codice ottengono lo stesso risultato? Se ho avuto queste righe in una funzione, la stringa è memorizzata nello stack in entrambi i casi? C'è una forte ragione per cui dovrei usare l'una sull'altra, oltre a non dover dichiarare il terminatore null nella prima riga di codice?In C, posso inizializzare una stringa in una dichiarazione di puntatore nello stesso modo in cui posso inizializzare una stringa in una dichiarazione di array di caratteri?

char s[] = "string"; 
char* s = "string\0"; 
+7

Solo per informazioni, non è necessario il \ 0 nel secondo esempio. Quando si utilizzano le virgolette doppie, \ 0 viene sempre inserito nell'array. – RMAAlmeida

+0

E proprio per il vocabolario, quello di cui stai parlando non sono compiti, ma dichiarazioni con inizializzatori. Obbediscono a regole diverse. E.La tua prima affermazione non sarebbe consentita come un incarico, non puoi assegnare gli array. –

+0

possibile duplicato di [C: differenze tra puntatore e array] (http://stackoverflow.com/questions/1335786/c-differenze-tra -pointer-e-array) –

risposta

23

No, quelle due linee non ottengono lo stesso risultato.

char s[] = "string" produce un array modificabile di 7 byte, che viene inizialmente riempito con il contenuto 's' 't' 'r' 'i' 'n' 'g' '\0' (tutto copiato in fase di esecuzione da string letterale).

char *s = "string" risultati in un puntatore ad alcuni di sola lettura memoria contenente la "stringa" letterale stringa.

Se si desidera modificare il contenuto della stringa, il primo è l'unico modo per andare. Se hai solo bisogno dell'accesso in sola lettura a una stringa, il secondo sarà leggermente più veloce perché la stringa non deve essere copiata.


In entrambi i casi, non è necessario specificare un terminatore null nella stringa letterale. Il compilatore prende cura di questo per voi quando incontra la chiusura"

+5

Inoltre, il secondo è consentito solo per orribile retaggio motivi. Dovresti usare 'const char * s =" string ";' –

+0

@Steve: per C++ sarei completamente d'accordo con te. Per C, tendo a dare un po 'più margine di manovra, perché in pratica ci sono troppi modi in cui il 'const' si mette sulla tua strada. (Che è anche noto come avvelenamento const) –

+2

Se sto usando librerie dodgy, sono d'accordo con te (a volte). Se il codice è sotto il mio controllo, lo aggiusto in modo che 'const' non si intrometti. L'alternativa è prendere copie di stringhe che devono essere passate come parametri non-const a API dodgy. A volte è fattibile, ad esempio se la stringa che viene passata è un letterale definito vicino alla chiamata, o come globale, quindi usa solo la prima delle due opzioni sopra. Altre volte è un PITA, nel qual caso si può prendere il colpo di strdup o gettare via 'const' (che è" non sicuro ", ma si sta già utilizzando un'API" non sicura "). –

2

La differenza tra questi due.

char a[] = "string"; 
char* b = "string"; 

è che a sia effettivamente una matrice statica sulla pila, mentre b è un puntatore una costante. È possibile modificare il contenuto di una, ma non b.

1

In aggiunta alle altre risposte cercherò di spiegare il motivo per cui non è possibile modificare la variabile *s in seguito il flusso del programma.

Concettualmente quando un il programma è caricato in memoria che dispone di 3 aree (segmenti):

  • segmento di codice: il testo del programma è memorizzato qui (si tratta di una lettura unica area)
  • segmento dati: contiene tutte le variabili globali o statiche che hanno un valore predefinito e modificabile
  • segmento di stack: qui vengono caricate le funzioni come vengono chiamate. L'insieme di valori (uno stack frame) inserito nello stack per ogni chiamata di funzione che contiene l'indirizzo di ritorno della funzione e le variabili locali.

Nel suo caso la variabile s[] è una variabile locale (array), nella funzione main(), che viene inizializzato con il valore "string". Pertanto, viene memorizzato nello stack e può essere modificato.

La variabile *s è un puntatore che punta all'indirizzo "string\0", una costante situata nel segmento di codice. Essendo un'area di sola lettura, non è possibile modificarne il contenuto.

Problemi correlati