初始化标头中的静态变量

时间:2010-10-01 08:14:04

标签: c variables static linker

我是C语言编程的新手,所以我尝试了许多不同的东西来尝试熟悉语言。

我写了以下内容:

档案 q7a.h

static int err_code = 3;
void printErrCode(void);

文件 q7a.c

#include <stdio.h>
#include "q7a.h"

void printErrCode(void)
{
        printf ("%d\n", err_code);
}

文件 q7main.c

#include "q7a.h"

int main(void)
{
        err_code = 5;
        printErrCode();

        return 0;
}

然后我在makefile中运行了以下内容(我使用的是Linux操作系统)

gcc –Wall –c q7a.c –o q7a.o
gcc –Wall –c q7main.c –o q7main.o
gcc q7main.o q7a.o –o q7

输出为3。

为什么会这样?

如果在头文件中初始化静态变量(实际上是任何变量),那么如果2个文件包含相同的头文件(在本例中为q7.c和q7main.c),则链接器将给出错误定义两次相同的var?

为什么不将值5插入到静态var中(毕竟它是静态和全局的)?

感谢您的帮助。

4 个答案:

答案 0 :(得分:34)

static表示该变量仅在编译单元中使用,不会向链接器公开,因此如果头文件中有static int并且包含两个单独的.c文件,你将拥有该int的两个离散副本,这很可能根本不是你想要的。

相反,您可以考虑extern int,并选择一个实际定义它的.c文件(即只int err_code=3)。

答案 1 :(得分:2)

静态变量不具有外部链接,这意味着它们不能在定义它们的翻译单元之外访问。所以在你的情况下,q7.h在翻译单元q7a.c和q7main.c中都是#include'ed ...在它们相应的.o文件中存在两个不同的副本。这就是链接器不报告错误的原因,因为链接器在执行外部符号链接时不会看到这两个副本。

答案 2 :(得分:2)

当您将变量声明为静态变量时,它仅在文件内具有作用域,即只能在文件内访问。 当您在头文件中声明静态变量并将此头文件包含在两个.c文件中时,您将创建两个不同的文件。 两个不同的“ .c”文件的内存

直接在Main函数中打印err_code时,您会看到其值为5而不是3, 但是您正在调用函数printErrCode,该函数在另一个文件“ q7a.c”中定义,该文件的err_code具有不同的存储位置 其中err_code内存仍为3并且未更新,这就是为什么您将值设为3而不是5的原因。

由于创建了两个内存,并且err_code被视为两个不同的变量,它们具有不同的内存,并且文件范围不同,所以您不会看到任何链接错误。

答案 3 :(得分:0)

虽然进行小型研究后才知道我们可以在Header文件中声明变量,但在其中一个源文件包含应该有该变量的定义。

相反,如果我们在头文件中定义一个变量。在包含此头文件的源文件中,将创建导致多个定义的定义。

静态变量应该在我们使用它的文件中声明,不应该暴露给头文件。

希望我能提供正确的信息。如果我错了,请随时在评论中纠正我的陈述。