26 июн. 2009 г., 00:26 отMetaphile

В C, как я могу ограничить область действия глобальной переменной файлом, в котором она объявлена?

Я новичок в C. У меня передо мной книга, в которой объясняется "область действия файла" C, включая пример кода. Но код только объявляет и инициализирует переменную области файла - он не проверяет область действия переменной, скажем, пытаясь получить к ней доступ незаконным способом. Так! В духе науки я построил эксперимент.

файлbar.c:

<code>static char fileScopedVariable[] = "asdf";
</code>

файлfoo.c:

<code>#include <stdio.h>
#include "bar.c"

main()
    {
    printf("%s\n", fileScopedVariable);
    }
</code>

Согласно моей книге и Google, звонокprintf() должен потерпеть неудачу - но это не так.foo.exe выводит строку "asdf" и заканчивается нормально. Я бы очень хотел использовать область видимости файлов. Что мне не хватает?

Ответы на вопрос(4)

25 июн. 2009 г., 22:02 отT.E.D.

Когда-либ # Включите файл .c, как вы делаете там. Язык это позволяет, но C-кодеры просто не делают этого, так что вы запутаете людей, если сделаете это. Скорее всего, включая себя.

"# include" означает "Компилятор, перейдите к этому другому файлу и прикрепите его к началу этого файла перед тем, как приступить к компиляции моего кода."

Однажды я потерял целый день в полной растерянности, потому что один из исходных файлов vxWorks сделал это. Я все еще нахожусь на них из-за этого.

25 июн. 2009 г., 21:27 отTyler McHenry

в результате чего препроцессор буквально копирует содержимое bar.c в foo.c до того, как его коснется компилятор.

Попытайтесь избавиться от включения, но при этом попросите компилятор скомпилировать оба файла (например,gcc foo.c bar.c) и смотри, как жалуешься.

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

25 июн. 2009 г., 21:43 отJohannes Schaub - litb

file scope в C не означает ограничение привязки идентификатора только к одной единице перевода. Это также не означает, что область действия ограничена одним физическим файлом. Вместоfile scope означает, что ваш идентификатор является глобальным. Семестрfile здесь относится к тексту, который получается в результате обработки всех#include, #define и другие директивы препроцессора.

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

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

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

В твоем случае включениеbar.c вfoo.c вставляет определениеfileScopeVariable в переводимую единицу перевода. Таким образом, это видно в этом блоке.

25 июн. 2009 г., 21:28 отdmitri

Перед компиляцией вашего кода компилятор предварительно обрабатывает его. На этом этапе он обрабатывает все инструкции, начинающиеся с '#', например #include, #define и т. Д.

Чтобы увидеть результат этого этапа, вы можете просто запустить 'gcc -E' (если вы используете gcc).

ВАШ ОТВЕТ НА ВОПРОС