【问题标题】:Static variables in C accessed from another file从另一个文件访问的 C 中的静态变量
【发布时间】:2014-02-27 05:10:42
【问题描述】:

我有两个 C 文件,每个文件都定义了一个共享相同名称的静态 int 变量。 我的理解是,在顶层声明的静态变量应该仅限于在同一个文件中使用。 但是,当我运行我的程序时,很明显这些文件会影响彼此的静态变量的值。

我是否误解了 static 关键字的工作原理,还有其他方法可以实现这种基于文件的范围分离吗?

*编辑:添加源代码来演示问题。如 cmets 所示,此代码来自 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”)。

提前致谢

/弗里施

【问题讨论】:

  • 您能否提供一小部分代码示例?这些变量是在一个类中声明的吗?
  • 变量被限制在文件中,但内存不是。如果您有一个返回此静态变量地址的函数,则另一个文件中的另一个函数可以访问它。本质上,你可以有一个指向这个静态变量的指针。此外,如前所述,您应该举一个小例子。
  • Static variable 的可能重复项
  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。如果两个变量在两个单独的源文件中定义static int i = 0;,则有两个单独的变量。您将需要生成 MCRTE (How to create a Minimal, Complete, Tested and Readable Example),即 MCVE 或 SSCCE (Short, Self-Contained, Correct Example)。显然,您至少需要两个源文件来演示这个问题(但它们会很小)。您还应该确定您正在使用的平台(o/s、版本)和编译器(带有版本)。
  • 在顶层声明的静态变量不应仅限于在同一个文件中使用,但它们的可见性仅限于它们所在的同一个文件被声明在其中。这就是为什么你可以在不同的文件中拥有不同的同名静态变量。

标签: c static scope


【解决方案1】:

尽管我们经常用“文件”来谈论C程序的结构,但大多数时候“文件”的真正含义是翻译单元——源文件和一切也就是#included。

现在,C 中的static 变量表示具有内部链接的变量,即在不同翻译单元之间不能通过名称链接的变量。每个翻译单元在这种情况下都有自己的、完全独立的变量。在这种情况下,拥有多个翻译单元是绝对关键的:同样,只有在不同的翻译单元之间才有可能进行分离。

在您的示例中,您只有一个翻译单元:您将 .c 文件包含在一个 main.c 文件中,即您将所有翻译单元合并到一个翻译单元中。您问题的标题是指“从另一个文件访问”的静态变量。实际上,您的示例中没有“另一个文件”。你只有一个“文件”。

由于您将所有内容合并到一个翻译单元中,因此您的静态变量声明变成了一个翻译单元内同一变量的重复声明。

请注意,您的静态变量声明恰好同时是定义。在 C++ 中,相同变量的重复定义会触发“多重定义”错误。在 C 中,此类定义被视为暂定定义(C 特有的功能),这允许它们通过。但是,如果您将显式初始化程序添加到静态变量(例如static int buffer = 0;),则定义将不再是暂定的,即使在 C 中代码也将无法编译。

如果您想在这种情况下维护不同的独立变量,请停止将您的 .c 文件包含到您的 main.c 文件中。独立翻译每个.c 文件,作为一个单独的翻译单元,然后将它们链接到最终程序中。

【讨论】:

  • 这是一个很棒的答案。非常感谢。
【解决方案2】:

发生这种情况的一种方法是在两个文件中的函数之间传递指向这些静态变量的指针:

file1.c:

static int i1;
...
foo(&i1);

file2.c:

void foo(int *ip)
{
    *ip = 42;
}

在 file1.c 中调用 foo 会从函数 outside file1.c 修改 i1

【讨论】:

    【解决方案3】:

    我想通过包含你已经有效地声明了两次相同的静态全局变量,这就是为什么你不再有两个单独的变量,而是一个。

    【讨论】:

      【解决方案4】:

      按照您的做法,通过在 main 中包含文件 1 和文件 2,您实际上只有一个“缓冲区”变量。

      【讨论】:

        猜你喜欢
        • 2010-12-30
        • 2014-09-20
        • 2011-01-14
        • 2012-09-06
        • 2012-05-04
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多