Это:
const char * terry = "hello";
cout<<terry;
выводит hello
вместо адреса памяти 'h'
. Почему это происходит?
Это:
const char * terry = "hello";
cout<<terry;
выводит hello
вместо адреса памяти 'h'
. Почему это происходит?
Причиной этого является то, что std::cout
будет обрабатывать char *
как указатель на (первый символ) строки стиля C и печатать его как таковой. Если вы хотите вместо этого адрес, вы можете просто передать его указателю, который не обрабатывается таким образом, например:
cout << (void *) terry;
(или используйте приведение const void *
, если вы беспокоитесь о том, чтобы покинуть конспирацию, что не является проблемой в данном конкретном случае).
Если вы скорее пурист, чем прагматик, вы также можете использовать С++ static_cast
в соответствии с строками:
cout << static_cast <const void *> (terry);
хотя в этом конкретном случае это необязательно, приведение к void *
будет работать нормально. Следующий пример кода показывает все эти параметры в действии:
#include <iostream>
int main (void) {
const char *terry = "hello";
std::cout << terry << '\n';
std::cout << (void *) terry << '\n';
std::cout << (const void *) terry << '\n';
std::cout << static_cast<const void *> (terry) << '\n';
return 0;
}
(адрес может быть другим в вашей среде):
hello
0x8048870
0x8048870
0x8048870
Обратите внимание, что при использовании static_cast
вы должны убедиться, что не пытаетесь отбросить константу с помощью static_cast <void *>
(для чего предназначен const_cast
). Это одна из проверок, выполненных более новыми С++-переходами, и старинный стиль не имеет этого ограничения.
Оператор <<
на std::cout
перегружен. Его поведение зависит от типа правильного операнда. (На самом деле это несколько разных функций, все они называются operator<<
, компилятор решает, какой из них вызывать.)
Если вы даете ему char*
или const char*
, он обрабатывает операнд как указатель на (первый символ) строки стиля C и печатает содержимое этой строки:
const char * terry = "hello";
cout << terry; // prints "hello"
Если вы даете ему значение char
, оно печатает это значение как символ:
cout << *terry; // prints "h"
cout << terry[0]; // the same
Если вы указали ему указатель типа void*
, он печатает это значение указателя (в определенном варианте реализации, обычно шестнадцатеричном):
cout << static_cast<const void*>(terry); // prints something like 0x4008e4
Рассмотрение char*
или const char*
в качестве указателя на строку C-стиля - это особый случай, и единственное, что я могу придумать, которое вызывает operator<<
для печати чего-либо, кроме значения операнд. Причина этого восходит к корням С++ в C, который не имеет типа "string" и манипулирует строками с помощью указателей char*
.
Существует множество других перегрузок для operator<<
для различных целых чисел и числовых типов с плавающей запятой для std::string
и т.д.
Вы должны изменить свой код на это:
cout << static_cast<const void*>(terry);
Проблема заключается в том, что оператор <<
перегружен для указателей на строки C-стиля для печати содержимого строки. Если вместо этого вы нарисуете его на необработанный указатель, вы будете использовать поведение указателя печати по умолчанию, используя iostreams, как вы хотите.
cout
перегружен, поэтому, когда вы даете ему char*
, он будет печататься как указатель на строку в стиле C. Таким образом, он печатает символы, пока не достигнет нулевого завершающего символа.
Если вы используете printf
вместо cout
, вы увидите адрес. Вы также можете привести указатель к другому типу, скажем, (void*)
, и вы также получите адрес.
std::cout
определяется как std::ostream
с этим определением operator<<
.
В частности, эта строка:
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
const char* s );
Это выбирается, когда вы используете <<
с аргументом типа char*
.
Случай с любым другим типом указателя, отличного от символа, приводится здесь:
basic_ostream& operator<<( const void* value );
Это продолжается до std::num_put
, который предназначен для форматирования числовых значений. Поэтому указатель численно интерпретируется как %p
в функциях форматирования C.
"hello" - это строка, т.е. массив char. const char*
является указателем на этот массив, поэтому, когда вы разыскиваете этот указатель, вы получаете значение первого элемента.
Это похоже на
int a[] = {1, 2, 3};
int *b = a;
cout << *b << endl;
вы получите только 1
.