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. Тогда мы увидели бы строку:
Большее из 10, 20 равно false
и все стало бы ясно. По умолчанию литерал false печатается как 0, а true – как 1. Это можно изменить, воспользовавшись манипулятором boolalpha(), что и сделано в следующей программе:
int main()
{
cout "печать значений типа bool по умолчанию: "
true " " false
"\nи в виде строк: "
boolalpha()
true " " false
endl;
}
Вот результат:
печать значений типа bool по умолчанию: 1 0
и в виде строк: true false
Для вывода массива, а также вектора или отображения, необходимо обойти все элементы и напечатать каждый из них:
#include iostream
#include vector
#include string
string pooh_pals[] = {
"Тигра", "Пятачок", "Иа-Иа", "Кролик"
};
int main()
{
vectorstring ppals( pooh_pals, pooh_pals+4 );
vectorstringt::iterator iter = ppals.begin();
vectorstring::iterator iter_end = ppals.end();
cout "Это друзья Пуха: ";
for ( ; iter != iter_end; iter++ )
cout *iter " ";
cout endl;
}
Вместо того чтобы явно обходить все элементы контейнера, выводя каждый по очереди, можно воспользоваться потоковым итератором ostream_iterator. Так выглядит эквивалентная программа, где используется эта техника (подробное обсуждение итератора ostream_iterator см. в разделе 12.4):
#include iostream
#include algorithm
#include vector
#include string
string pooh_pals[] = {
"Тигра", "Пятачок", "Иа-Иа", "Кролик"
};
int main()
{
vectorstring ppals( pooh_pals, pooh_pals+4 );
vectorstring::iterator iter = ppals.begin();
vectorstring::iterator iter_end = ppals.end();
cout "Это друзья Пуха: ";
// копируем каждый элемент в cout ...
ostream_iteratorstring output( cout, " " );
copy( iter, iter_end, output );
cout endl;
}
Программа печатает такую строку:
Это друзья Пуха: Тигра Пятачок Иа-Иа Кролик
Упражнение 20.1
Даны следующие определения объектов:
string sa[4] = { "пух", "тигра", "пятачок", "иа-иа" };
vectorstring svec( sa, sa+4 );
string robin( "кристофер робин" );
const char *pc = robin.c_str();
int ival = 1024;
char blank = ' ';
double dval = 3.14159;
complex purei( 0, 7 );
(a)Направьте значение каждого объекта в стандартный вывод.
(b)Напечатайте значение адреса pc.
(c)Напечатайте наименьшее из двух значений ival и dval, пользуясь оператором условного выражения:
ival dval ? ival : dval
20.2. Ввод
Основное средство реализации ввода – это оператор сдвига вправо (). Например, в следующей программе из стандартного ввода читается последовательность значений типа int и помещается в вектор:
#include iostream