2011-06-11 35 views
7

我寫下面的程序爲什麼以下

#include<stdio.h> 
main() 
{ 
     extern int i; 
     printf("\n%d",i); 
} 
int i=30; 

我期待的錯誤消息,因爲我是後主要初始化,但與此相反的程序給我output.Why它並沒有給我工作方案的誤差我想知道的。

+0

爲什麼會給你一個錯誤? – Marcin 2011-06-11 19:19:26

回答

8

由於表示i中的符號仍然存在於程序空間。通過聲明它爲「extern」,你告訴編譯器在遇到它之前不一定期待「i」的定義......換句話說,你明確地告訴編譯器相信該符號將在稍後被鏈接。

從根本上說,這與在完全獨立的函數庫中定義函數並在主函數中聲明extern不同。順序是不重要的,因爲符號仍將在被鏈接。

+1

+1那麼解釋。 – 2011-06-11 19:21:52

21

extern整個目的是,它說「有一個叫iint類型的變量,在項目,以後可能在鏈接的地方。只是假設它的存在」。

您可以在完全獨立的.c文件中定義i,只要您將.o文件鏈接在一起,它就會一直工作。 這就是extern確實

就好像你可以聲明一個函數並使用它,即使它是在一個完全獨立的.c文件中定義的(或者實際上,在後面的同一個文件中)。

閱讀C書中關於extern的章節。

+1

我upvoted只是在你的答案的最後一行 – 2011-06-11 21:02:36

+0

@Eknath:嘿謝謝; p – 2011-06-12 04:15:03

+0

這就是我的一天學到的一天...:D(初級在C) – Anonymous 2011-06-15 07:18:08

3

extern是在當前模塊的外部定義的東西。如果您的聲明稍後出現,或者您的聲明位於某個尚未遇到的其他文件中,則可以使用extern。

[節省您努力 - 下面>線從WIKIPEDIA]

當定義的變量,則告訴編譯器該變量分配內存,並且還可能將其內容初始化爲某個值。

當你聲明一個變量時,你告訴編譯器該變量是在別處定義的。

您只是告訴編譯器,該名稱和類型存在一個變量,但編譯器不應該爲它分配內存,因爲它在其他地方完成。

extern關鍵字的意思是「不定義聲明」。換句話說,它是一種顯式聲明變量的方法,或者在沒有定義的情況下強制聲明。

瞭解更多:http://wiki.answers.com/Q/What_is_the_use_of_extern_in_C#ixzz1OzrWVmAC

1

作爲i被主B之後初始化

全局變量我期待的錯誤信息(如具有靜態存儲持續時間的所有變量)在main()中的代碼開始執行之前進行初始化,而不管您定義的代碼在哪裏。

+0

我懷疑他實際上意味着聲明定義而不是特別初始化。當然,但是,你是對的。 – 2011-06-11 19:24:46

3

如果您想更深入地瞭解我如何從main訪問以及初始化它的時間,您可以查看示例程序集輸出。正如在下面的評論中指出的那樣,它來自一個工具鏈(gcc/linux),但應該有助於給出一張好照片。它顯示我在數據段中,並在執行main之前初始化。

.file "test.c" 
    .section .rodata 
.LC0: 
    .string "\n%d" 
    .text 
.globl main 
    .type main, @function 
main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    subl $16, %esp 
    movl i, %edx 
    movl $.LC0, %eax 
    movl %edx, 4(%esp) 
    movl %eax, (%esp) 
    call printf 
    leave 
    ret 
    .size main, .-main 
.globl i 
    .data 
    .align 4 
    .type i, @object 
    .size i, 4 
i: 
    .long 30 
    .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2" 
    .section .note.GNU-stack,"",@progbits 
+0

一個工具鏈運行的組裝輸出與標準的保證不一樣。但是,仍然研究得很好...... – 2011-06-11 19:52:44