Intereting Posts
Что вы можете сделать в C без «std»? Являются ли они частью «С» или просто библиотек? Как запретить пользователям вводить неверные данные? Включить заголовки в заголовочный файл? Объясните разницу между ближайшими, большими и большими указателями в c? ID2D1HwndRenderTarget всегда имеет черный фон вместо прозрачного Предоставляет ли компилятор возможность добавлять функции в стандартные заголовки? Сравнение массивов C Unsigned integer и unsigned char, имеющие одинаковое значение, но по-другому ведут себя по-другому? Является ли GNU gprof ошибкой? Бит popcount для большого буфера, с процессором Core 2 (SSSE3) Минимальная реализация sprintf или printf Ядро запускается в CUDA при использовании Thrust 2 ^ n экспоненциальные вычисления действительно менее эффективны, чем бит-сдвиги? Я получаю «несовместимый тип указателя», и я не понимаю, почему Как препроцессор типа (macros) для вывода int

Переобучение глобальной переменной vs локальной переменной

Когда я скомпилирую код ниже

#include int main() { int a; int a = 10; printf("a is %d \n",a); return 0; } 

Я получаю сообщение об ошибке:

 test3.c: In function 'main': test3.c:6:5: error: redeclaration of 'a' with no linkage test3.c:5:5: note: previous declaration of 'a' was here 

Но если я делаю переменную global, тогда она отлично работает.

 #include int a; int a = 10; int main() { printf("a is %d \n",a); return 0; } 

Почему объявить одну и ту же глобальную переменную дважды не ошибкой, но сделать это для локальной переменной является ошибкой?

В C оператор int a; когда сделано в области файлов, является декларацией и предварительным определением . Вы можете иметь столько предварительных определений, сколько хотите, если они все соответствуют друг другу.

Если определение (с инициализатором) появляется до конца блока перевода, переменная будет инициализирована этим значением. Наличие нескольких значений инициализации является ошибкой компилятора.

Если конец единицы перевода достигнут, и не было найдено никаких предварительных определений, переменная будет нулевой инициализирована.

Вышеприведенное не применяется к локальным переменным. Здесь декларация также служит определением, и наличие нескольких ошибок приводит к ошибке.

Другая причина, о которой я мог думать, это то, что не инициализированные глобальные переменные хранятся в BSS (Block Structured Segment), где инициализируются глобальные переменные, хранятся в сегменте данных.

Я предполагаю, что существует какое-то разрешение пространства имен, и когда есть конфликт, переменная в сегменте данных переопределяет переменную в блочном структурированном сегменте.

если вы хотите объявить

int a = 5 int a = 10

в глобальном масштабе (как в сегменте данных) возникнет конфликт, как ожидалось.

Вы не можете иметь две глобальные переменные с тем же именем в программе C. C может допускать несколько определений в той же области файла с помощью правила предварительного определения, но в любом случае все определения будут относиться к одной и той же переменной.

Локальная переменная

В C несколько локальных переменных не объединяются в один.

Все локальные переменные с тем же именем будут ссылаться на разный объем памяти.

  #include int main() { int a; int a = 10; printf("a is %d \n",a); return 0; } 

Поэтому при назначении памяти для повторной записи одной и той же переменной она дает ошибку.

Глобальная переменная

В C несколько глобальных переменных «сливаются» в один. Таким образом, у вас действительно есть только одна глобальная переменная, объявленная несколько раз. Это происходит в то время, когда экстерн не был нужен (или, возможно, не существовал – не совсем уверен) в C.

Другими словами, все глобальные переменные с одинаковым именем будут преобразованы в одну переменную, поэтому ваши

 #include int a; int a = 10; int main() { printf("a is %d \n",a); return 0; } 

будет ссылаться на тот же самый объем памяти.