2014-02-14 63 views
4

對不起,這類問題。但是,我對C\C++中的關鍵字extern非常好奇。在c/C++中使用extern的概念是什麼?

在搜索extern的解釋時我知道extern告訴編譯器該變量或函數已經在其他文件或程序中定義了。

但是,如果這是一種情況,那麼我們爲什麼使用extern

,我嘗試了一些代碼如下:

extern int var; 
int main(void) 
{ 
var = 10; 
return 0; 
} 

此代碼是給我一個錯誤消息unresolved external symbol "int var" ([email protected]@3HA)

,如果我使用像一些代碼:

extern int var; 
int main(void) 
{ 
int var = 10; 
return 0; 
} 

它不表現出任何錯誤,並給出我在主函數已定義的值相同。

那麼,任何人都可以幫我瞭解extern的行爲嗎? 我對此很困惑。 請原諒我,如果這不是一個有效的問題。 先謝謝您。

+0

'extern int var'是一個聲明,它沒有爲'var'分配任何內存,因此當你使用'var = 10'時,你的程序搜索'var'的定義但是找不到它。 –

+0

@jalf:他們不是一樣的 –

回答

5

extern用於指另一個翻譯單元(「源文件」)中的變量。 比如你的main.c中的代碼如下所示:

extern int var; 
int main(void) 
{ 
    var = 10; 
    return 0; 
} 

該代碼包含一個整數名爲VAR的聲明,但沒有定義,因爲EXTERN明確地說:「這樣做的定義是在別處」

你可以定義另一個源文件,比方說,other.c:

int var = 0; 

然後,這個新的翻譯單元添加到您的構建命令後,你的程序將鏈接的罰款,並在這兩個文件中的代碼可以在共享012上操作變量。

在第二個版本中,您只需在主函數中用局部變量覆蓋extern var的聲明。由於extern var不再使用(ODR-),因此鏈接器不需要它,所以您的可執行文件可以成功構建。

+0

謝謝你的回答。但是當我在其他文件中定義一個變量'int var;'時,它會給出錯誤信息爲'int var redefinition'。我應該在其代碼中包含其他文件嗎? –

+0

另一個文件不應該被包含在'#include'語句的意義上。源文件翻譯產生的目標文件應由鏈接器鏈接在一起。 –

+0

謝謝,它幫助我很多 –

3

第一個版本失敗,因爲你還必須提供extern -declared變量,即一個定義,通過與具有

int var; 
在其全球範圍內

一些其他的C文件鏈接。

第二個成功自int var = 10;main()shadows全球聲明;如果您希望變量是extern,即在許多C文件之間共享,這通常是一件壞事。當然,這種共享本身也很不好(參見:global variables)。

1

extern用於指示變量存在於另一個編譯單元中。如果您有:

的main.cpp

extern int var; 
int main(void) 
{ 
var = 10; 
return 0; 
} 

和:

var.cpp

int var; 

那麼你就不會得到鏈接器錯誤的鏈接程序會將main.cpp中的var與var.cpp中的decleration聯繫起來

在你的第二個例子中,你已經定義了一個extern int var,但你永遠不會引用它。 int var = 10與extern之一是完全不同的int var。當它們連接器運行時,它注意到你從不使用extern int var變量,所以不用去搜索它。

0

聲明一個變量extern告訴編譯器變量的實際情況是別的地方。如果你不在其他地方提供它,鏈接階段將失敗。

在第二個例子中,你不要指extern聲明的變量在所有。您在主函數的作用域中聲明瞭一個影響全局聲明的新函數。

1

我建議你必須清除你對變量的定義和聲明的理解。

extern關鍵字用於當你想說變量被分配了內存時你只想聲明該變量。

在聲明使用extern關鍵字編譯器將嘗試找到之前或之後的聲明可存在相同的變量定義的任何變量。

在第一種情況下,您只是聲明變量不分配任何內存即不定義變量。

您可以通過this更好地瞭解extern關鍵字。

1

如果你已經聲明瞭一個全局變量,比方說在file1.cpp double myvar=5,你要訪問file2.cpp該變量,然後在file2.cpp聲明爲

extern double myvar; 

在C++中,每個文件都稱爲編譯單元。要將文件編譯爲目標文件,需要聲明所有變量,但不需要對這些變量進行初始化或賦值。

返回到示例:

File1.cpp:double myvar=5這既是一個聲明和初始化。您可以將file1.cpp編譯爲file1.o。

File2.cpp:假設您在file2.cpp中的某處使用myvar,並且還想在file1.cpp中訪問該值(也許在計算之後)。因此,爲了能夠將file2.cpp編譯到file2.o中,您必須聲明extern double myvar,以便可以編譯file2.cpp。這將使編譯器愉快並將任務留給鏈接器。

現在您已經編譯了這些文件,您將擁有名爲(如果您使用的是g ++)file1.o和file2.o的對象文件(翻譯單元)。現在鏈接器的工作是將它們鏈接在一起,讓file2.o訪問myvar

相關問題