- •1. Начинаем
 - •1.1. Решение задачи
 - •1.2. Программа на языке C++
 - •1.2.1. Порядок выполнения инструкций
 - •1.3. Директивы препроцессора
 - •1.4. Немного о комментариях
 - •1.5. Первый взгляд на ввод/вывод
 - •1.5.1. Файловый ввод/вывод
 - •2. Краткий обзор С++
 - •2.1. Встроенный тип данных “массив”
 - •2.2. Динамическое выделение памяти и указатели
 - •2.3. Объектный подход
 - •2.4. Объектно-ориентированный подход
 - •2.5. Использование шаблонов
 - •2.6. Использование исключений
 - •2.7. Использование пространства имен
 - •2.8. Стандартный массив – это вектор
 - •3. Типы данных С++
 - •3.1. Литералы
 - •3.2. Переменные
 - •3.2.1. Что такое переменная
 - •3.2.2. Имя переменной
 - •3.2.3. Определение объекта
 - •3.3. Указатели
 - •3.4. Строковые типы
 - •3.4.1. Встроенный строковый тип
 - •3.4.2. Класс string
 - •3.5. Спецификатор const
 - •3.6. Ссылочный тип
 - •3.7. Тип bool
 - •3.8. Перечисления
 - •3.9. Тип “массив”
 - •3.9.1. Многомерные массивы
 - •3.9.2. Взаимосвязь массивов и указателей
 - •3.10. Класс vector
 - •3.11. Класс complex
 - •3.12. Директива typedef
 - •3.13. Спецификатор volatile
 - •3.14. Класс pair
 - •3.15. Типы классов
 - •4. Выражения
 - •4.1. Что такое выражение?
 - •4.2. Арифметические операции
 - •4.3. Операции сравнения и логические операции
 - •4.4. Операции присваивания
 - •4.5. Операции инкремента и декремента
 - •4.6. Операции с комплексными числами
 - •4.7. Условное выражение
 - •4.8. Оператор sizeof
 - •4.9. Операторы new и delete
 - •4.10. Оператор “запятая”
 - •4.11. Побитовые операторы
 - •4.12. Класс bitset
 - •4.13. Приоритеты
 - •4.14. Преобразования типов
 - •4.14.1. Неявное преобразование типов
 - •4.14.2. Арифметические преобразования типов
 - •4.14.3. Явное преобразование типов
 - •4.14.4. Устаревшая форма явного преобразования
 - •4.15. Пример: реализация класса Stack
 - •5. Инструкции
 - •5.1. Простые и составные инструкции
 - •5.2. Инструкции объявления
 - •5.3. Инструкция if
 - •5.4. Инструкция switch
 - •5.5. Инструкция цикла for
 - •5.6. Инструкция while
 - •5.8. Инструкция do while
 - •5.8. Инструкция break
 - •5.9. Инструкция continue
 - •5.10. Инструкция goto
 - •5.11. Пример связанного списка
 - •5.11.1. Обобщенный список
 - •6. Абстрактные контейнерные типы
 - •6.1. Система текстового поиска
 - •6.2. Вектор или список?
 - •6.3. Как растет вектор?
 - •6.4. Как определить последовательный контейнер?
 - •6.5. Итераторы
 - •6.6. Операции с последовательными контейнерами
 - •6.6.1. Удаление
 - •6.6.2. Присваивание и обмен
 - •6.6.3. Обобщенные алгоритмы
 - •6.7. Читаем текстовый файл
 - •6.8. Выделяем слова в строке
 - •6.9. Обрабатываем знаки препинания
 - •6.10. Приводим слова к стандартной форме
 - •6.11. Дополнительные операции со строками
 - •6.12. Строим отображение позиций слов
 - •6.12.1. Определение объекта map и заполнение его элементами
 - •6.12.2. Поиск и извлечение элемента отображения
 - •6.12.3. Навигация по элементам отображения
 - •6.12.4. Словарь
 - •6.12.5. Удаление элементов map
 - •6.13. Построение набора стоп-слов
 - •6.13.1. Определение объекта set и заполнение его элементами
 - •6.13.2. Поиск элемента
 - •6.13.3. Навигация по множеству
 - •6.14. Окончательная программа
 - •6.15. Контейнеры multimap и multiset
 - •6.16. Стек
 - •6.17. Очередь и очередь с приоритетами
 - •6.18. Вернемся в классу iStack
 - •7. Функции
 - •7.1. Введение
 - •7.2. Прототип функции
 - •7.2.1. Тип возвращаемого функцией значения
 - •7.2.2. Список параметров функции
 - •7.2.3. Проверка типов формальных параметров
 - •7.3. Передача аргументов
 - •7.3.1. Параметры-ссылки
 - •7.3.2. Параметры-ссылки и параметры-указатели
 - •7.3.3. Параметры-массивы
 - •7.3.4. Абстрактные контейнерные типы в качестве параметров
 - •7.3.5. Значения параметров по умолчанию
 - •7.3.6. Многоточие
 - •7.4. Возврат значения
 - •7.4.1. Передача данных через параметры и через глобальные объекты
 - •7.5. Рекурсия
 - •7.6. Встроенные функции
 - •7.7. Директива связывания extern "C" A
 - •7.8. Функция main(): разбор параметров командной строки
 - •7.8.1. Класс для обработки параметров командной строки
 - •7.9. Указатели на функции
 - •7.9.1. Тип указателя на функцию
 - •7.9.2. Инициализация и присваивание
 - •7.9.3. Вызов
 - •7.9.4. Массивы указателей на функции
 - •7.9.5. Параметры и тип возврата
 - •7.9.6. Указатели на функции, объявленные как extern "C"
 - •8. Область видимости и время жизни
 - •8.1. Область видимости
 - •8.1.1. Локальная область видимости
 - •8.2. Глобальные объекты и функции
 - •8.2.1. Объявления и определения
 - •8.2.2. Сопоставление объявлений в разных файлах
 - •8.2.3. Несколько слов о заголовочных файлах
 - •8.3. Локальные объекты
 - •8.3.1. Автоматические объекты
 - •8.3.2. Регистровые автоматические объекты
 - •8.3.3. Статические локальные объекты
 - •8.4. Динамически размещаемые объекты
 - •8.4.1. Динамическое создание и уничтожение единичных объектов
 - •8.4.2. Шаблон auto_ptr А
 - •8.4.3. Динамическое создание и уничтожение массивов
 - •8.4.4. Динамическое создание и уничтожение константных объектов
 - •8.4.5. Оператор размещения new А
 - •8.5. Определения пространства имен А
 - •8.5.1. Определения пространства имен
 - •8.5.2. Оператор разрешения области видимости
 - •8.5.3. Вложенные пространства имен
 - •8.5.4. Определение члена пространства имен
 - •8.5.5. ПОО и члены пространства имен
 - •8.5.6. Безымянные пространства имен
 - •8.6. Использование членов пространства имен А
 - •8.6.1. Псевдонимы пространства имен
 - •8.6.2. Using-объявления
 - •8.6.3. Using-директивы
 - •8.6.4. Стандартное пространство имен std
 - •9. Перегруженные функции
 - •9.1. Объявления перегруженных функций
 - •9.1.1. Зачем нужно перегружать имя функции
 - •9.1.2. Как перегрузить имя функции
 - •9.1.3. Когда не надо перегружать имя функции
 - •9.1.4. Перегрузка и область видимости A
 - •9.1.5. Директива extern "C" и перегруженные функции A
 - •9.1.6. Указатели на перегруженные функции A
 - •9.1.7. Безопасное связывание A
 - •9.2. Три шага разрешения перегрузки
 - •9.3. Преобразования типов аргументов A
 - •9.3.1. Подробнее о точном соответствии
 - •9.3.2. Подробнее о расширении типов
 - •9.3.3. Подробнее о стандартном преобразовании
 - •9.3.4. Ссылки
 - •9.4. Детали разрешения перегрузки функций
 - •9.4.1. Функции-кандидаты
 - •9.4.2. Устоявшие функции
 - •9.4.3. Наилучшая из устоявших функция
 - •9.4.4. Аргументы со значениями по умолчанию
 - •10. Шаблоны функций
 - •10.1. Определение шаблона функции
 - •10.2. Конкретизация шаблона функции
 - •10.3. Вывод аргументов шаблона А
 - •10.4. Явное задание аргументов шаблона A
 - •10.5. Модели компиляции шаблонов А
 - •10.5.1. Модель компиляции с включением
 - •10.5.2. Модель компиляции с разделением
 - •10.5.3. Явные объявления конкретизации
 - •10.6. Явная специализация шаблона А
 - •10.7. Перегрузка шаблонов функций А
 - •10.8. Разрешение перегрузки при конкретизации A
 - •10.9. Разрешение имен в определениях шаблонов А
 - •10.10. Пространства имен и шаблоны функций А
 - •10.11. Пример шаблона функции
 - •11. Обработка исключений
 - •11.1. Возбуждение исключения
 - •11.2. try-блок
 - •11.3. Перехват исключений
 - •11.3.1. Объекты-исключения
 - •11.3.2. Раскрутка стека
 - •11.3.3. Повторное возбуждение исключения
 - •11.3.4. Перехват всех исключений
 - •11.4. Спецификации исключений
 - •11.4.1. Спецификации исключений и указатели на функции
 - •11.5. Исключения и вопросы проектирования
 - •12. Обобщенные алгоритмы
 - •12.1. Краткий обзор
 - •12.2. Использование обобщенных алгоритмов
 - •12.3. Объекты-функции
 - •12.3.1. Предопределенные объекты-функции
 - •12.3.3. Сравнительные объекты-функции
 - •12.3.4. Логические объекты-функции
 - •12.3.5. Адаптеры функций для объектов-функций
 - •12.3.6. Реализация объекта-функции
 - •12.4. Еще раз об итераторах
 - •12.4.1. Итераторы вставки
 - •12.4.2. Обратные итераторы
 - •12.4.3. Потоковые итераторы
 - •12.4.4. Итератор istream_iterator
 - •12.4.5. Итератор ostream_iterator
 - •12.4.6. Пять категорий итераторов
 - •12.5. Обобщенные алгоритмы
 - •12.5.1. Алгоритмы поиска
 - •12.5.2. Алгоритмы сортировки и упорядочения
 - •12.5.3. Алгоритмы удаления и подстановки
 - •12.5.4. Алгоритмы перестановки
 - •12.5.5. Численные алгоритмы
 - •12.5.6. Алгоритмы генерирования и модификации
 - •12.5.7. Алгоритмы сравнения
 - •12.5.8. Алгоритмы работы с множествами
 - •12.5.9. Алгоритмы работы с хипом
 - •12.6.1. Операция list_merge()
 - •12.6.2. Операция list::remove()
 - •12.6.3. Операция list::remove_if()
 - •12.6.4. Операция list::reverse()
 - •12.6.5. Операция list::sort()
 - •12.6.6. Операция list::splice()
 - •12.6.7. Операция list::unique()
 - •13. Классы
 - •13.1. Определение класса
 - •13.1.1. Данные-члены
 - •13.1.2. Функции-члены
 - •13.1.3. Доступ к членам
 - •13.1.4. Друзья
 - •13.1.5. Объявление и определение класса
 - •13.2. Объекты классов
 - •13.3. Функции-члены класса
 - •13.3.1. Когда использовать встроенные функции-члены
 - •13.3.2. Доступ к членам класса
 - •13.3.3. Закрытые и открытые функции-члены
 - •13.3.4. Специальные функции-члены
 - •13.3.5. Функции-члены со спецификаторами const и volatile
 - •13.3.6. Объявление mutable
 - •13.4. Неявный указатель this
 - •13.4.1. Когда использовать указатель this
 - •13.5. Статические члены класса
 - •13.5.1. Статические функции-члены
 - •13.6. Указатель на член класса
 - •13.6.1. Тип члена класса
 - •13.6.2. Работа с указателями на члены класса
 - •13.6.3. Указатели на статические члены класса
 - •13.7. Объединение – класс, экономящий память
 - •13.8. Битовое поле – член, экономящий память
 - •13.9. Область видимости класса A
 - •13.9.1. Разрешение имен в области видимости класса
 - •13.10. Вложенные классы A
 - •13.10.1. Разрешение имен в области видимости вложенного класса
 - •13.11. Классы как члены пространства имен A
 - •13.12. Локальные классы A
 - •14. Инициализация, присваивание и уничтожение класса
 - •14.1. Инициализация класса
 - •14.2. Конструктор класса
 - •14.2.1. Конструктор по умолчанию
 - •14.2.2. Ограничение прав на создание объекта
 - •14.2.3. Копирующий конструктор
 - •14.3. Деструктор класса
 - •14.3.1. Явный вызов деструктора
 - •14.3.2. Опасность увеличения размера программы
 - •14.4. Массивы и векторы объектов
 - •14.4.1. Инициализация массива, распределенного из хипа A
 - •14.4.2. Вектор объектов
 - •14.5. Список инициализации членов
 - •14.6. Почленная инициализация A
 - •14.6.1. Инициализация члена, являющегося объектом класса
 - •14.7. Почленное присваивание A
 - •14.8. Соображения эффективности A
 - •15. Перегруженные операторы и определенные пользователем преобразования
 - •15.1. Перегрузка операторов
 - •15.1.1. Члены и не члены класса
 - •15.1.2. Имена перегруженных операторов
 - •15.1.3. Разработка перегруженных операторов
 - •15.2. Друзья
 - •15.3. Оператор =
 - •15.4. Оператор взятия индекса
 - •15.5. Оператор вызова функции
 - •15.6. Оператор “стрелка”
 - •15.7. Операторы инкремента и декремента
 - •15.8. Операторы new и delete
 - •15.8.1. Операторы new[ ] и delete [ ]
 - •15.8.2. Оператор размещения new() и оператор delete()
 - •15.9. Определенные пользователем преобразования
 - •15.9.1. Конвертеры
 - •15.9.2. Конструктор как конвертер
 - •15.10. Выбор преобразования A
 - •15.10.1. Еще раз о разрешении перегрузки функций
 - •15.10.2. Функции-кандидаты
 - •15.10.3. Функции-кандидаты для вызова функции в области видимости класса
 - •15.10.4. Ранжирование последовательностей определенных пользователем преобразований
 - •15.11. Разрешение перегрузки и функции-члены A
 - •15.11.1. Объявления перегруженных функций-членов
 - •15.11.2. Функции-кандидаты
 - •15.11.3. Устоявшие функции
 - •15.12. Разрешение перегрузки и операторы A
 - •15.12.1. Операторные функции-кандидаты
 - •15.12.2. Устоявшие функции
 - •15.12.3. Неоднозначность
 - •16. Шаблоны классов
 - •16.1. Определение шаблона класса
 - •16.1.1. Определения шаблонов классов Queue и QueueItem
 - •16.2. Конкретизация шаблона класса
 - •16.2.1. Аргументы шаблона для параметров-констант
 - •16.3. Функции-члены шаблонов классов
 - •16.3.1. Функции-члены шаблонов Queue и QueueItem
 - •16.4. Объявления друзей в шаблонах классов
 - •16.4.1. Объявления друзей в шаблонах Queue и QueueItem
 - •16.5. Статические члены шаблонов класса
 - •16.6. Вложенные типы шаблонов классов
 - •16.7. Шаблоны-члены
 - •16.8. Шаблоны классов и модель компиляции A
 - •16.8.1. Модель компиляции с включением
 - •16.8.2. Модель компиляции с разделением
 - •16.8.3. Явные объявления конкретизации
 - •16.9. Специализации шаблонов классов A
 - •16.10. Частичные специализации шаблонов классов A
 - •16.11. Разрешение имен в шаблонах классов A
 - •16.12. Пространства имен и шаблоны классов
 - •16.13. Шаблон класса Array
 - •17. Наследование и подтипизация классов
 - •17.1. Определение иерархии классов
 - •17.1.1. Объектно-ориентированное проектирование
 - •17.2. Идентификация членов иерархии
 - •17.2.1. Определение базового класса
 - •17.2.2. Определение производных классов
 - •17.2.3. Резюме
 - •17.3. Доступ к членам базового класса
 - •17.4. Конструирование базового и производного классов
 - •17.4.1. Конструктор базового класса
 - •17.4.2. Конструктор производного класса
 - •17.4.3. Альтернативная иерархия классов
 - •17.4.4. Отложенное обнаружение ошибок
 - •17.4.5. Деструкторы
 - •17.5. Виртуальные функции в базовом и производном классах
 - •17.5.1. Виртуальный ввод/вывод
 - •17.5.2. Чисто виртуальные функции
 - •17.5.3. Статический вызов виртуальной функции
 - •17.5.4. Виртуальные функции и аргументы по умолчанию
 - •17.5.5. Виртуальные деструкторы
 - •17.5.6. Виртуальная функция eval()
 - •17.5.7. Почти виртуальный оператор new
 - •17.5.8. Виртуальные функции, конструкторы и деструкторы
 - •17.6. Почленная инициализация и присваивание A
 - •17.7. Управляющий класс UserQuery
 - •17.7.1. Определение класса UserQuery
 - •17.8. Соберем все вместе
 - •18. Множественное и виртуальное наследование
 - •18.1. Готовим сцену
 - •18.2. Множественное наследование
 - •18.3. Открытое, закрытое и защищенное наследование
 - •18.3.1. Наследование и композиция
 - •18.3.2. Открытие отдельных членов
 - •18.3.3. Защищенное наследование
 - •18.3.4. Композиция объектов
 - •18.4. Область видимости класса и наследование
 - •18.4.1. Область видимости класса при множественном наследовании
 - •18.5. Виртуальное наследование A
 - •18.5.1. Объявление виртуального базового класса
 - •18.5.2. Специальная семантика инициализации
 - •18.5.3. Порядок вызова конструкторов и деструкторов
 - •18.5.4. Видимость членов виртуального базового класса
 - •18.6. Пример множественного виртуального наследования A
 - •18.6.1. Порождение класса, контролирующего выход за границы массива
 - •18.6.2. Порождение класса отсортированного массива
 - •18.6.3. Класс массива с множественным наследованием
 - •19. Применение наследования в C++
 - •19.1. Идентификация типов во время выполнения
 - •19.1.1. Оператор dynamic_cast
 - •19.1.2. Оператор typeid
 - •19.1.3. Класс type_info
 - •19.2. Исключения и наследование
 - •19.2.1. Исключения, определенные как иерархии классов
 - •19.2.2. Возбуждение исключения типа класса
 - •19.2.3. Обработка исключения типа класса
 - •19.2.4. Объекты-исключения и виртуальные функции
 - •19.2.5. Раскрутка стека и вызов деструкторов
 - •19.2.6. Спецификации исключений
 - •19.2.7. Конструкторы и функциональные try-блоки
 - •19.2.8. Иерархия классов исключений в стандартной библиотеке C++
 - •19.3. Разрешение перегрузки и наследование A
 - •19.3.1. Функции-кандидаты
 - •19.3.2. Устоявшие функции и последовательности пользовательских преобразований
 - •19.3.3. Наилучшая из устоявших функций
 - •20. Библиотека iostream
 - •20.1. Оператор вывода <<
 - •20.2. Ввод
 - •20.2.1. Строковый ввод
 - •20.3. Дополнительные операторы ввода/вывода
 - •20.4. Перегрузка оператора вывода
 - •20.5. Перегрузка оператора ввода
 - •20.6. Файловый ввод/вывод
 - •20.7. Состояния потока
 - •20.8. Строковые потоки
 - •20.9. Состояние формата
 - •20.10. Сильно типизированная библиотека
 - •21. Обобщенные алгоритмы в алфавитном порядке
 - •Алгоритм accumulate()
 - •Алгоритм adjacent_difference()
 - •Алгоритм adjacent_find()
 - •Алгоритм binary_search()
 - •Алгоритм copy()
 - •Алгоритм copy_backward()
 - •Алгоритм count()
 - •Алгоритм count_if()
 - •Алгоритм equal()
 - •Алгоритм equal_range()
 - •Алгоритм fill()
 - •Алгоритм fill_n()
 - •Алгоритм find()
 - •Алгоритм find_if()
 - •Алгоритм find_end()
 - •Алгоритм find_first_of()
 - •Алгоритм for_each()
 - •Алгоритм generate()
 - •Алгоритм generate_n()
 - •Алгоритм includes()
 - •Алгоритм inner_product()
 - •Алгоритм inplace_merge()
 - •Алгоритм iter_swap()
 - •Алгоритм lexicographical_compare()
 - •Алгоритм lower_bound()
 - •Алгоритм max()
 - •Алгоритм max_element()
 - •Алгоритм min()
 - •Алгоритм min_element()
 - •Алгоритм merge()
 - •Алгоритм mismatch()
 - •Алгоритм next_permutation()
 - •Алгоритм nth_element()
 - •Алгоритм partial_sort()
 - •Алгоритм partial_sort_copy()
 - •Алгоритм partial_sum()
 - •Алгоритм partition()
 - •Алгоритм prev_permutation()
 - •Алгоритм random_shuffle()
 - •Алгоритм remove()
 - •Алгоритм remove_copy()
 - •Алгоритм remove_if()
 - •Алгоритм remove_copy_if()
 - •Алгоритм replace()
 - •Алгоритм replace_copy()
 - •Алгоритм replace_if()
 - •Алгоритм replace_copy_if()
 - •Алгоритм reverse()
 - •Алгоритм reverse_copy()
 - •Алгоритм rotate()
 - •Алгоритм rotate_copy()
 - •Алгоритм search()
 - •Алгоритм search_n()
 - •Алгоритм set_difference()
 - •Алгоритм set_intersection()
 - •Алгоритм set_symmetric_difference()
 - •Алгоритм set_union()
 - •Алгоритм sort()
 - •Алгоритм stable_partition()
 - •Алгоритм stable_sort()
 - •Алгоритм swap()
 - •Алгоритм swap_ranges()
 - •Алгоритм transform()
 - •Алгоритм unique()
 - •Алгоритм unique_copy()
 - •Алгоритм upper_bound()
 - •Алгоритмы для работы с хипом
 - •Алгоритм make_heap()
 - •Алгоритм pop_heap()
 - •Алгоритм push_heap()
 - •Алгоритм sort_heap()
 
