Выбрать главу

#include iostream

int main()

{

cout "сплетница Анна Ливия\n";

}

печатает на терминале строку:

сплетница Анна Ливия

Имеются операторы, принимающие аргументы любого встроенного типа данных, включая const char*, а также типов string и complex из стандартной библиотеки. Любое выражение, включая вызов функции, может быть аргументом оператора вывода при условии, что результатом его вычисления будет тип, принимаемый каким-либо вариантом этого оператора. Например, программа

#include iostream

#include string.h

int main()

{

cout "Длина 'Улисс' равна:\t";

cout strlen( "Улисс" );

cout '\n';

cout "Размер 'Улисс' равен:\t";

cout sizeof( "Улисс" );

cout endl;

}

выводит на терминал следующее:

Длина 'Улисс' равна:7

Размер 'Улисс' равен:8

endl – это манипулятор вывода, который вставляет в выходной поток символ перехода на новую строку, а затем сбрасывает буфер объекта ostream. (С буферизацией мы познакомимся в разделе 20.9.)

Операторы вывода, как правило, удобнее сцеплять в одну инструкцию. Например, предыдущую программу можно записать таким образом:

#include iostream

#include string.h

int main()

{

// операторы вывода можно сцеплять

cout "Длина 'Улисс' равна:\t";

strlen( "Улисс" ) '\n';

cout "Размер 'Улисс' равен:\t"

sizeof( "Улисс" ) endl;

}

Сцепление операторов вывода (и ввода тоже) возможно потому, что результатом выражения

cout "некоторая строка";

служит левый операнд оператора вывода, т.е. сам объект cout. Затем этот же объект передается следующему оператору и далее по цепочке (мы говорим, что оператор Имеется также предопределенный оператор вывода для указательных типов, который печатает адрес объекта. По умолчанию адреса отображаются в шестнадцатеричном виде. Например, программа

#include iostream

int main()

{

int i = 1024;

int *pi =

cout "i: " i

"\t&i:\t" &&&i&& '\n';

cout "*pi: " *pi

"\tpi:\t" pi endl

"\t\t&pi:\t"&& &pi && endl;

}

выводит на терминал следующее:

i: 1024 &i: 0x7fff0b4

*pi: 1024 pi: 0x7fff0b4

&pi: 0x7fff0b0

Позже мы покажем, как напечатать адреса в десятичном виде.

Следующая программа ведет себя странно. Мы хотим напечатать адрес, хранящийся в переменной pstr:

#include iostream

const char *str = "vermeer";

int main()

{

const char *pstr = str;

cout "Адрес pstr равен: "

pstr endl;

}

Но после компиляции и запуска программа неожиданно выдает такую строку:

Адрес pstr равен: vermeer

Проблема в том, что тип const char* интерпретируется как C-строка. Чтобы все же напечатать адрес, хранящийся в pstr, необходимо подавить обработку типа const char* по умолчанию. Для этого мы сначала убираем спецификатор const, а затем приводим pstr к типу void*:

static_cast void*(const_cast char*(pstr))

Теперь программа выводит ожидаемый результат:

Адрес pstr равен: 0x116e8

А вот еще одна загадка. Нужно напечатать большее из двух чисел:

#include iostream

inline void

max_out( int val1, int val2 )

{

cout ( val1 val2 ) ? val1 : val2;

}

int main()

{

int ix = 10, jx = 20;

cout "Большее из " ix

", " jx " равно ";

max_out( ix, jx );

cout endl;

}

Однако программа выдает неправильный результат:

Большее из 10, 20 равно 0

Проблема в том, что оператор вывода имеет более высокий приоритет, чем оператор условного выражения, поэтому печатается результат сравнения val1 и val2. Иными словами, выражение

cout ( val1 val2 ) ? val1 : val2;

вычисляется как

(cout ( val1 val2 )) ? val1 : val2;

Поскольку val1 не больше val2, то результатом сравнения будет false, обозначаемый нулем. Чтобы изменить приоритет операций, весь оператор условного выражения следует заключить в скобки:

cout ( val1 val2 ? val1 : val2 );

Теперь результат получается правильный:

Большее из 10, 20 равно 20

Такого рода ошибку было бы проще найти, если бы значения литералов true и false типа bool печатались как строки, а не как 1 и 0. Тогда мы увидели бы строку: