Вопрос по c++, string – Почему потоковый указатель на символ cout не печатает адрес?

1

Когда я печатаю указатель на символ сprintf(), он принимает решение с помощью спецификатора преобразования, должен ли адрес печататься или вся строка в соответствии с% u или% s.

Но когда я хочу сделать то же самое сcout, как будетcout решить, что должно быть напечатано среди адреса и всей строки? Вот пример источника:

int main()
{
  char ch='a';
  char *cptr=&ch;
  cout<<cptr<<endl;
  return 0;
}

Здесь, в моем компиляторе GNU,cout пытается вывести ch в виде строки.

Как я могу получить адресch с помощьюcptr с помощьюcout?

Возможный дубликатcout << with char* argument prints string, not pointer value GingerPlusPlus

Ваш Ответ

4   ответа
4

Я бы просто бросил его в void *, чтобы он не пытался интерпретировать его как C-строку:

cout << (void*) cptr << endl;

Однако более безопасным вариантом будет использование static_cast, как в ответе dirkgently (таким образом, приведение по крайней мере проверяется во время компиляции).

актерский стиль? Разве не было бы безопаснее использовать приведение c ++?
@ dirkgently Ах, не знал этого.
@ Корбин: Дляvoid *, C ++ 11 'sreinterpret_cast это просто хорошо. УвидетьIssue #1120.
@AdrienPlisson Это менее безопасно, чем приведение C ++, кроме reinterpret_cast. В таком тривиальном случае я бы не стал заниматься приведением стиля в C ++, хотя, полагаю, для полноты я должен упомянуть об этом. Трудно предвидеть ситуацию, в которой приведение к void * только для того, чтобы отследить его, в конечном итоге оказалось бы вредным, хотя я уверен, что как только база кода станет достаточно большой, может произойти какое-то действительно странное приведение.
0

cout знает, что печатать, основываясь на типе. Если вы хотите напечатать значение указателя, вы должны привести указатель к void *, который будет интерпретирован как указатель.

14

ostream& operator<<(ostream& o, const char *c); который используется для печати строк в стиле C Вы хотите другойostream& operator<<(ostream& o, const void *p); быть выбранным. Вы, вероятно, лучше всего с актерами здесь:

 cout << static_cast<void *>(cptr) << endl;
@ Зета: Да. Ред.
static_cast<void*> должно быть достаточно в этом случае, так как мы говорим о базовом указателе типа данных.
7

cout печатает строку, если она получаетchar *, просто как тот.

Вот перегрузки дляoperator << заostream:

ostream& operator<< (bool val);
ostream& operator<< (short val);
ostream& operator<< (unsigned short val);
ostream& operator<< (int val);
ostream& operator<< (unsigned int val);
ostream& operator<< (long val);
ostream& operator<< (unsigned long val);
ostream& operator<< (float val);
ostream& operator<< (double val);
ostream& operator<< (long double val);
ostream& operator<< (const void* val);

ostream& operator<< (streambuf* sb);

ostream& operator<< (ostream& ( *pf )(ostream&));
ostream& operator<< (ios& ( *pf )(ios&));
ostream& operator<< (ios_base& ( *pf )(ios_base&));

ostream& operator<< (ostream& out, char c );
ostream& operator<< (ostream& out, signed char c );
ostream& operator<< (ostream& out, unsigned char c );


//this is called
ostream& operator<< (ostream& out, const char* s );
ostream& operator<< (ostream& out, const signed char* s );
ostream& operator<< (ostream& out, const unsigned char* s );

Если вы хотите адрес, вы хотите:

ostream& operator<< (const void* val);

так что вам нужно привести кconst void*.

спасибо за такие подробности ... :) это очень полезно .. amin__

Похожие вопросы