Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Константы объявляются так же, как переменные, за исключением ключевого слова

const
и требования инициализации.

const int x = 7; // инициализация с помощью синтаксической

// конструкции =

const int x2(9); // инициализация с помощью синтаксической

// конструкции

const int y; // ошибка: нет инициализации

Причина, по которой константа требует инициализации, очевидна: после объявления
константы она уже не может изменить свое значение. Как правило, целесообразно инициализировать и переменные; переменная, не имеющая начального значения, способна вызвать недоразумения. Рассмотрим пример.

void f(int z)

{

int x; // неинициализированная переменная

// ...здесь нет присваивания значений переменной x...

x = 7; // присваивание значения переменной x

// ...

}

Этот код выглядит вполне невинно, но что будет, если в первом пропущенном фрагменте, отмеченном многоточием, будет использована переменная

x
? Рассмотрим пример.

void f(int z)

{

int x; // неинициализированная переменная

// ...здесь нет присваивания значений переменной x...

if (z>x) {

// ...

}

// ...

x = 7; // присваивание значения переменной x

// ...

}

Поскольку переменная

x
не инициализирована, выполнение оператора
z>x
может привести к неопределенным последствиям. Сравнение
z>x
приведет к разным результатам на разных компьютерах и даже на одном и том же компьютере в разных сеансах работы. В принципе оператор
z>x
может вызвать прекращение работы программы из-за машинной ошибки, но чаще всего ничего не происходит, и мы получаем непредсказуемые результаты.

Естественно, такое непредсказуемое поведение программы нас не устраивает, но если мы не проинициализируем переменные, то в итоге произойдет ошибка.

Напомним, что “глупые ошибки” (которые происходят при использовании неинициализированных переменных) происходят из-за спешки или усталости. Как правило, компиляторы пытаются предупредить программистов, но в сложных программах — в которых такие ошибки и появляются чаще всего — они не могут выловить все такие ошибки. Существуют люди, не привыкшие инициализировать переменные. Часто это происходит потому, что они учили языки, в которых этого не требовалось; вы можете встретить такие примеры в будущем. Пожалуйста, не усложняйте себе жизнь, забывая инициализировать переменные при их определении.

8.2.3. Инициализация по умолчанию

Возможно, вы заметили, что мы часто не инициализируем объекты классов

string
,
vector
и т.д. Рассмотрим пример.

vector<string> v;

string s;

while (cin>>s) v.push_back(s);

Это не противоречит правилу, утверждающему, что переменные перед их использованием должны быть проинициализированы. В данном случае, если мы не задаем начальные значения, происходит инициализация строк и векторов по умолчанию. Таким образом, вектор

v
пуст (т.е. не содержит элементов), и строка
s
перед входом в цикл также пуста (
""
). Механизм, гарантирующий инициализацию по умолчанию, называется конструктором
по умолчанию
(default constructor).

К сожалению, язык С++ не предусматривает инициализацию по умолчанию для встроенных типов. Лишь глобальные переменные (см. раздел 8.4) по умолчанию инициализируются нулем, но их использование следует ограничивать. Большинство полезных переменных, к которым относятся локальные переменные и члены классов, не инициализируются, пока не указано их начальное значение (или не задан конструктор по умолчанию).

Не говорите, что вас не предупреждали!

8.3. Заголовочные файлы

Как управлять объявлениями и определениями? Они должны быть согласованными. В реальных программах могут быть десятки тысяч объявлений; программы с сотнями тысяч объявлений тоже не редкость. Как правило, когда вы пишете программу, большинство используемых определений написано не вами. Например, реализации потока

cout
и функции
sqrt
были написаны много лет назад кем-то другим. Мы просто используем их. Главным средством управления сущностями, определенными где-то в другом месте, в языке С++ являются заголовки. В принципе заголовок (header) — это коллекция объявлений, записанных в файле, поэтому заголовок часто называют заголовочным файлом (header file). Такие заголовки подставляются в исходные файлы с помощью директивы
#include
. Например, вы можете решить улучшить организацию исходного кода нашего калькулятора (см. главы 6 и 7), выделив объявления лексем в отдельный файл. Таким образом, можно определить заголовочный файл
token.h
, содержащий объявления, необходимые для использования классов
Token
и
Token_stream
.

Объявления классов

Token
и
Token_stream
находятся в заголовке
token.h
. Их определения находятся в файле
token.cpp
. В языке C++ расширение
.h
относится к заголовочным файлам, а расширение
.cpp
чаще всего используется для исходных файлов. На самом деле в языке С++ расширение файла не имеет значения, но некоторые компиляторы и большинство интегрированных сред разработки программ настаивают на использовании определенных соглашений относительно расширений файлов.

В принципе директива

#include "file.h"
просто копирует объявления из файла
file.h
в ваш файл в точку, отмеченную директивой
#include
. Например, мы можем написать заголовочный файл
f.h
.

// f.h

int f(int);

А затем можем включить его в файл

user.cpp
.

// user.cpp

#include "f.h"

int g(int i)

{

return f(i);

}

При компиляции файла

user.cpp
компилятор выполнит подстановку заголовочного файла и скомпилирует следующий текст:

int f(int);

int g(int i)

{

return f(i);

}

Поскольку директива

#include
выполняется компилятором в самом начале, выполняющая ее часть компилятора называется препроцессором (preprocessing) (раздел A.17).

Поделиться:
Популярные книги

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5