Что такое концепция использования extern в c / c ++?

Извините за этот вопрос. Но мне очень интересно узнать о ключевом слове extern в C\C++ .

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

Но если это так, то почему мы используем extern ?

поскольку я пробовал некоторые коды следующим образом:

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

Этот код дает мне сообщение об ошибке как unresolved external symbol "int var" (?var@@3HA) .

и если я использую какой-то код, например:

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

Он не показывает никаких ошибок и дает значение такое же, как я определил в основной функции.

Итак, может ли кто-нибудь помочь мне в отношении поведения extern ? Я немного смущен этим. Пожалуйста, простите меня, если это недействительный вопрос. Заранее спасибо.

extern используется для обозначения переменной в другой единицы перевода («исходный файл»). Например, ваш код в main.c выглядит так:

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

Этот код содержит объявление для целого числа с именем var, но не определение, потому что extern явно говорит: «определение для этого есть где-то еще»

Вы можете определить другой исходный файл, скажем, other.c:

 int var = 0; 

Затем, после добавления этой новой единицы перевода в команду сборки, ваша программа будет хорошо связываться, а код в обоих файлах может работать с общей переменной var .

Во второй версии вы просто переопределяете объявление extern var локальной переменной в своей основной функции. Поскольку extern var больше не используется (ODR-), компоновщик не требует этого, поэтому ваш исполняемый файл может успешно сгенерироваться.

Первая версия завершается с ошибкой, так как вы также должны предоставить определение переменной extern indeclared, то есть путем связывания с некоторым другим C-файлом, который имеет

 int var; 

в глобальном масштабе.

Второй преуспевает, поскольку int var = 10; line в main() затеняет глобальную декларацию; это, как правило, плохо, если вы хотите, чтобы переменная была extern, то есть разделялась между многими C-файлами. Разумеется, такое совместное использование само по себе также довольно плохое (см. Глобальные переменные ).

extern используется для указания того, что переменная существует в другом модуле компиляции. Если у тебя есть:

main.cpp

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

а также:

var.cpp

 int var; 

Тогда у вас не было бы ошибки компоновщика, поскольку компоновщик подключил бы использование var в main.cpp с его объявлением в var.cpp

Во втором примере вы определили extern int var но никогда не ссылаетесь на него. int var = 10 – это совершенно другой int var из внешнего. Когда они запускаются, он замечает, что вы никогда не используете переменную extern int var поэтому не пытайтесь ее искать.

Я предлагаю вам очистить свое понимание определения и объявления переменной.

Ключевое слово extern используется, когда вы хотите сказать, что переменной была выделена память, которую вы хотите только объявить переменной.

Когда вы объявляете какую-либо переменную, используя компилятор ключевого слова extern, попытается найти определение той же переменной, которая может присутствовать до или после объявления.

В первом случае вы просто объявляете переменную, не назначая ей какую-либо память, а не определяющую переменную.

вы можете пройти через это, чтобы лучше понять ключевое слово extern.

Если вы double myvar=5 глобальную переменную, скажем, double myvar=5 в файле file1.cpp, и вы хотите получить доступ к этой переменной в файле file2.cpp, то в файле file2.cpp вы объявляете

 extern double myvar; 

В C ++ каждый файл называется единицей компиляции. Чтобы файл был скомпилирован в объектный файл, вам нужны все объявленные переменные, но вам не нужно инициализировать или выполнять назначение этих переменных.

Возвращаясь к примеру:

File1.cpp: double myvar=5 это и объявление, и инициализация. Вы можете скомпилировать файл file1.cpp в файл file1.o.

File2.cpp: Предполагая, что вы используете myvar где-то в файле file2.cpp, а также хотите получить доступ к значению (возможно, после вычисления) в файле file1.cpp. Поэтому, чтобы иметь возможность компилировать файл file2.cpp в file2.o, вы должны объявить extern double myvar , чтобы файл file2.cpp мог быть скомпилирован. Это порадует компилятор и оставляет задачу для компоновщика.

Теперь, когда вы скомпилировали эти файлы, у вас будут объектные файлы (единицы перевода), названные как (если вы используете g ++) file1.o и file2.o. Теперь это работа компоновщика, чтобы связать их вместе и позволить file2.o получить доступ к myvar .

Объявление переменной extern сообщает компилятору, что фактический экземпляр переменной находится где-то в другом месте. Если вы не предоставите его в другом месте, этап ссылки не будет выполнен.

Во втором примере вы вообще не ссылаетесь на объявленную переменную extern . Вы объявляете новый в рамках своей основной функции, который затеняет глобальную декларацию.