我是新来的C.我有一本书在我的面前,解释C'S“文件范围”,包括示例代码。 但代码只声明并初始化文件范围的变量 - 它不核实,比如说变量的作用域,试图访问它以非法方式。 所以! 在科学的精神,我构建了一个实验。
文件bar.c
:
static char fileScopedVariable[] = "asdf";
文件foo.c
:
#include <stdio.h>
#include "bar.c"
main()
{
printf("%s\n", fileScopedVariable);
}
根据我的书,并给谷歌,调用printf()
应该失败-但事实并非如此。 foo.exe
输出字符串“ASDF”和正常终止。 我非常喜欢使用文件作用域。 我在想什么?
您执行#included bar.c,它具有使预处理器bar.c的内容逐字复制到foo.c的编译器接触它之前的效果。
尝试摆脱的包括,但告诉你的编译器来编译这两个文件(如gcc foo.c bar.c
),看它抱怨如您所愿。
编辑:我想主混乱是编译器和预处理器之间。 语言规则是由编译器执行。 预处理器编译器之前运行,作用于通过#前缀的命令。 所有预处理程序所做的就是操纵纯文本。 它不解析代码或试图以任何方式解释代码的含义。 该“#包括”指令是非常字面 - 它告诉预处理器“在这里插入该文件的内容”。 这就是为什么你通常只在.H(头)文件使用的#include,你只把函数原型和外部变量的声明在头文件中。 否则,你最终会编译相同的功能,或定义相同的变量,多次,这是不合法的。
这是容易混淆的名词引起的。 file scope
在C不指限制的标识符的连接到仅一个翻译单元。 这也并不意味着,范围仅限于一个物理文件。 相反, file scope
意味着你的标识符是全球性的。 术语file
,在这里,是指从处理所有结果的文本#include
, #define
和其他预处理器指令。
在一般情况下,范围只考虑一个翻译单元内生效的概念。 当多次编译都参与其中,联动开始发生。
如果你宣布你的文件范围变量static
,那么它给人的变量内在联系,这意味着它是不是翻译单元的外部可见。
如果不对它做静态声明明确,或者如果你声明的文件范围变量extern
,那么它是其他翻译单元可见:这些,如果他们宣称具有相同标识符文件范围的变量,将有标识链接同一个变量。
在你的情况,列入bar.c
到foo.c
插入的定义fileScopeVariable
被编译成翻译单元。 因此,在这一单元中可见。
永远不要#包括.c文件像你做什么。 语言允许的话,但是C程序员就是不这样做,所以你会混淆挫折感的人,如果你做到这一点。 最有可能的,包括你自己。
“#包括”是指“编译器,请去其他文件,它钉到这一块的前面,你开始编译我的代码之前。”
有一次,我失去了一整天的时间在总的混乱,因为VxWorks的源文件中的一个这样做。 我仍然在他们那个以上POed。
除去第二指令包括。 由于这是上面说的...
编译代码之前编译预处理它。 在这个阶段,它处理以“#”所有的指令,像的#include,#define和等。
要查看该阶段的结果(如果你正在使用gcc),你只需运行“gcc的-E”。
文章来源: In C, how do I restrict the scope of a global variable to the file in which it's declared?