//文件: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(),但它仍然无法编译。
答案 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.c
和main.c
,则编译为
gcc main.c
然后结果将是2
,因为只有一个全局变量var
。