Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Перепишем программу, изменяющую регистр первого слова в строке, с использованием итератора.
// обрабатывать символы, пока они не исчерпаются,
// или не встретится пробел
for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it)
*it = toupper(*it); // преобразовать в верхний регистр
Этот цикл, подобно таковому в разделе 3.2.3, перебирает символы строки s
, останавливаясь, когда встречается пробел. Но данный цикл использует для этого итератор, а не индексирование.
Цикл начинается с инициализации итератора it
результатом вызова функции s.begin()
, чтобы он указывал на первый символ строки s
(если он есть). Условие проверяет, не достиг ли итератор it
конца строки ( s.end()
). Если это не так, то проверяется следующее условие, где обращение к значению итератора it
, возвращающее текущий символ, передается функции isspace()
, чтобы выяснить, не пробел ли это. В конце каждой итерации выполняется оператор ++it
, чтобы переместить итератор на следующий символ строки s
.
У этого цикла то же тело, что и у последнего оператора if
предыдущей программы. Обращение к значению итератора it
используется и для передачи текущего символа функции toupper()
, и для присвоения полученного результата символу, на который указывает итератор it
.
Программисты, перешедшие на язык С++ с языка С или Java, могли бы быть удивлены тем, что в данном цикле for
был использован оператор !=
, а не <
. Программисты С++ используют оператор !=
исключительно по привычке. По этой же причине они используют итераторы, а не индексирование: этот стиль программирования одинаково хорошо применим к контейнерам различных видов, предоставляемых библиотекой.
Как уже упоминалось, только у некоторых библиотечных типов, vector
и string
, есть оператор индексирования. Тем не менее у всех библиотечных контейнеров есть итераторы, для которых определены операторы ==
и !=
. Однако большинство их итераторов не имеют оператора <
. При обычном использовании итераторов и оператора !=
можно не заботиться о точном типе обрабатываемого контейнера.
Подобно тому, как не всегда известен точный тип size_type
элемента вектора или строки (см. раздел 3.2.2), мы обычно не знаем (да и не обязаны знать) точный тип итератора. Как и в случае с типом size_type
, библиотечные типы, у которых есть итераторы, определяют типы по имени iterator
и const_iterator
, которые представляют фактические типы итераторов.
vector::iterator it; // it позволяет читать и записывать
// в элементы вектора vector
string::iterator it2; // it2 позволяет читать и записывать
// символы в строку
vector::const_iterator it3; // it3 позволяет читать, но не
// записывать элементы
string::const_iterator it4; // it4 позволяет читать, но не
// записывать символы
Тип const_iterator
ведет себя как константный указатель (см. раздел 2.4.2). Как и константный указатель, тип const_iterator
позволяет читать, но не писать в элемент, на который он указывает; объект типа iterator
позволяет и читать, и записывать. Если вектор или строка являются константой, можно использовать итератор только типа const_iterator
. Если вектор или строка на являются константой, можно использовать итератор и типа iterator
, и типа const_iterator
.
Термин итератор (iterator) используется для трех разных сущностей. Речь могла бы идти о концепции итератора, или о типе iterator
, определенном классом контейнера, или об объекте итератора.
Следует уяснить, что существует целый набор типов, связанных концептуально. Тип относится к итераторам, если он поддерживает общепринятый набор функций. Эти функции позволяют обращаться к элементу в контейнере и переходить с одного элемента на другой.
Каждый класс контейнера определяет тип по имени iterator
, который обеспечивает действия концептуального итератора.
begin()
и end()
Тип, возвращаемый функциями begin()
и end()
, зависит от константности объекта, для которого они были вызваны. Если объект является константой, то функции begin()
и end()
возвращают итератор типа const_iterator
; если объект не константа, они возвращают итератор типа iterator
.
vector v;
const vector cv;
auto it1 = v.begin(); // it1 имеет тип vector::iterator
auto it2 = cv.begin(); // it2 имеет тип vector::const_iterator
Зачастую это стандартное поведение желательно изменить. По причинам, рассматриваемым в разделе 6.2.3, обычно лучше использовать константный тип (такой как
const_iterator
), когда необходимо только читать, но не записывать в объект. Чтобы позволить специально задать тип const_iterator
, новый стандарт вводит две новые функции, cbegin()
и cend()
:
auto it3 = v.cbegin(); // it3 имеет тип vector::const_iterator
Подобно функциям-членам begin()
и end()
, эти функции-члены возвращают итераторы на первый и следующий после последнего элементы контейнера. Но независимо от того, является ли вектор (или строка) константой, они возвращают итератор типа const_iterator
.
При обращении к значению итератора получается объект, на который указывает итератор. Если этот объект имеет тип класса, то может понадобиться доступ к члену полученного объекта. Например, если есть вектор строк, то может понадобиться узнать, не пуст ли некий элемент. С учетом, что it
— это итератор данного вектора, можно следующим образом проверить, не пуста ли строка, на которую он указывает:
(*it).empty()
По причинам, рассматриваемым в разделе 4.1.2, круглые скобки в части (*it).empty()
необходимы. Круглые скобки требуют применить оператор обращения к значению к итератору it
, а к результату применить точечный оператор (см. раздел 1.5.2). Без круглых скобок точечный оператор относился бы к итератору it
, а не к полученному объекту.
(*it).empty() // обращение к значению it и вызов функции-члена empty()
// полученного объекта
*it.empty() // ошибка: попытка вызова функции-члена empty()
// итератора it,
// но итератор it не имеет функции-члена empty()
Второе выражение интерпретируется как запрос на выполнение функции-члена empty()
объекта it
. Но it
— это итератор, и он не имеет такой функции. Следовательно, второе выражение ошибочно.
Интервал:
Закладка: