2015-01-26 19 views
7
string a = "asdf"; 
cout<<&a[0]; 
cout<<a[0]; 

Perché queste due uscite sono diverse? Perché lo &a[0] non è l'indirizzo ma l'intera stringa?qual è la differenza tra un [0] e un [0] nella stringa

+0

si stanno ottenendo il sottostante ' char * 'all'interno di quella stringa come spiegato in dettaglio in questa [risposta] (http://stackoverflow.com/a/4152881/2458319) – mty

risposta

13

&a[0] ha tipo char *. L'operatore di streaming << è volutamente sovraccaricato per gli argomenti const char * per generare una stringa con terminazione a zero (stringa in stile C) che inizia con quell'indirizzo. Per esempio. se si fa

const char *p = "Hello World!"; 
cout << p; 

è che versione di overload di << che consente di verificare la stringa "Hello World!" stesso viene inviato in uscita, non il valore del puntatore.

E questo è esattamente ciò che rende il vostro codice per produrre anche l'intera stringa. Poiché gli oggetti C++ 11 std::string sono necessari per archiviare i propri dati come stringhe a terminazione zero e &a[0] non è nient'altro che un puntatore all'inizio della stringa memorizzata all'interno dell'oggetto a.

+0

Addendum: Usare' & a [0] 'invece di' a' è meno performante e non può far fronte a zero incorporati ... – Deduplicator

1

Quando si stampa un puntatore su un flusso di output di libreria standard, se è char* o const char*, verrà stampata la stringa terminata da null puntata a, anziché l'indirizzo stesso. Se si vuole avere l'indirizzo stampata:

cout << static_cast<const void*>(&a[0]); 

(Curiosità: se il tipo di puntatore non è convertibile in const void* sia --- perché è un puntatore a funzione o un puntatore a membro o è volatile-- -quindi viene convertito in bool.)

1

&a[0] rese tipo char*. Questo è un tipo per il quale lo operator<<() è sovraccarico. Questo particolare sovraccarico stampa i caratteri che iniziano all'indirizzo finché non trova un carattere null, '\0'. Non stamperà l'indirizzo come ci si aspetterebbe.

Dal momento che è necessario l'indirizzo, c'è std::addressof() nella libreria standard:

std::cout << std::addressof(a[0]); 

si può anche lanciare a void* che è quasi come la variante di cui sopra:

std::cout << static_cast<void*>(&a[0]); 
+0

'std :: addressof (a [0])' è esattamente lo stesso di '& a [0]' qui, giusto? –

+0

@MattMcNabb Sì, hanno entrambi lo stesso effetto. Ma 'std :: addressof()' non considererà l'operatore 'sovraccarico 'per i tipi definiti dall'utente. – 0x499602D2

Problemi correlati