Letterale inizializzatore stringa per un array di caratteri
Domanda
Nelle seguenti regole per il caso in cui matrice decade di puntatore:
Un lvalue [vedere domanda 2.5] di tipo array-of-T che appare in un'espressione decade (con tre eccezioni) in un puntatore al suo primo elemento; il tipo del puntatore risultante è puntatore a T.
(eccetto quando l'array è l'operando di sizeof o & operatore, oppure è un inizializzatore stringa letterale per un array di caratteri.)
Come capire il caso in cui la matrice è "inizializzatore stringa letterale per un array di caratteri"? Alcuni esempi per favore.
Grazie!
Soluzione
I tre eccezioni in cui una matrice non decade in un puntatore sono i seguenti:
eccezione 1 -.. Quando la matrice è l'operando di sizeof
int main()
{
int a[10];
printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */
int* p = a;
printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}
eccezione 2 -.. Quando la matrice è l'operando dell'operatore &
int main()
{
int a[10];
printf("%p", (void*)(&a)); /* prints the array's address */
int* p = a;
printf("%p", (void*)(&p)); /*prints the pointer's address */
}
eccezione 3 -.. Quando l'array è inizializzato con una stringa letterale
int main()
{
char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */
char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}
Altri suggerimenti
Si assuma le dichiarazioni
char foo[] = "This is a test";
char *bar = "This is a test";
In entrambi i casi, il tipo della stringa letterale "This is a test
" è "15-elemento array di char". In molte circostanze, espressioni di matrice sono implicitamente convertiti dal tipo "N-elemento array di T" a "puntatore a T", e l'espressione restituisce l'indirizzo del primo elemento della matrice. Nella dichiarazione per bar
, questo è esattamente ciò che accade.
Nella dichiarazione per foo
, tuttavia, l'espressione viene utilizzato per inizializzare il contenuto un'altra matrice, e quindi non convertito in un tipo di puntatore; invece, contenuto della stringa letterale vengono copiati foo
.
Questo è un inizializzatore stringa letterale per un array di caratteri:
char arr[] = "literal string initializer";
Potrebbe anche essere:
char* str = "literal string initializer";
Definizione da K & R2:
Una stringa letterale, chiamato anche una stringa costante, è una sequenza di caratteri circondato da virgolette doppie come in "...". Una stringa ha tipo `` array di caratteri '' e la classe di archiviazione statica (Vedi Par.A.3 sotto) ed è inizializzata con i caratteri dati. Se identici stringhe sono distinti è definito dall'implementazione, e comportamento di un programma che tenta di alterare una stringa letterale non è definito.
Sembra che hai tirato quella citazione dal FAQ comp.lang.c (forse una vecchia versione o forse la versione stampata, lo fa non proprio incontro con l'attuale stato di quella on-line):
http://c-faq.com/aryptr/aryptrequiv.html
I collegamenti sezione corrispondente ad altre sezioni del FAQ di elaborare su tali eccezioni. Nel tuo caso, si dovrebbe guardare a: