Почему потоковый указатель на символ cout не печатает адрес?

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

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

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

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

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

 GingerPlusPlus05 янв. 2016 г., 17:43

Ответы на вопрос(4)

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

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

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

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

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

Решение Вопроса

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

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

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__03 июн. 2012 г., 12:27
спасибо за такие подробности ... :) это очень полезно ..

Ваш ответ на вопрос