int iva1=512 jva1=1024, kva1=4096;
int bufsize; // ...
switch( swt ) { case ival:
bufsize = ival * sizeof( int );
break; case jval:
bufsize = jval * sizeof( int );
break; case kval:
bufsize = kval * sizeof( int );
break;
}
enum { illustrator = 1, photoshop, photostyler = 2 };
switch ( ival ) { case illustrator:
--i11us_1icense; break;
case photoshop: --pshop_1icense; break;
case photostyler: --psty1er_license;
(e)
break;
}
5.5. Инструкция цикла for
Как мы видели, выполнение программы часто состоит в повторении последовательности инструкций – до тех пор, пока некоторое условие остается истинным. Например, мы читаем и обрабатываем записи файла, пока не дойдем до его конца, перебираем элементы массива, пока индекс не станет равным размерности массива минус 1, и т.д. В С++ предусмотрено три инструкции для организации циклов, в частности for и while, которые начинаются проверкой условия. Такая проверка означает, что цикл может закончиться без выполнения связанной с ним простой или составной инструкции. Третий тип цикла, do while, гарантирует, что тело будет выполнено как минимум один раз: условие цикла проверяется по его завершении. (В этом разделе мы детально рассмотрим цикл for; в разделе 5.6 разберем while, а в разделе 5.7 – do while.)
Цикл for обычно используется для обработки структур данных, имеющих фиксированную длину, таких, как массив или вектор:
#include <vector> int main() {
int ia[ 10 ];
for ( int ix = 0; ix < 10; ++-ix ) ia[ ix ] = ix;
vector<int> ivec( ia, ia+10 ); vector<int>::iterator iter =
ivec.begin() ;
for ( ; iter != ivec.end(); ++iter ) *iter *= 2;
return 0;
}
for (инструкция-инициализации; условие; выражение )
Синтаксис цикла for следующий:
инструкция
инструкция-инициализации может быть либо выражением, либо инструкцией объявления. Обычно она используется для инициализации переменной значением, которое увеличивается в ходе выполнения цикла. Если такая инициализация не нужна или выполняется где-то в другом месте, эту инструкцию можно заменить пустой (см. второй из приведенных ниже примеров). Вот примеры правильного использования
// index и iter определены в другом
месте
for ( index =0; ...
for ( ; /* пустая инструкция */ ...
for ( iter = ivec.begin(); ...
for ( int 1o = 0,hi = max; ...
инструкции-инициализации:
for ( char *ptr = getStr(); ...
условие служит для управления циклом. Пока условие при вычислении дает true, инструкция продолжает выполняться. Выполняемая в цикле инструкция может быть как простой, так и составной. Если же самое первое вычисление условия дает false,
(... index < arraySize; ... ) (... iter !=
ivec.end(); ... ) (... *stl++ = *st2++; ... )
инструкция не выполняется ни разу. Правильные условия можно записать так:
(... char ch = getNextChar(); ... )
Выражение вычисляется после выполнения инструкции на каждой итерации цикла. Обычно его используют для модификации переменной, инициализированной в
инструкции-инициализации. Если самое первое вычисление условия дает false,
( ... ...; ++-index ) ( ... ...; ptr = ptr-
>next )
( ... ...; ++i, --j, + +cnt )
выражение не выполняется ни разу. Правильные выражения выглядят таким образом:
( ... ...; ) // пустое выражение
const int sz = 24; int ia[ sz ];
vector<int> ivec( sz );
for ( int ix = 0; ix < sz; ++ix )
{
ivec[ ix ] = ix; ia[ ix ]= ix;
Для приведенного ниже цикла for
}
порядок вычислений будет следующим:
1.инструкция-инициализации выполняется один раз перед началом цикла. В данном примере объявляется переменная ix, которая инициализируется значением 0.
2.Вычисляется условие. Если оно равно true, выполняется составная инструкция тела цикла. В нашем примере, пока ix меньше sz, значение ix присваивается элементам ivec[ix] и ia[ix]. Когда значением условия станет false, выполнение цикла прекратится. Если самое первое вычисление условия даст false, составная инструкция выполняться не будет.
3.Вычисляется выражение. Как правило, его используют для модификации переменной, фигурирующей в инструкции-инициализации и проверяемой в условии. В нашем примере ix увеличивается на 1.
Эти три шага представляют собой полную итерацию цикла for. Теперь шаги 2 и 3 будут повторяться до тех пор, пока условие не станет равным false, т.е. ix окажется равным или большим sz.
В инструкции-инициализации можно определить несколько объектов, однако все они должны быть одного типа, так как инструкция объявления допускается только одна:
for ( int ival = 0, *pi = &ia, &ri = val;
ival < size; ++iva1, ++pi, ++ri )
// ...
Объявление объекта в условии гораздо труднее правильно использовать: такое объявление должно хотя бы раз дать значение false, иначе выполнение цикла никогда
#include <iostream>
int main()
{
for ( int ix = 0;
bool done = ix == 10; ++ix )
cout << "ix: " << ix << endl;
не прекратится. Вот пример, хотя и несколько надуманный:
}
Видимость всех объектов, определенных внутри круглых скобок инструкции for, ограничена телом цикла. Например, проверка iter после цикла вызовет ошибку
int main()
{
string word;
vector< string > text; // ...
for ( vector< string >::iterator iter = text.begin(), iter_end =
text.end();
iter != text.end(); ++iter )
{
if ( *iter == word ) break;
// ...
}
// ошибка: iter и iter_end невидимы if ( iter != iter_end )
компиляции8:
// ...
8 До принятия стандарта языка С++ видимость объектов, определенных внутри круглых скобок for, простиралась на весь блок или функцию, содержащую данную инструкцию. Например, употребление двух циклов for внутри одного блока
}  | 
	{  | 
	
  | 
	
  | 
в  | 
	// верно для стандарта С++  | 
	
  | 
	
  | 
ранних//версияхпредыдущихязыка вызываловерсиях ошибку:C++ - ошибка:определенаival определенаважды. В стандарте С++  | 
|||
  | 
	ival  | 
	ival  | 
	
  | 
данный текст дважды  | 
	является  | 
||
  | 
	синтаксически правилен, так как каждый экземпляр  | 
	
  | 
|
локальнымforдля(intсвоегоivalблока.= 0; ival < size; ++iva1 ) // ...  | 
	
  | 
	
  | 
|
  | 
	for (int ival = size-1; ival > 0; ival ) // ...  | 
	
  | 
	
  | 
Упражнение 5.8
(a)
for ( int *ptr = &ia, ix = 0; ix < size && ptr != ia +size;
++ix, ++ptr ) // ...
Допущены ли ошибки в нижеследующих циклах for? Если да, то какие?
(b)
for ( ; ; ) { if
( some_condition
)
break; // ...
}
(c)
for ( int ix = 0; ix < sz; ++ix )
// ...
if ( ix != sz )
// ...
(d)
int ix;
for ( ix < sz; ++ix ) // ...
(e)
for ( int ix = 0; ix < sz; ++ix, ++ sz )
// ...
Упражнение 5.9
Представьте, что вам поручено придумать общий стиль использования цикла for в вашем проекте. Объясните и проиллюстрируйте примерами правила использования каждой из трех частей цикла.
Упражнение 5.10
Дано объявление функции:
