Спецификатор extern
В языке С при редактировании связей к переменной может применяться одно из трех связываний: внутреннее, внешнее или не относящееся ни к одному из этих типов. В общем случае для имен функций и глобальных переменных предназначено внешнее связывание. Это означает, что после компоновки они будут доступны во всех файлах, составляющих программу. К объектам, объявленным со спецификатором static и видимым на уровне файла, применяется внутренне связывание, после компоновки они будут доступны только внутри того файла, в котором объявлены. К локальным переменным связывание не применяется, и поэтому они доступны только внутри своих блоков. Спецификатор extern указывает на то, что к объекту применяется внешнее связывание. Объявление (декларация) объявляет имя и тип объекта. Описание (определение, дефиниция) выделяет для объекта участок памяти, где он будет находиться. Один и тот же объект может быть объявлен неоднократно в разных местах, но описываться только один раз. Рассмотрим пример применения спецификатора extern глобальным переменным:
Описание глобальных переменных дано за пределами главной функции main(). Если бы их объявление и инициализация встретились перед main(), то в объявлении со спецификатором extern не было бы необходимости. При компиляции выполняются следующие правила: 1) если компилятор находит переменную, не объявленную внутри блока, он ищет ее объявление во внешних блоках; 2) если не находит ее там, то ищет среди объявлений глобальных переменных. Спецификатор extern играет большую роль в программах, состоящих из многих файлов [3]. В языке С программа может быть записана в нескольких файлах, которые компилируются раздельно, а затем компонуются в одно целое. В этом случае необходимо как-то сообщить всем файлам о глобальных переменных программы. Самый лучший (и легко переносимый) способ сделать это – определить (описать) все глобальные переменные в одном файле и объявить их со спецификатором extern в остальных файлах. Например:
В программе первый файл – это основная часть программного проекта. Второй файл создан как текстовый (с помощью блокнота) с расширением *.h. Список глобальных переменных (x, y, ch) копируется из первого файла во второй, а затем добавляется спецификатор extern, сообщающий компилятору, что имена и типы переменных, следующих далее, объявлены в другом месте. Все ссылки на внешние переменные распознаются в процессе редактирования связей. Подключение второго файла выполнено с указанием имени диска (D:), на котором расположен файл second.h. Для подключения имени файла, созданного пользователем, его заключают в двойные кавычки. Результат выполнения программы показан на рис. 17.1. В общем случае h -файл (например, second.h) формируется редактором кода: надо создать заготовку обычным способом, очистить все поле редактора и записать в него необходимые данные (программный код созданной функции), затем выполнить команду главного меню File/Save as и выбрать для сохраняемого файла расширение .h в раскрывающемся списке типов сохраняемого файла: C++ Header Files (*.h; *.hh; *.hpp; *.hxx; *.inl; *.tlh; *.tli). Сохраненный файл с расширением .h следует подключить к проекту. Для этого потребуется в узле Solution Explorer навести курсор мыши к папке Header Files и правой кнопкой мыши выбрать Add ® Existing Item сохраненный файл second.h. Затем с помощью оператора #include файл нужно включить в основную программу. Другой способ, реализуемый в Microsoft Visual Studio 2010, состоит в том, чтобы сразу через пункт меню File выбрать New ® File и далее в списке Installed Templates Visual C++ ® Header File (.h). Откроется окно, представленное на рис. 17.2. Далее в правом нижнем углу нажмем клавишу Open. Откроется пустое поле – заготовка для набора необходимого кода. По умолчанию этот файл имеет имя Header1.h. При повторном создании заголовочного файла это будет Header2.h и т. д. После написания кода можно сохранить этот заголовочный файл по желанию в любом каталоге с любым (допустимым) именем (расширение остается .h).
|