2012-03-28 162 views
2

我有一個頭文件,它聲明瞭一個extern變量。C extern變量訪問

因此,這將是這個樣子這個A.H文件

extern uint16_t externVariable; 

所以我有2點.c文件b和c中,我想訪問的A.H文件中的外部變量。在B和C的.c文件我已經包括了啊文件已經

當我沒有申報B中的變量,但在C中聲明(無字的extern),它是像

uint16_t externVariable; 

它的工作原理精細。但是當它在b和c中都有一些編譯錯誤。有什麼辦法可以解決這個問題嗎?

這樣做的原因是因爲我有一個.c文件中的代碼,我想將代碼分成兩個不同的.c文件以保持整潔和清晰。

+2

你真的不得不說「一些編譯錯誤」?你不能指定錯誤是什麼? – abelenky 2012-03-28 02:53:34

+0

順便說一句:你已經標記了這個問題C,但你指的是.cpp文件,這是C++的典型擴展。 C與C++不是同一種語言。 – abelenky 2012-03-28 04:05:45

回答

5

該變量只能在之間聲明一個源代碼文件。 (在你的例子中爲b.c)。

通過在頭文件中聲明extern,或者甚至在多個.c文件的頂部,您基本上都會聲明「該變量不在此處,它的外部但它確實存在,並且它將可見給你。」

變量只能「活」在一個文件中。

如果您試圖使其在多個源文件中「活動」(例如,通過在b.cc.c中聲明它),您將看到您看到的錯誤。

+3

值得一提的是*鏈接器*會發出錯誤,因爲它在兩個不同的文件中看到相同的名稱。這就像在兩個不同的源文件中定義相同的函數並鏈接結果。 – 2012-03-28 02:54:13

+0

另外值得注意的是,非extern聲明應該在只會被編譯一次的文件中聲明,即。 *不*通常在頭部。如果它位於標題中並且標題包含在多個位置,則可能會出現像@NiklasB這樣的錯誤。提及。 – Dmitri 2012-03-28 05:20:54

0

extern的想法是讓編譯器知道這個變量是在一個不同的源文件中分配的,所以你做而不是需要在另一個源文件中再次聲明它。把它放在一個文件中(我會說a.cpp,因爲它在a.h中),幷包含a.h,它將從所有的.cpp文件中運行。

1

「extern」告訴C編譯器這個函數或變量是在別處聲明的,所以即使沒有在頭文件中聲明它們並在.c文件中包含.h文件,也可以使用它們。注意,「extern」表示這個變量不是最初的聲明,最初的聲明不能有extern關鍵字。

在你的情況下,你在一個文件中聲明一個外部變量而不添加「static」關鍵字,所以變量的作用域將是整個項目。然後你聲明「uint16_t externVariable;」在2個地方,編譯器認爲他們都是最初的聲明都有相同的名稱,所以衝突開始了。

例如,你可以這樣做:

例1:

交流轉換器:uint16_t externVariable;

b.c:extern uint16_t externVariable;

不用擔心你的頭文件,你可以在a.c和b.c中都使用externVariable。

實施例2:

交流轉換器的:#include 「A.H」

b.c的:#include 「A.H」

A.H:uint16_t externVariable;

This Works。

實施例3:

交流轉換器:的extern uint16_t externVariable;

b.c:uint16_t externVariable;

c.c:uint16_t externVariable;

由於您在多個位置聲明瞭externVariable,因此這不起作用。

實施例4:

交流轉換器:靜態uint16_t externVariable;

b.c:static uint16_t externVariable;

這將工作,因爲「靜態」關鍵字限制了他們的範圍,所以他們不會衝突。

實施例5:

交流轉換器:靜態uint16_t externVariable;

b.c:static uint16_t externVariable;

c.c:extern uint16_t externVariable;

由於「靜態」關鍵字限制了它們的作用域,編譯器無法找到你在c.c中聲明externVariable的地方,所以這仍然不起作用。

您還可以查看TCPL,它提供了關於這些關鍵字一個更大的圖片,希望這些例子可以幫助:)

+0

+1好例子! – lnafziger 2012-03-28 20:31:16