Понимание ключевого слова extern в C

Опубликовано: 5 Января, 2022

Я уверен, что этот пост будет таким же интересным и информативным для новичков C (то есть новичков), как и для тех, кто хорошо разбирается в C. Итак, позвольте мне начать с того, что ключевое слово extern применяется к переменным C (объектам данных ) и функции C. По сути, ключевое слово extern расширяет видимость переменных C и функций C. Вероятно, поэтому он был назван extern.
Хотя большинство людей, вероятно, понимают разницу между «объявлением» и «определением» переменной или функции, для полноты я хотел бы их прояснить.

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

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

 int foo (int arg1, char arg2);

Компилятор рассматривает это как:

 extern int foo (int arg1, char arg2);

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

 extern int var;

Здесь объявлена переменная целочисленного типа с именем var (она еще не определена, поэтому пока для var не выделяется память). И мы можем делать это объявление столько раз, сколько захотим. Все идет нормально.
А как бы вы определили var? Вы бы сделали это:

int var;

В этой строке объявлена и определена переменная целочисленного типа с именем var (помните, что определение - это надмножество объявления ). Поскольку это определение , также выделяется память для var. А теперь сюрприз. Когда мы объявили / определили функцию, мы увидели, что ключевое слово extern присутствует неявно. Но с переменными дело обстоит иначе. Если бы это было так, память для них никогда бы не была выделена. Следовательно, нам нужно явно включать ключевое слово extern, когда мы хотим объявить переменные, не определяя их. Кроме того, поскольку ключевое слово extern расширяет видимость для всей программы, используя ключевое слово extern с переменной, мы можем использовать переменную в любом месте программы при условии, что мы включаем ее объявление, переменная где-то определена.
Теперь давайте попробуем разобраться в extern на примерах.
Пример 1:

c

int var;
int main( void )
{
var = 10;
return 0;
}

Эта программа успешно компилируется. var определяется (и объявляется неявно) глобально.
Пример 2:

c

extern int var;
int main( void )
{
return 0;
}

Эта программа успешно компилируется. Здесь объявлен только var. Обратите внимание, что var никогда не используется, поэтому никаких проблем не возникает.
Пример 3:

c

extern int var;
int main( void )
{
var = 10;
return 0;
}

Эта программа выдает ошибку при компиляции (на этапе компоновки, подробнее здесь), потому что var объявлен, но нигде не определен. По сути, var не выделяется памяти. И программа пытается изменить значение переменной, которой вообще не существует, на 10.
Пример 4:

c

#include "somefile.h"
extern int var;
int main( void )
{
var = 10;
return 0;
}

Предполагая, что somefile.h содержит определение var, эта программа будет успешно скомпилирована.
Пример 5:

c

extern int var = 0;
int main( void )
{
var = 10;
return 0;
}

Как вы думаете, эта программа будет работать? Что ж, вот еще один сюрприз от стандартов C. Они говорят, что ... если переменная только объявляется и инициализатор также предоставляется с этим объявлением, тогда будет выделена память для этой переменной - другими словами, эта переменная будет считаться определенной. Следовательно, согласно стандарту C, эта программа будет успешно компилироваться и работать.
Итак, это был предварительный обзор ключевого слова extern в C.
Вкратце можно сказать:

  1. Объявление можно делать любое количество раз, а определение - только один раз.
  2. ключевое слово extern используется для расширения видимости переменных / функций.
  3. Поскольку по умолчанию функции видны во всей программе, использование extern не требуется в объявлениях или определениях функций. Его использование неявно.
  4. Когда extern используется с переменной, она только объявляется, а не определяется.
  5. В виде исключения, когда внешняя переменная объявляется с инициализацией, она также используется как определение переменной.
Хотите учиться на лучших видео и практических задачах, ознакомьтесь с Базовым курсом C для базового и продвинутого C.