Читать «Полный справочник по С++» онлайн - страница 21

Герберт Шилдт

В языке C++ предусмотрен еще один спецификатор хранения mutable. Он рассматривается в части II.

Спецификатор extern

Прежде чем рассмотреть спецификатор extern, опишем систему связей в языке C/C++. В языке C/C++ предусмотрено три категории: внешние, внутренние связи и их отсутствие. Как правило, функции и глобальные переменные имеют внешние связи. Это означает, что они доступны из любой части программы. Глобальные объекты, объявленные с помощью спецификатора static (описанного в следующем разделе), имеют внутренние связи. Они доступны лишь внутри файла, в котором описаны. Локальные переменные не имеют связей и, следовательно, видимы лишь внутри своего блока.

Главное предназначение спецификатора extern — указать, что объявляемый объект обладает внешними связями в рамках всей программы. Чтобы понять, почему это так важно, необходимо различать объявление (declaration) и определение (definition). В объявлении указываются имя и тип объекта. Определение выделяет память для объекта. В программе может быть несколько объявлений одного и того же объекта, но только одно определение.

В большинстве случаев объявление переменной одновременно является ее определением. Однако, указав перед именем переменной спецификатор extern, можно объявить ее, не определяя. Таким образом, чтобы обратиться к переменной, определенной в другой части программы, ее следует объявить, используя спецификатор extern.

Рассмотрим пример использования спецификатора extern. Обратите внимание на то, что глобальные переменные first и last объявлены после функции znain().

int main(void)

{

extern int first; /* Глобальные переменные */ printf("%d %d", first, last); return 0;

/* Глобальное определение переменных first и last */ int first = 10, last = 20;

Эта программа выведет на печать числа 10 20, поскольку глобальные переменные first и last, которые используются при вызове функции printf (), инициализированы именно этими значениями. Поскольку спецификатор extern в функции main() сообщает компилятору, что переменные first и last объявлены в другом месте (в данном случае в конце текущего файла), программа будет скомпилирована без ошибок, даже если переменные first и last будут использованы раньше своих определений.

Следует иметь в виду, что объявление переменных в качестве внешних, как показано в предыдущей программе, необходимо лишь потому, что переменные first и last не были объявлены до своего использования в функции main(). В противном случае необходимости в спецификаторе extern не было бы. Обнаружив переменную, ранее не объявленную в текущем блоке, компилятор проверяет, не объявлена ли она в охватывающих блоках. Если нет, компилятор проверяет глобальные переменные. Обнаружив совпадение, компилятор считает, что данная ссылка относится к ранее объявленной переменной. Если необходимо использовать переменную, объявленную позднее в том же файле, следует применять спецификатор extern.

Как указывалось выше, спецификатор extern позволяет объявить переменную, не определяя ее. Однако, если при этом выполняется инициализация переменной, объявление extern становится определением. Это важно, поскольку объект может иметь несколько объявлений, но только одно определение.