我有两个C文件,每个文件都定义了一个共享相同名称的静态int变量。 我的理解是,在顶层声明的静态变量应限于同一文件中的使用。 但是,当我运行程序时,很明显这些文件会影响彼此静态变量的值。
我是否误解了静态关键字的工作原理,是否有其他方法可以获得基于文件的范围分离?
*编辑:添加源代码以演示问题。此代码来自3个单独的文件,如注释所示。
//file 1
static int buffer;
void setter_1(int *input) {
buffer = *input;
}
void getter_1(int *output) {
*output = buffer;
}
//file 2
static int buffer;
void setter_2(int *input) {
buffer = *input;
}
void getter_2(int *output) {
*output = buffer;
}
//main
#include <stdio.h>
#include "buffer_1.c"
#include "buffer_2.c"
int main() {
int int1 = 1;
int int2 = 2;
setter_1(&int1);
setter_2(&int2);
getter_1(&int1);
getter_2(&int2);
printf("%i, %i\n", int1, int2);
return 0;
}
我们希望得到两个不同的数字(“1,2”),但得到两个相同的数字(“2,2”)。
提前致谢
/弗里希
答案 0 :(得分:3)
尽管我们经常以“文件”的形式谈论C程序的结构,但大多数时候“文件”的真正含义是翻译单元 - 源文件和所有内容那是#include
进入它。
现在,C中的static
变量表示带有内部链接的变量,即不能在不同翻译单元之间按名称链接的变量。每个翻译单元都是这样的情况下获得自己的,完全独立的变量。在这种情况下拥有多个翻译单元绝对是至关重要的:有关的分离只能在不同的翻译单元之间进行。
在您的示例中,您只有一个翻译单元:您将.c
个文件包含在一个main.c
文件中,即您将所有翻译单元合并为一个翻译单元。您的问题的标题是指“从另一个文件访问”的静态变量。实际上,您的示例中没有“另一个文件”。你只有一个“文件”。
由于您将所有内容合并到一个翻译单元中,因此静态变量声明成为一个翻译单元内同一变量的重复声明。
请注意,您的静态变量声明恰好是 definitions 。在C ++中,对同一变量的重复定义会触发“多重定义”错误。在C中,这样的定义被视为暂定定义(一种特定于C的特征),它允许它们通过。但是,如果向静态变量添加显式初始值设定项(例如static int buffer = 0;
),则定义将不再是暂定的,即使在C中代码也无法编译。
如果您想在这种情况下维护不同的独立变量,请停止将.c
个文件包含在main.c
文件中。单独翻译每个.c
文件,作为单独的翻译单元,然后将它们链接到最终程序中。
答案 1 :(得分:1)
这种情况的一种方式是当指向这些静态变量的指针在两个文件中的函数之间传递时:
file1.c中:
static int i1;
...
foo(&i1);
file2.c中:
void foo(int *ip)
{
*ip = 42;
}
在file1.c中调用foo会从函数外部 file1.c修改i1
答案 2 :(得分:1)
我认为通过包含有效地声明了两次相同的静态全局变量,这就是为什么你不再有两个单独的变量,而是一个变量。
答案 3 :(得分:1)
通过在main中包含文件1和文件2的方式,您实际上只有一个“缓冲区”变量。