Внешняя переменная
Эта статья нуждается в дополнительных цитатах для проверки . ( январь 2017 г. ) |
В языке программирования C внешняя переменная — это переменная, определенная вне любого функционального блока. С другой стороны, локальная (автоматическая) переменная — это переменная, определенная внутри функционального блока.
В качестве альтернативы автоматическим переменным можно определить переменные, внешние по отношению ко всем функциям, то есть переменные, к которым любая функция может обращаться по имени. (Этот механизм похож на переменные Fortran COMMON или Pascal , объявленные во внешнем блоке.) Поскольку внешние переменные доступны глобально, их можно использовать вместо списков аргументов для передачи данных между функциями. Более того, поскольку внешние переменные продолжают существовать постоянно, а не появляются и исчезают при вызове и выходе из функции, они сохраняют свои значения даже после того, как функции, которые их установили, вернулись.
Определение, декларация и extern
ключевое слово
[ редактировать ] Чтобы понять, как внешние переменные связаны с extern
ключевое слово, необходимо знать разницу между определением и объявлением переменной. Когда переменная определена , компилятор выделяет память для этой переменной и, возможно, также инициализирует ее содержимое некоторым значением. Когда переменная объявлена , компилятор требует, чтобы переменная была определена в другом месте. Объявление сообщает компилятору, что переменная с таким именем и типом существует, но компилятору не нужно выделять для нее память, поскольку она выделена в другом месте.
extern
Ключевое слово означает «объявить без определения». Другими словами, это способ явного объявления переменной или принудительного объявления без определения. Также возможно явно определить переменную, т.е. принудительно определить ее. Это делается путем присвоения переменной значения инициализации. Если ни extern
ключевое слово и значение инициализации отсутствуют, оператор может быть либо объявлением, либо определением. Компилятор должен проанализировать модули программы и принять решение.
Переменная должна быть определена ровно один раз в одном из модулей программы. Если определений нет или их несколько, возникает ошибка, возможно, на этапе связывания. Переменная может быть объявлена много раз, если ее объявления согласуются друг с другом и с определением (что заголовочными файлами очень облегчается ). Он может быть объявлен во многих модулях, включая модуль, в котором он был определен, и даже много раз в одном и том же модуле. Но объявлять его более одного раза в модуле обычно бессмысленно.
Внешняя переменная также может быть объявлена внутри функции. В этом случае extern
Ключевое слово необходимо использовать, иначе компилятор сочтет его определением локальной ( автоматической ) переменной, которая имеет другую область действия, время жизни и начальное значение. Это объявление будет видно только внутри функции, а не во всем модуле функции.
The extern
Ключевое слово, примененное к прототипу функции, абсолютно ничего не делает (ключевое слово extern
Ключевое слово, применяемое к определению функции, конечно, бессмысленно). Прототип функции — это всегда объявление, а не определение. Кроме того, в стандарте C функция всегда является внешней, но некоторые расширения компилятора позволяют определять функцию внутри функции.
Внешняя переменная должна быть определена ровно один раз вне любой функции; это выделяет для него место. Переменная также должна быть объявлена в каждой функции, которая хочет получить к ней доступ; это указывает тип переменной. Декларация может быть явным
extern
утверждение или может быть неявным из контекста. ... Обратите внимание, что мы осторожно используем слова определение и объявление, когда ссылаемся на внешние переменные в этом разделе. Определение относится к месту, где переменная создается или назначается для хранения; Объявление относится к местам, где указывается природа переменной, но не выделяется память.
Область применения, срок службы и static
ключевое слово
[ редактировать ] К внешней переменной могут обращаться все функции во всех модулях программы. Это глобальная переменная . Чтобы функция могла использовать переменную, объявление или определение внешней переменной должно находиться перед определением функции в исходном коде. Или должно быть объявление переменной с ключевым словом extern
, внутри функции.
The static
ключевое слово ( static
и extern
взаимоисключающие), примененный к определению внешней переменной, немного меняет ситуацию: доступ к переменной возможен только из функций того же модуля, где она была определена. Но функция в том же модуле может передать ссылку (указатель) на переменную другой функции в другом модуле. В этом случае, даже если функция находится в другом модуле, она может читать и изменять содержимое переменной — она просто не может обращаться к ней по имени.
Также возможно использовать static
ключевое слово в определении локальной переменной. Без static
ключевое слово, переменная автоматически выделяется при вызове функции и освобождается при выходе из функции (отсюда и название «автоматическая переменная»). Его значение не сохраняется между вызовами функций. С static
ключевое слово, переменная выделяется при запуске программы и освобождается при ее завершении. Его значение не теряется между вызовами функций. Переменная по-прежнему является локальной, поскольку доступ к ней возможен только по имени внутри функции, которая ее определила. Но ссылку (указатель) на нее можно передать другой функции, позволив ей прочитать и изменить содержимое переменной (опять же не обращаясь к ней по имени).
Внешние переменные выделяются и инициализируются при запуске программы, а память освобождается только после завершения программы. Их время жизни такое же, как и у программы.
Если инициализация не выполняется явно, внешние (статические или нет) и локальные статические переменные инициализируются нулем. Локальные автоматические переменные не инициализированы, т.е. содержат «мусорные» значения.
The static
Ключевое слово, примененное к определению функции, изменяет связь функции так, что она видна только из той единицы перевода, где находится ее определение. Это предотвращает вызов функции по имени извне ее модуля (остается возможность передать указатель функции из модуля и использовать его для вызова функции). Объявление функции с помощью static
Ключевое слово также является хорошим способом сделать его имя коротким, избегая при этом конфликтов имен.
Пример (язык программирования C)
[ редактировать ]Файл 1:
// Explicit definition, this actually allocates
// as well as describing
int global_variable;
// Function prototype (declaration), assumes
// defined elsewhere, normally from include file.
void some_function(void);
int main(void) {
global_variable = 1;
some_function();
return 0;
}
Файл 2:
// Implicit declaration, this only describes and
// assumes allocated elsewhere, normally from include
extern int global_variable;
// Function header (definition)
void some_function(void) {
++global_variable;
}
В этом примере переменная Global_Variable определена в файле 1. Чтобы использовать ту же переменную в файле 2, ее необходимо объявить . Независимо от количества файлов глобальная переменная определяется только один раз; однако он должен быть объявлен в любом файле, кроме файла, содержащего определение.
Если программа находится в нескольких исходных файлах, а переменная определена в файле1 и используется в файле2 и файле3, то в файлах2 и файл3 необходимы объявления extern для связи вхождений переменной. Обычной практикой является сбор внешних объявлений переменных и функций в отдельном файле, исторически называемом заголовком, который включается с помощью #include в начале каждого исходного файла. Суффикс .h является традиционным для имен заголовков.
Обычная методология заключается в том, чтобы выделение и фактические определения помещались в файлы .c, но простые объявления и прототипы не выделяют, а просто описывают типы и параметры, чтобы компилятор мог работать правильно, и эта информация принадлежит заголовочному файлу .h, который другие могут безопасно включаться без какого-либо возможного конфликта.
См. также
[ редактировать ]- Объявление - конструкция языка программирования, определяющая свойства идентификатора.
- Прототип функции — объявление имени функции и сигнатуры типа, но не тела.
- Глобальная переменная - компьютерное программирование, переменная, доступная во всей компьютерной программе.
- Компоновщик (вычисления) - компьютерная программа, которая объединяет несколько объектных файлов в один файл.
- Локальная переменная - компьютерное программирование, переменная, которую можно использовать только в части программы (области действия).
- Область действия — часть компьютерной программы, в которой действительна заданная привязка имени.
- Статическая переменная — программная переменная, которая сохраняется на протяжении всего срока действия программы.
- Язык программирования C — книга Брайана Кернигана и Денниса Ритчи
Внешние ссылки
[ редактировать ]- Справочник по языку Microsoft C: Спецификаторы классов хранения для объявлений внешнего уровня
- «Стандарт C (C99 с техническими исправлениями TC1, TC2 и TC3)» (PDF) . (3,61 МБ ) . В частности, см. разделы 6.2.2 (Связывание идентификаторов), 6.2.4 (Продолжительность хранения объектов), 6.7.1 (Спецификаторы класса хранилища) и 6.9 (Внешние определения).