C C 之關鍵字extern

2021-10-06 05:43:41 字數 2816 閱讀 8012

typist : akame qixisi / excel bloonow

extern是計算機語言c/c++中乙個關鍵字,可用於變數或函式前;對於使用者,它宣告乙個外部符號,以表示該變數或函式是定義在別的檔案中的外部符號;對於建立者,它用在標頭檔案中的乙個宣告之前或乙個定義之前,顯式說明該符號可以被其他檔案使用(有些形式具有預設的外部鏈結,可以不用extern顯式說明)。另外,extern也可以用來進行鏈結指定。

在編譯時,提示編譯器遇到此變數或函式時,知道這個識別符號在其他檔案中定義過,可以編譯通過。在鏈結時,提示鏈結器在其他檔案中尋找其定義。

需要注意的是,根據前述指標與陣列的區別,在乙個檔案中使用int a[8]定義乙個陣列,而在另乙個檔案中使用extern int* a去宣告這個外部符號,編譯可以通過,但它們的鏈結是不成功的。因此說明,在乙個檔案中定義的外部符號和在另一檔案中宣告的外部符號,必須是嚴格型別相同的。

// a.c		// 定義外部符號,以供其他檔案使用,注意參考《大規模c++程式設計》查閱預設具有外部鏈結的形式

int x =10;

int add (

int a,

int b)

// b.c		// 宣告外部符號,以便使用其他檔案定義的符號,可直接使用

extern

int x;

extern

intadd

(int

,int

);

現代編譯器一般採用按檔案編譯(其實是編譯單元)編譯的方式,因此在編譯時,各個編譯單元中定義的全域性變數是互相不透明的。也就是,在編譯時,全域性變數的可見域限制在檔案內部。到了鏈結階段,要將各個編譯單元中的符號鏈結到乙個程式中,因而,定義於某編譯單元的全域性變數,在鏈結完成後,它的可見範圍被擴大到了整個程式,很容易推導出,乙個檔案中定義的全域性變數,可以在整個程式的任何地方都使用。在鏈結時,如果在不同的編譯單元中存在重複的全域性定義,則會鏈結失敗。

首先明確,extern "c"是 c++ 中的寫法( .h 標頭檔案,.cpp 實現檔案),c語言中並沒有該寫法。

總括:extern 「c」 是 c++ 語言為了相容 c 程式、使用 c 語言庫,實現c++與c以及其他語言混合程式設計所引入的。為了更好的支援原來的c**和已經寫好的c語言庫,需要在c++中盡可能的支援c,而 extern 「c」 就是其中的乙個策略。任何語言中的任何語法特性的誕生都不是隨意而為的,**於真實世界的需求驅動。

對於乙個函式 int add(int a, int b)。由於c++支援過載,編譯器為了解決函式的過載問題,會將函式名和引數型別一起加到編譯後的**中,合起來生成乙個中間的函式名稱,如 _add_int_int 這樣的符號;而c語言並不支援函式過載,因此編譯c語言**的函式時不會帶上函式的引數型別,一般只包括函式名,如 _add 這樣的符號。不同的編譯器可能生成的名字不同,但是都採用了相同的機制,生成的新名字稱為」mangled name「。由於在c++**中編譯的符號和c**中編譯的符號不同,自然鏈結不成功。

同樣地,本質上,編譯器在c++中的類成員變數等時,與函式的處理相似,也為類中的變數取了乙個獨一無二的名字,這個名字與**中的名字不同。

extern 「c」 的主要作用就是為了能夠正確實現c++**呼叫其他c語言**,加上extern "c"後,會指示編譯器這部分(c++)**按c語言(而不是c++)的方式進行編譯,即函式編譯成的符號不帶引數型別資訊,從而c++**編譯後在目標檔案中的符號,就和c**編譯成的符號一樣,自然可以鏈結成功。一般來說有三種使用方式:

// myheader.h	c++標頭檔案

extern "c" int add(int, int); // 對於單一函式使用

extern "c"

extern "c"

由於對頭檔案來說,無法靠字尾名等形式區分是c語言的標頭檔案還是c++的標頭檔案,所以常使用乙個c++才有的巨集來判斷是否是c++檔案,如下:

// myheader.h

#ifdef __cplusplus // c++檔案(編譯器)才有的巨集定義,如果定義了,就說明這是c++**

extern "c"

#endif

常見的使用場合為:c++**呼叫c語言**;在c++的標頭檔案中使用;在多人協同開發時,可能有人比較擅長c語言,有人擅長c++等。如在c++中使用c語言函式或c語言的庫函式:

// c_sample.h		// c標頭檔案

#ifndef c_sample_h

#define c_sample_h

extern

intadd

(int x,

int y)

;// 自由free函式預設居然外部鏈結,可以不用extern

#endif

// c_sample.c // c實現檔案

#include

"c_sample.h"

intadd

(int x,

int y)

// tool_model.cpp	// c++實現檔案,也可以為c++標頭檔案或其他c++檔案

extern "c"

// use the c function somewhere.

int result = add(lvalue, rvalue);

同理,如果要從c++語言**中匯出函式,一共c語言程式使用,也需要在c++原始檔要匯出的函式前使用 extern 「c」 來修飾,以按c語言編譯風格編譯,讓c語言程式可以呼叫。

C C 中extern關鍵字

extern關鍵字可置於變數或者函式前,以表示變數或者函式的定義在別的檔案中,提示編譯器遇到此變數或函式時,在其它模組中尋找其定義。另外,extern也可用來進行鏈結指定。在介紹外部變數之前,先來看一下什麼是區域性變數。下面是乙個例子。include define maxline 1000 int ...

C C 的extern關鍵字

比如這是我的myextern.cpp檔案,只有一行 int ex 3 然後這是我的main.cpp include using namespace std intmain 如果我在main中加extern關鍵字 include using namespace std intmain 也就是說在沒有用...

C C 中extern關鍵字

當extern與 c 一起連用時,如 extern c void fun int a,int b 這就告訴編譯器在編譯fun這個函式名時按著c的規則去翻譯相應的函式名而不是c 的,c 的規則在翻譯這個函式名時會把fun這個名字弄得面目全非,例如 fun abc isdnfsdf 不同編譯器採取的翻譯...