extern
extern,是計算機語言中的一個關鍵字,可置於變量或者函數前,以表示變量或者函數的定義在別的文件中。提示編譯器遇到此變量或函數時,在其它模塊中尋找其定義,另外,extern也可用來進行鏈接指定。
聲明可以多次,但是定義只能有一次。
(1) 變量
extern int a; //聲明一個全局變量
int a; //定義一個全局變量
extern int a = 0;//定義全局變量並給初值
int a = 0; //定義全局變量並給初值
當要引用一個全局變量時,就要聲明extern int a,這個時候extern不能省,否則就成定義了。
(2) 函數
函數也有聲明和定義,但由於函數的聲明和定義是有區別的,函數的定義是有函數體的,所以函數的聲明和定義都可以將extern省略掉,反正其他文件也是知道這個函數是在其他地方定義的。
extern "C"
extern "C"的主要作用就是爲了能夠正確實現C++代碼調用其他C語言代碼。加上extern "C"後,會指示編譯器這部分代碼按C語言(而不是C++)的方式進行編譯。由於C++支持函數重載,因此編譯器編譯函數的過程中會將函數的參數類型也加到編譯後的代碼中,而不僅僅是函數名;而C語言並不支持函數重載,因此編譯C語言代碼的函數時不會帶上函數的參數類型,一般只包括函數名。
例如函數void fun(int, int),編譯後的可能是_fun_int_int(不同編譯器可能不同,但都採用了類似的機制,用函數名和參數類型來命名編譯後的函數名);而C語言沒有類似的重載機制,一般是利用函數名來指明編譯後的函數名的,對應上面的函數可能會是_fun這樣的名字。
舉個例子:
test.h
#ifndef _HELLO_H_
#define _HELLO_H_
/* C++需加上extern "C" 聲明 */
#ifdef __cplusplus
extern "C" {
#endif
void hello(int number);
#ifdef __cplusplus
}
#endif
#endif
test.cpp
#include "test.h"
#include <iostream>
void hello(int number){
std::cout<<"hello: "<<number<<std::endl;
}
int main()
{
int num = 666;
hello(num);
return 0;
}
編譯運行:
下面一道面試題,爲什麼標準頭文件都有類似的結構?
#ifndef __INCvxWorksh //防止該頭文件被重複引用
#define __INCvxWorksh
#ifdef __cplusplus //告訴編譯器,這部分代碼按C語言的格式進行編譯,而不是C++的
extern "C"{
#endif
/*…*/
#ifdef __cplusplus
}
#endif
#endif /*end of __INCvxWorksh*/
參考
[1] extern “C”的作用詳解