我在閱讀時遇到以下問題......只是無法得到此背後的邏輯。爲什麼使用'extern'聲明而不是定義創建一個變量?
auto int c;
static int c;
register int c;
extern int c;
給出前三個是定義,最後一個是聲明..怎麼來的?
我在閱讀時遇到以下問題......只是無法得到此背後的邏輯。爲什麼使用'extern'聲明而不是定義創建一個變量?
auto int c;
static int c;
register int c;
extern int c;
給出前三個是定義,最後一個是聲明..怎麼來的?
最後一個與extern
沒有定義存儲c
。它僅僅表示c
存在於某處,鏈接器應該能夠將其解析爲其他地方定義的全局c
。
如果您編譯並鏈接了一個.c文件,並嘗試使用最後一個c
,則會出現鏈接器錯誤。在第一個3 c
的情況下,你不會因爲它們在當前編譯單元中具有實質性(它們已經被定義爲)。
如果你想了解更多關於extern
和聲明vs定義,這裏是關於這個話題的good article。
變量/函數的聲明只是聲明的變量/函數在程序中的某處存在,但內存不爲它們分配
關鍵字extern
引用的事實:從該文章引述變量(或可能的函數)的定義在其他地方;然後編譯器將這個聲明鏈接到一個單獨文件中定義的主體。前三個關鍵字聲明瞭一個聲明 - 該變量沒有在其他地方定義,因此不是prototypes
。
舉例來說,假設你有一個項目結構如下所示:
..
-- main.c
-- client.c
-- client.h
-- server.c
-- server.h
當gcc
編譯這些使用頭文件,頭文件一般define
方案所需的變量。這將分配一個鏈接到.c文件中符號的declaration
的符號。這是編譯器如何將各種項目文件與.o
對象鏈接起來。您可能會對如何使用objdump -d
(假設您在Linux上)調試程序的實際反彙編結構感興趣。
享受和祝你好運!
前3條語句實際上爲int
分配了一個位置。
最後一個沒有。它所做的只是告訴編譯器在另一個編譯單元中的某個地方,將會定義一個名爲c
的int
。
如果未定義,則稍後會收到鏈接器錯誤。不出所料,鏈接器會說c
沒有被定義。
前三個是定義,因爲它將爲變量留出存儲空間。
最後一個將不會爲int c
分配任何存儲空間。它只會使用分配並在別處命名的存儲。
爲什麼downvotes?這是這個論壇的有效問題。 – 2012-07-16 15:32:33
這四個都是聲明。前三個也是定義。 – 2012-07-16 15:35:06
@Blank - 這是一個愚蠢的問題。 'extern'意味着在其他地方定義。爲什麼這不是一個定義? – 2012-07-16 17:28:18