Вход/Регистрация
Программирование. Принципы и практика использования 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
чаще всего используется для исходных файлов. На самом деле в языке С++ расширение файла не имеет значения, но некоторые компиляторы и большинство интегрированных сред разработки программ настаивают на использовании определенных соглашений относительно расширений файлов.

  • Читать дальше
  • 1
  • ...
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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