- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
Когда какая-нибудь функция вызывает функцию f(), сначала создается переменная s; иначе говоря, переменная s инициализируется пустой строкой. Она будет существовать, пока функция f() не вернет управление. Каждый раз, когда мы входим в тело цикла while, создаются переменные stripped и not_letters. Поскольку переменная stripped определена до переменной not_letters, сначала создается переменная stripped. Они существуют до выхода из тела цикла. В этот момент они уничтожаются в обратном порядке (иначе говоря, переменная not_letters уничтожается до переменной stripped) и до того, как произойдет проверка условия выхода из цикла. Итак, если, до того, как мы обнаружим строку quit, мы выполним цикл десять раз, переменные stripped и not_letters будут созданы и уничтожены десять раз.
Каждый раз, когда мы входим в цикл for, создается переменная i. Каждый раз, когда мы выходим из цикла for, переменная i уничтожается до того, как мы достигнем инструкции v.push_back(stripped);.
Обратите внимание на то, что компиляторы (и редакторы связей) — довольно разумны и способны оптимизировать код. В частности, компиляторы не выделяют и не освобождают память чаще, чем это действительно требуется.
8.6.1. Вычисление выражения
Порядок вычисления подвыражений управляется правилами, которые больше ориентируются на оптимизацию кода, чем на удобство работы программиста. Это неудобно, но в любом случае следует избегать чрезмерно сложных выражений. Помните простое правило: если изменяете значение переменной в выражении, то не используйте его дважды в одном и том же выражении. Рассмотрим пример.
v[i] = ++i; // неопределенный порядок вычислений
v[++i] = i; // неопределенный порядок вычислений
int x = ++i + ++i; // неопределенный порядок вычислений
cout << ++i << ' ' << i << 'n'; // неопределенный порядок вычислений
f(++i,++i); // неопределенный порядок вычислений
К сожалению, не все компиляторы выдают предупреждение о таких ошибках; это плохо, потому что нельзя рассчитывать на то, что результаты будут одинаковыми при выполнении вычислений на другом компьютере, при использовании других компиляторов или при других установках оптимизатора.
Компиляторы действительно по-разному обрабатывают этот код; избегайте таких ситуаций.
Обратите внимание на то, что оператор = (присваивание) в выражениях используется наряду с остальными, поэтому нет никакой гарантии того, что левая часть оператора будет вычислена раньше правой части. По этой причине выражение v[++i] = i имеет неопределенный результат.
8.6.2. Глобальная инициализация
Глобальные переменные (и переменные из пространства имен; раздел 8.7) в отдельной единице трансляции инициализируются в том порядке, в котором они появляются. Рассмотрим пример.
// файл f1.cpp
int x1 = 1;
int y1 = x1+2; // переменная y1 становится равной 3
Эта инициализация логически происходит до выполнения кода в функции main(). Использование глобальной переменной, за исключением редких ситуаций, нецелесообразно. Мы уже говорили, что не существует эффективного способа, позволяющего программисту определить, какие части программы считывают или записывают переменную (см. раздел 8.4). Другая проблема заключается в том, что порядок инициализации глобальных переменных не определен. Рассмотрим пример.
// файл f2.cpp
extern int y1;
int y2 = y1+2; // переменная y2 становится равной 2 или 5
Такой код нежелателен по нескольким причинам: в нем используются глобальные переменные, которые имеют слишком короткие имена, и сложная инициализация глобальных переменных. Если глобальные переменные в файле f1.cpp инициализируются до глобальных переменных в файле f2.cpp, то переменная y2 будет инициализирована числом 5 (как наивно ожидает программист).
Однако, если глобальные переменные в файле f2.cpp инициализируются до глобальных переменных в файле f1.cpp, переменная y2 будет инициализирована числом 2 (поскольку память, используемая для глобальных переменных, инициализируется нулем до попытки сложной инициализации). Избегайте этого и старайтесь не использовать нетривиальную инициализацию глобальных переменных; любой инициализатор, отличающийся от константного выражения, следует считать сложным.
Но что же делать, если нам действительно нужна глобальная переменная (или константа) со сложной инициализацией? Например, мы можем предусмотреть значение по умолчанию для переменных типа Date.
const Date default_date(1970,1,1); // дата по умолчанию: 1 января 1970
Как узнать, что переменная default_date никогда не использовалась до своей инициализации? В принципе мы не можем этого знать, поэтому не должны писать это определение. Чаще всего для проверки используется вызов функции, возвращающей некое значение. Рассмотрим пример.
const Date default_date() // возвращает дату по умолчанию
{
return Date(1970,1,1);
}
Эта функция создает объект типа Date каждый раз, когда вызывается функция default_date(). Часто этого вполне достаточно, но если функция default_date() вызывается часто, а создание объекта класса Date связано с большими затратами, предпочтительнее было бы конструировать его только один раз. В таком случае код мог бы выглядеть так:
const Date& default_date()
{
static const Date dd(1970,1,1); // инициализируем dd
// только при первом вызове
return dd;
}
Статическая локальная переменная инициализируется (создается) только при первом вызове функции, в которой она объявлена. Обратите внимание на то, что мы вернули ссылку, чтобы исключить ненужное копирование, и, в частности, вернули константную ссылку, чтобы предотвратить несанкционированное изменение значения аргумента при вызове функции. Рассуждения о передаче аргумента (см. раздел 8.5.6) относятся и к возвращаемому значению.
8.7. Пространства имен
Для организации кода в рамках функции используются блоки (см. раздел 8.4).
Для организации функций, данных и типов в рамках типа используется класс (глава 9). Предназначение функций и классов заключается в следующем.
• Они позволяют определить множество сущностей без опасения, что их имена совпадут с другими именами в программе.
• Позволяют именовать то, что мы определили.
Нам нужно иметь средство для организации классов, функций, данных и типов в виде идентифицируемой и именованной части программы, не прибегая к определению типа. Языковый механизм, позволяющий осуществить такую группировку объявлений, называют пространством имен (namespace). Например, мы можем создать графическую библиотеку с классами Color, Shape, Line, Function и Text (глава 13).
namespace Graph_lib {
struct Color { /* ... */ };
struct Shape { /* ... */ };
struct Line: Shape { /* ... */

