Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Особенно полезно то, что эту программу можно переписать так:
istream_iterator in_iter(cin), eof; // читает целые числа из cin
vector vec(in_iter, eof); // создает вектор vec из
// диапазона итераторов
Здесь вектор vecсоздается из пары итераторов, которые обозначают диапазон элементов. Это итераторы istream_iterator, следовательно, диапазон получается при чтении связанного потока. Этот конструктор читает поток cin, пока он не встретит конец файла, или ввод, тип которого отличается от int. Прочитанные элементы используются для создания вектора vec.
Поскольку алгоритмы используют функции итераторов, а потоковые итераторы поддерживают по крайней мере некоторые функции итератора, потоковые итераторы можно использовать с некоторыми из алгоритмов. Какие именно алгоритмы применимы с потоковыми итераторами, рассматривается в разделе 10.5.1. В качестве примера рассмотрим вызов функции accumulate()с парой итераторов istream_iterators:
istream_iterator in (cin), eof;
cout << accumulate(in, eof, 0) << endl;
Этот вызов создаст сумму значений, прочитанных со стандартного устройства ввода. Если ввод в этой программе будет таким:
23 109 45 89 6 34 12 90 34 23 56 23 8 89 23
то результат будет 664.
istream_iteratorпозволяют использовать ленивое вычислениеТо, что итератор istream_iteratorсвязан с потоком, еще не гарантирует, что он начнет читать поток немедленно. Некоторые реализации разрешают задержать чтение потока, пока итератор не будет использован. Гарантированно, что поток будет прочитан перед первым обращением к значению итератора. Для большинства программ не имеет никакого значения, будет ли чтение немедленным или отсроченным. Но если создается итератор istream_iterator, который удаляется без использования, или если необходима синхронизация чтения того же потока из двух разных объектов, то тогда придется позаботиться и о моменте чтения.
ostream_iteratorИтератор ostream_iteratorможет быть определен для любого типа, у которого есть оператор вывода (оператор <<). При создании итератора ostream_iteratorможно (необязательно) предоставить второй аргумент, определяющий символьную строку, выводимую после каждого элемента. Это должна быть символьная строка в стиле С (т.е. строковый литерал или указатель на массив с нулевым символом в конце). Итератор ostream_iteratorследует связать с определенным потоком. Не бывает пустого итератора ostream_iteratorили такового после конца.
Таблица 10.4. Операторы итератора ostream_iterator
ostream iterator out(os); |
outпишет значения типа Tв поток вывода os |
ostream_iterator out(os, d); |
outпишет значения типа T, сопровождаемые dв поток вывода os. dуказывает на символьный массив с нулевым символом в конце |
out = val |
Записывает valв поток вывода, с которым связан out, используя оператор <<. Тип valдолжен быть совместим с типом, который можно писать в out |
*out, ++out, out++ |
Эти операторы существуют, но ничего не делают с out. Каждый оператор возвращает итератор out |
Итератор ostream_iteratorможно использовать для записи последовательности значений:
ostream_iterator out_iter(cout, " ");
for (auto e : vec)
*out_iter++ = e; // это присвоение запишет элемент в cout
cout << endl;
Эта программа запишет каждый элемент вектора vecв поток cout, сопровождая каждый элемент пробелом. При каждом присвоении значения итератора out_iterпроисходит запись.
Следует заметить, что при присвоении итератору out_iterможно пропустить обращение к значению и инкремент. Таким образом, этот цикл можно переписать так:
for (auto е : vec)
out_iter = е; // это присвоение запишет элемент в cout
cout << endl;
Операторы *и ++ничего не делают с итератором ostream_iterator, поэтому их пропуск никак не влияет на программу. Но предпочтительней писать цикл как в первом варианте. Он использует итератор единообразно с тем, как используются итераторы других типов. Этот цикл можно легко изменить так, чтобы он выполнялся итераторами других типов. Кроме того, поведение этого цикла понятней читателям нашего кода.
Чтобы не сочинять цикл самостоятельно, можно легко ввести элементы в вектор vecпри помощи алгоритма copy():
copy(vec.begin(), vec.end(), out_iter);
cout << endl;
Итератор istream_iteratorможно создать для любого типа, у которого есть оператор ввода ( >>). Точно так же итератор ostream_iteratorможно определить для любого типа, обладающего оператором вывода ( <<). Поскольку у класса Sales_itemесть оба оператора (ввода и вывода), итераторы ввода-вывода вполне можно использовать, чтобы переписать программу книжного магазина из раздела 1.6:
istream_iterator item_iter(cin), eof;
ostream_iterator out_iter(cout, "\n");
// сохранить первую транзакцию в sum и читать следующую запись
Sales_item sum = *item_iter++;
while (item_iter != eof) {
// если текущая транзакция (хранимая в item_iter) имеет тот же ISBN
if (item_iter->isbn() == sum.isbn())
sum += *item_iter++; // добавить ее к sum и читать следующую
// транзакцию
else {
out_iter = sum; // вывести текущую сумму
sum = *item_iter++; // читать следующую транзакцию
}
}
out_iter = sum; // не забыть вывести последний набор записей
Эта программа использует итератор item_iterдля чтения транзакций Sales_itemиз потока cin. Она использует итератор out_iterдля записи полученной суммы в поток cout, сопровождая каждый вывод символом новой строки. Определив итераторы, используем итератор item_iterдля инициализации переменной sumзначением первой транзакции:
// сохранить первую транзакцию в sum и читать следующую запись
Sales_item sum = *item_iter++;
Выражение осуществляет обращение к значению результата постфиксного инкремента итератора item_iter. Затем оно читает следующую транзакцию и инициализирует переменную sumзначением, предварительно сохраненным в item_iter.
Цикл whileвыполняется до тех пор, пока поток cinне встретит конец файла. В цикле whileосуществляется проверка, не относится ли содержимое переменной sumи только что прочитанная запись к той же книге. Если это так, то только что прочитанный объект класса Sales_itemдобавляется в переменную sum. Если ISBN отличаются, переменная sum присваивается итератору out_iter, который выводит текущее значение переменной sum, сопровождаемое символом новой строки. После вывода суммы для предыдущей книги переменной sum присваивается копия последней прочитанной транзакции и осуществляется инкремент итератора для чтения следующей транзакции. Цикл продолжается до конца файла или ошибки чтения. Перед завершением следует вывести значения по последней книге во вводе.
Интервал:
Закладка: