如何编译这段代码?

时间:2010-03-25 20:52:02

标签: c

//文件:foo.c

static int var;

void foo()
{
var++;
}

//文件结束foo.c

//文件bar.c:

static int var;

void bar()
{
var++;
}

//文件bar.c的结尾

// file main.c

static int var;
void main()
{
foo();
bar();
printf("%d", var);
}

//文件main.c的结尾

问题:上述程序会编译吗?如果是这样,结果会是什么?

我测试了代码并发现它无法编译。我尝试在main.c中使用extern来使用函数foo()和bar(),但它仍然无法编译。

4 个答案:

答案 0 :(得分:6)

main.c有一些小问题 - 它应该是这样的:

#include <stdio.h>

static int var;

extern void foo();
extern void bar();

int main(void)
{
    foo();
    bar();
    printf("%d\n", var);
    return 0;
}

它应该像这样构建好:

$ gcc -Wall main.c foo.c bar.c -o main

,结果应为:

$ ./main
0

答案 1 :(得分:4)

我希望它能编译并打印0(虽然如果你想把它编译为C ++,你必须为foo()bar()添加声明,并且在C或C ++中,您可能会收到main()应该真正返回int的警告。

由于var在三个文件中的每个文件中都被定义为静态,因此您确实有三个单独的变量,这些变量都具有相同的名称。也许最容易将每个文件视为定义包含其静态变量的结构。您所做的工作称为foo(),其增加foo.var。然后你调用bar(),增加bar.var。然后你打印出main.var,它被初始化为零,从未修改过。

答案 2 :(得分:0)

这为我编译(尽管有关main()的返回类型的警告。)

根据main()将打印的内容,结果未确定,因为您尚未在main.c中初始化var的值。在没有优化的情况下调用编译器时最可能的结果是零,因为操作系统会将提供给进程的物理内存归零以进行数据存储(操作系统会这样做以避免在进程之间泄漏机密数据)。

var变量定义的静态限定符意味着变量在定义的源文件之外是不可见的。它还意味着三个var变量中的每一个都有自己的存储位置

如果我们分别向printf("[module name] *var=%p\n", &var)foo()bar()添加main()来打印存储这三个变量的内存位置的地址,那么您应该得到类似这样的内容: -

foo() *var=0x8049620
bar() *var=0x8049624
main() *var=0x8049628

请注意,每个变量都有自己的存储位置。每个源文件中的代码将访问特定于该源文件的var版本。在.c文件中使用static这样的{{1}}通常用于实现C中信息隐藏的概念。

答案 3 :(得分:0)

代码(原样)将编译并且结果将为0(正如Jerry所解释的),因为static变量将具有文件范围。

但是,如果您在foo.c中加入bar.cmain.c,则编译为

gcc main.c

然后结果将是2,因为只有一个全局变量var