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

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

Жанры

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

double sqrt(double d) {/* ... */} // определение

double sqrt(double d) {/* ... */} // ошибка: повторное определение

int a; // определение

int a; // ошибка: повторное определение

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

int x = 7; //
определение

extern int x; // объявление

extern int x; // другое объявление

double sqrt(double); // объявление

double sqrt(double d) {/* ... */} // определение

double sqrt(double); // другое объявление функции sqrt

double sqrt(double); // еще одно объявление функции sqrt

int sqrt(double); // ошибка: несогласованное определение

Почему последнее объявление является ошибкой? Потому что в одной и той же программе не может быть двух функций с именем
sqrt
, принимающих аргумент типа
double
и возвращающих значения разных типов (
int
и
double
).

Ключевое слово

extern
, использованное во втором объявлении переменной
x
, утверждает, что это объявление не является определением. Это редко бывает нужным. Мы не рекомендуем делать это, но в принципе такие объявления можно встретить в некоторых программах, особенно в программах, использующих слишком много глобальных переменных (см. разделы 8.4 и 8.6.2).

Почему в языке С++ предусмотрены как объявления, так и определения? Различие между ними отражает фундаментальное различие между тем, что нам необходимо, чтобы использовать некую сущность (интерфейс), от того, что нам необходимо, чтобы нечто делало то, для чего оно предназначено (реализация). Объявление переменной устанавливает ее тип, но лишь определение создает реальный объект (выделяет память). Объявление функции также устанавливает ее тип (типы аргументов и тип возвращаемого значения), но лишь определение создает тело функции (выполняемые инструкции). Обратите внимание на то, что тело функции хранится в памяти как часть программы, поэтому правильно будет сказать, что определения функций и переменных выделяют память, а объявления — нет.

Разница между объявлением и определением позволяет разделить программу на части и компилировать их по отдельности. Объявления обеспечивают связь между разными частями программы, не беспокоясь об определениях. Поскольку все объявления должны быть согласованы друг с другом и с единственным объявлением, использование имен во всей программе должно быть непротиворечивым. Мы обсудим этот вопрос в разделе 8.3. А здесь мы лишь напомним о грамматическом анализаторе выражений из главы 6: функция

expression
вызывает функцию
term
, которая, в свою очередь, вызывает функцию
primary
, которая вызывает функцию
expression
. Поскольку любое имя в программе на языке С++ должно быть объявлено до того, как будет использовано, мы вынуждены объявить эти три функции.

double expression; //
это лишь объявление, но не определение

double primary

{

// ...

expression;

// ...

}

double term

{

// ...

primary;

// ...

}

double expression

{

// ...

term;

// ...

}

Мы можем расположить эти четыре функции в любом порядке, потому что вызов одной из функций всегда будет предшествовать ее определению. Таким образом, необходимо предварительное объявление. По этой причине мы объявили функцию

expression
до определения функции
primary
, и все было в порядке. Такие циклические вызовы весьма типичны.

Почему имя должно быть определено до его использования? Не могли бы мы просто потребовать, чтобы компилятор читал программу (как это делаем мы), находил определение и выяснял, какую функцию следует вызвать? Можно, но это приведет к “интересным” техническим проблемам, поэтому мы решили этого не делать. Спецификация языка С++ требует, чтобы определение предшествовало использованию имени (за исключением членов класса; см. раздел 9.4.4).

Помимо всего прочего, существует обычная практика (не программирования): когда вы читаете учебники, то ожидаете, что автор определит понятия и обозначения прежде, чем станет их использовать, в противном случае читатели будут вынуждены постоянно догадываться об их смысле. Правило “объявления для использования” упрощает чтение как для людей, так и для компилятора. В программировании существует и вторая причина, по которой это правило имеет большую важность. Программа может состоять из тысяч строк (а то и сотен тысяч), и большинство функций, которые мы хотим вызвать, определены “где-то”. Это “где-то” часто является местом, куда мы даже не собираемся заглядывать. Объявления, которые описывают только способ использования переменной или функции, позволяет нам (и компилятору) не просматривать огромные тексты программ.

8.2.1. Виды объявлений

Программист может объявить множество сущностей в языке С++. Среди них наиболее интересными являются следующие.

• Переменные.

• Константы.

• Функции (см. раздел 8.5).

• Пространства имен (см. раздел 8.7).

• Типы (классы и перечисления; см. главу 9).

• Шаблоны (см. главу 19).

8.2.2. Объявления переменных и констант

Объявление переменной или константы задает ее имя, тип и (необязательно) начальное значение. Рассмотрим пример.

int a; // без инициализации

double d = 7; // инициализация с помощью синтаксической конструкции =

vector<int> vi(10); // инициализация с помощью синтаксической

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

Полная грамматика языка описана в книге Язык программирования С++ Страуструпа и в стандарте ISO C++.

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

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

Ренгач Евгений
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