2012-07-16 71 views
1

我在閱讀時遇到以下問題......只是無法得到此背後的邏輯。爲什麼使用'extern'聲明而不是定義創建一個變量?

auto int c; 
static int c; 
register int c; 
extern int c; 

給出前三個是定義,最後一個是聲明..怎麼來的?

+0

爲什麼downvotes?這是這個論壇的有效問題。 – 2012-07-16 15:32:33

+2

這四個都是聲明。前三個也是定義。 – 2012-07-16 15:35:06

+0

@Blank - 這是一個愚蠢的問題。 'extern'意味着在其他地方定義。爲什麼這不是一個定義? – 2012-07-16 17:28:18

回答

2

最後一個與extern沒有定義存儲c。它僅僅表示c存在於某處,鏈接器應該能夠將其解析爲其他地方定義的全局c

如果您編譯並鏈接了一個.c文件,並嘗試使用最後一個c,則會出現鏈接器錯誤。在第一個3 c的情況下,你不會因爲它們在當前編譯單元中具有實質性(它們已經被定義爲)。

如果你想了解更多關於extern和聲明vs定義,這裏是關於這個話題的good article

變量/函數的聲明只是聲明的變量/函數在程序中的某處存在,但內存不爲它們分配

1

關鍵字extern引用的事實:從該文章引述變量(或可能的函數)的定義在其他地方;然後編譯器將這個聲明鏈接到一個單獨文件中定義的主體。前三個關鍵字聲明瞭一個聲明 - 該變量沒有在其他地方定義,因此不是prototypes

舉例來說,假設你有一個項目結構如下所示:

.. 
-- main.c 
-- client.c 
-- client.h 
-- server.c 
-- server.h 

gcc編譯這些使用頭文件,頭文件一般define方案所需的變量。這將分配一個鏈接到.c文件中符號的declaration的符號。這是編譯器如何將各種項目文件與.o對象鏈接起來。您可能會對如何使用objdump -d(假設您在Linux上)調試程序的實際反彙編結構感興趣。

享受和祝你好運!

1

前3條語句實際上爲int分配了一個位置。

最後一個沒有。它所做的只是告訴編譯器在另一個編譯單元中的某個地方,將會定義一個名爲cint

如果未定義,則稍後會收到鏈接器錯誤。不出所料,鏈接器會說c沒有被定義。

1

這四個句子是聲明,但前三句也是定義。

閱讀here關於聲明和定義之間的區別。

auto,staticregister是變量的修飾符。閱讀有關它們的文檔。

extern只是聲明,因爲您告訴編譯器該變量或函數的定義是在別的地方 - 在另一個C模塊中。

希望它有幫助!

1

前三個是定義,因爲它將爲變量留出存儲空間。

最後一個將不會爲int c分配任何存儲空間。它只會使用分配並在別處命名的存儲。

相關問題