2010-03-25 89 views
1

//文件:foo.c的如何让这段代码编译?

static int var; 

void foo() 
{ 
var++; 
} 
foo.c文件的

//结束

//文件bar.c:

static int var; 

void bar() 
{ 
var++; 
} 
文件bar.c的

//结束

// main.c文件

​​

//文件结束main.c

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

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

+0

它使用'main main()'而不是'void main()'更好吗? – zneak 2010-03-25 20:57:02

+3

@nvl:应该是零。正确分开文件。 – zneak 2010-03-25 20:58:05

+1

您需要发布(a)用于尝试构建这些命令的命令以及(b)从编译器和/或链接器获得的错误消息。 – 2010-03-25 20:59:06

回答

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 
+0

GCC实际上是用'main.c'编写的,就像写在问题中一样。它只会抛出有关'printf'和'main'返回类型的隐式声明的警告。 – che 2010-03-25 21:12:24

+0

为什么函数原型需要'extern'? – 2010-03-25 21:13:46

+0

@jleeddev:在这种情况下,extern并不是绝对必要的,但它被一些人认为是很好的风格 – 2010-03-25 21:23:13

4

我希望它编译和打印0(但如果你想编译它为C++,你必须添加声明s为foo()bar(),并且在C或C++中,您可能会收到一个警告,main()应该确实返回一个int)。

由于var在三个文件的每一个文件中都被定义为静态的,所以您确实有三个单独的变量,它们都有相同的名称。也许最简单的方法是将每个文件视为定义一个包含其静态变量的结构。你所做的是叫做foo(),它增加了foo.var。然后您拨打bar(),增加bar.var。然后你打印出main.var,它被初始化为零,并且从未修改过。

+0

+1以确保完整性。 – 2010-03-25 21:01:28

0

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

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

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

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

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

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

0

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

但是,如果您在main.cfoo.cbar.c,并编译为

gcc main.c 

那么结果将是2因为只会有一个全局变量var