Counter в c что это
Перейти к содержимому

Counter в c что это

статическая переменная в c

Привет, я готовлюсь к тесту на C, и я столкнулся с вопросом, на который я не могу найти ответа.

Программист написал программу для подсчета количества пользователей (Count.h, Count.c):

И тестер для проверки:

На удивление результат был:

Я не понимаю, почему при таком использовании статической переменной счетчик не увеличивается .. почему они получили такой ввод?

Спасибо вам всем!

7 ответов

Подумайте об этом как о том, что «файлов .h не существует». Что происходит, так это то, что файлы .h включаются в файлы .c, и только файлы .c компилируются (и связываются (смешиваются) вместе).

В вашем случае у вас есть 2 файла .c с

Каждый counter специфичен для того файла .c, в котором он находится. counter в CounterMain.c — это переменная, отличная от counter в Counter.c.

У вас должно быть одно одно определение счетчика. У вас может быть несколько объявлений (обычно в файлах .h)

Оххххххххххххххххх и вот что такое static . Не используйте его в глобальном масштабе!

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

Поскольку вы загружаете этот заголовок в 2 отдельных файла .c, каждый файл получает уникальную переменную. Увеличение «счетчика» в одном файле не влияет на «статическую» переменную в другом файле.

Подробнее см. в этом описании. Чтобы переменная была видимой и совместно используемой в нескольких файлах, ее необходимо объявить как extern. Иначе:

Статические глобальные переменные: переменные, объявленные как статические на верхнем уровне исходного файла (вне каких-либо определений функций), видны во всем этом файле («область файла»).

static int counter = 0;

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

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

Единица перевода — это, по сути, предварительно обработанный исходный файл. Он содержит все включенные заголовочные и исходные файлы, указанные в директивах #include , и исключает все, что исключено #if или подобными директивами.

Когда переменная в области видимости файла объявляется static , она дает имя переменной внутренняя связь . Это означает, что имя относится к объекту, локальному для единицы перевода, в которой оно появляется. Если имя используется в другой единице перевода, тогда оно не может относиться к объекту в этой единице перевода, оно должно относиться к другому объекту.

[Напротив, имя с внешней связью относится к одному и тому же объекту независимо от единицы перевода, в которой используется это имя.]

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

В вашем случае есть один counter в блоке перевода, созданном из CounterMain.c , и отдельный в блоке перевода, созданном из Count.c . Один в Count.c никогда не увеличивается, но возвращается getUserNum() , один в CounterMain.c увеличивается в main , но больше нигде не используется.

Ключевое слово static означает, что при использовании для определения функций или глобальных переменных функция или переменная должны иметь internal linkage , то есть они не должны отображаться как глобальный символ. Следовательно, каждая единица компиляции, включая Counter.h , будет иметь свою собственную локальную копию counter , которая не будет конфликтовать с другими.

В этом случае Counter.c и CounterMain.c имеют разные переменные count , что и приводит к тому, что вы описали.

Решение состоит в том, чтобы изменить определение counter в Counter.h на объявление:
extern int counter;
и поместить определение в Counter.c :
int counter = 0;

После этого CounterMain и любые другие единицы компиляции, включая Counter.h , должны иметь доступ к единственному экземпляру counter , но вы можете захотеть заняться information hiding и получить доступ к нему только через функции в Counter , в результате получается более чистый interface .

Это потому, что статическая переменная объявлена ​​в заголовке. В C статические переменные существуют только в файле .c , в котором они объявлены. Поскольку ваш .h включен (директивы #include можно рассматривать как не что иное, как операцию копирования и вставки) в двух разных файлах .c, создаются две статические переменные с именем counter , по одной в каждом файле. Ваш тестовый файл увеличивает свою локальную переменную counter , но переменная, возвращаемая getUsersNum , получена из другого файла C и полностью независима.

Вопрос пытается получить доступ к статической переменной из файла, отличного от того, в котором она была объявлена. Вы должны знать, что это (напрямую) невозможно. Чтобы увеличить правый счетчик, вам понадобится функция, которая работает с переменной counter Counter.c .

Переменная static доступна только в том файле, в котором она определена. В этом примере и Counter.c , и CounterMain.c имеют свою собственную переменную counter .

Когда выполняется ++counter , это обновляет переменную, объявленную в CounterMain.c . Но когда вызывается getUsersNum() , он возвращает значение переменной counter из Counter.c , которое не было увеличено.

Если вы измените getUsersNum() на counter , вы увидите, что переменная counter , объявленная в CounterMain.c , была увеличена.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *