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

Dlaczego te dwa wyjścia różnią się od siebie? Dlaczego &a[0] nie jest adresem, ale całym ciągiem znaków?Jaka jest różnica między [0] a & a [0] w łańcuchu

+0

otrzymujesz bazowy ' char * "wewnątrz tego łańcucha, jak wyjaśniono szczegółowo w tym [odpowiedź] (http://stackoverflow.com/a/4152881/2458319) – mty

Odpowiedz

13

&a[0] ma typ char *. Operator strumienia << jest celowo przeciążany dla argumentów const char *, aby wyprowadzić łańcuch zakończony znakiem zerowym (ciąg w stylu C) rozpoczynający się pod tym adresem. Na przykład. jeśli nie

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

to, że przeciążony wersja << że pilnuje sam ciąg "Hello World!" jest wysyłany do wyjścia, a nie wartość wskaźnika.

I to jest dokładnie to, co sprawia, że ​​twój kod również wypisuje cały ciąg. Ponieważ obiekty C++ 11 std::string są wymagane do przechowywania ich danych jako łańcuchów zakończonych zerem, a &a[0] to nic innego jak wskaźnik do początku ciągu przechowywanego wewnątrz obiektu a.

+0

Dodatek: użycie' i a [0] 'zamiast' a' jest mniej wydajne i nie może radzić sobie z osadzonymi zerami ... – Deduplicator

1

Podczas drukowania wskaźnika do strumienia wyjściowego standardowej biblioteki, jeśli jest to char* lub const char*, zostanie wydrukowany łańcuch zakończony znakiem pustym, a nie sam adres. Jeśli chcesz mieć adres wydrukowane:

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

(Ciekawostki: jeśli typ wskaźnik nie jest wymienialny na const void* albo --- ponieważ jest to wskaźnik funkcji lub wskaźnikiem do członka lub jest volatile-- -później zostanie przekonwertowany na bool.)

1

&a[0] plony typu char*. Jest to typ, dla którego operator<<() jest przeciążony. To przeciążenie drukuje znaki zaczynające się od adresu, dopóki nie znajdzie znaku pustego, '\0'. Nie wydrukuje adresu, jak można się spodziewać.

ponieważ trzeba adres, tam std::addressof() w bibliotece standardowej:

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

można również rzutować na void* który jest prawie jak w powyższym wariancie:

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

'std :: addressof (a [0])' jest dokładnie takie samo jak '& a [0]' tutaj, prawda? –

+0

@MattMcNabb Tak, oba mają ten sam efekt. Ale 'std :: addressof()' nie bierze pod uwagę przeciążonego 'operatora &' dla typów zdefiniowanych przez użytkownika. – 0x499602D2

Powiązane problemy