2010-03-25 68 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