2011-11-09 13 views
16

Si scopre che char c[] = {"a"}; è completamente valido sia in C++03 sia in C++11.Perché un inizializzatore contiene una stringa letterale valida per inizializzare una matrice `char`?

non ci si aspetterebbe che fosse, perché è un array di char non di char const*, e ci si aspetta un tutore-initialiser richiedere un tipo compatibile per ciascuna delle sue "oggetti". Ha un articolo, e questo è un char const* non uno char.

Quindi cosa rende valida questa inizializzazione? E c'è una logica per essere così?


Allo stesso modo, char c[] = {"aa"}; compila e stampa c risultati nell'output "aa".

mi sarei aspetto char c[]{"a"} di essere valido in C++ 11, naturalmente, ma non è la stessa cosa! Allo stesso modo, char c[] = {'a'} è evidente in entrambi, così come lo è char c[] = "a".

+0

Hai provato 'char c [] = {" aa "};'? –

+0

@VJo: valido anche. –

+0

Perché ti aspetti che non sia valido? Non è chiaro cosa stai chiedendo. È valido perché non ci sono regole che lo proibiscano. Quale regola ti aspetteresti di proibirlo? – jalf

risposta

3

I tipi scalari possono anche essere inizializzati utilizzando le parentesi (proprio come le strutture e gli array).

struct S { int x, char c }; 
S s = {5, 'a'}; 

int arr[] = {5, 6, 7}; 

/* (my guess) out of consistency */ 
int z = { 4 }; 

E dal momento che le stringhe letterali possono essere assegnati a char serie di puntatori e

char arr[] = "literal"; 
char* ptr = "another"; 

Sembra giusto per consentire char arr[] = { "literal" }; troppo.

+0

Aha! Penso che abbia senso. Quindi mi stavo riagganciando sull'inizializzatore aggregato, quando in realtà è uno scalare? (Se capisci cosa intendo) Stiamo "vedendo" il letterale come una specie di scalare? –

+0

Sì, almeno è così che penso che abbia avuto origine. Ma io non sono nel comitato standard C :) Sto solo indovinando ... – Pieter

+0

OK; Grazie! –

5

Sebbene possa non essere necessariamente intuitivo, è semplicemente consentito; c'è una regola distinta per questo in entrambi gli standard:

[2003: 8.5.2/1]:A char array (whether plain char , signed char , or unsigned char) can be initialized by a string-literal (optionally enclosed in braces); a wchar_t array can be initialized by a wide string-literal (optionally enclosed in braces); successive characters of the string-literal initialize the members of the array. [..]

[n3290: 8.5.2/1]:A char array (whether plain char , signed char , or unsigned char), char16_t array, char32_t array, or wchar_t array can be initialized by a narrow character literal, char16_t string literal, char32_t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces. Successive characters of the value of the string literal initialize the elements of the array.

non riesco a spiegare il motivo per cui la commissione ha fatto in questo modo, però.

+0

Beh, è ​​un bel tocco.Ora puoi scrivere 'char a [] =" abc ";', 'char b [] = {" abc "};', e 'char c [] {" abc "};' ... –

+0

@KerrekSB: Non vedo come sia utile! –

+0

'Non riesco a spiegare perché il comitato ha fatto in questo modo, però. Potresti aggiungerlo alla domanda dato che è ancora senza risposta. In modo discutibile, la maggior parte delle risposte direbbe 'Perché lo dice lo standard' ma forse forse una buona buona risposta arriva che potrebbe semplicemente dire "perché?" –

0

Suppongo che sia compatibile con C? In realtà, lo T x = { value of T }; si applica anche ad altri tipi di T. Nello standard C99,

6.7.8/11: The initializer for a scalar shall be a single expression, optionally enclosed in braces.

6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces.

6.7.8/15: An array with element type compatible with wchar_t may be initialized by a wide string literal, optionally enclosed in braces.

non so il motivo per cui C ha questo però.

+0

La trama si infittisce. –

+0

Per quanto riguarda la seconda frase, cosa intendi? 'int main() {int i = 3; int * ptr = & i; int x [] = {ptr}; } Errore '->': conversione non valida da 'int *' a 'int'' (come previsto, e come inizialmente mi aspettavo con 'char' ... ... non che l'uso di un puntatore qui sia equivalente a un letterale comunque, ma sai cosa intendo ... sono abbastanza sicuro che sia un caso speciale per 'char'). [modifica: non importa; appena realizzato l'intera citazione chiarisce ciò che hai detto, appunto. Avrei detto "tipi" piuttosto che "tipi" :)] –

+0

@ TomalakGeret'kal: Intendo semplicemente "int * x = {ptr};'. Un puntatore non può essere convertito implicitamente in un array. E stringa letterale è un tipo di matrice (§6.4.5). – kennytm

Problemi correlati