c++
中extern
的用法1宣告外部實體
宣告外部全域性變數或物件,一般用於標頭檔案中,表示在其它編譯單元內定義的變數,鏈結時進行外部鏈結,如:
extern int ivalue;
此時的extern
是必須的,省略了
extern
編譯器將視為定義而不是宣告,一般地在源**中定義變數並進行初始化,在標頭檔案中使用
extern
宣告變數。
類該函式在其它編譯單元中定義,如:
extern void func( void );
此時的extern
可以省略
宣告:在某個標頭檔案
1.h(可以在同一檔案中或同一程式的不同檔案中出現多次
);定義:在任何乙個原始檔
x.cpp
(只能定義一次!
#include<1.h>);
使用:要使用這個全域性變數,只要包含
1.h就行了。
也可以在某個
.c 或
.cpp
檔案中宣告然後使用,在另外的
.c 或
.cpp
檔案中定義。
在全域性域中定義的物件
如果沒有指定顯式的初始值
則該儲存區被初始化為
0 因此下面兩個定義中
var1
和var2
有相同的初始值0
int var1 = 0;
int var2;
關鍵字extern
為宣告但不定義乙個物件提供了一種方法
實際上它類似於函式宣告承諾了該物件會在其他地方被定義,或者在此文字檔案中的其他地方
或者在程式的其他文字檔案中例如
extern int i;
對程式來說是乙個保證,表示在其他某個地方存在乙個如下所示的定義
int i;
extern
宣告不會引起記憶體被分配
它可以在同一檔案中或同一程式的不同檔案中出現多次
典型情況下
全域性物件的宣告只在公共的標頭檔案中出現一次
當乙個程式檔案需要引用這個全域性物件時
它可以包含這個標頭檔案
// 標頭檔案
extern int obj1;
extern int obj2;
// 文字檔案
int obj1 = 97;
int obj2;
既指定了關鍵字
extern
又指定了乙個顯式初始值的全域性物件宣告將被視為該物件的定義
編譯器將會為其分配儲存區
而且該物件後續的定義都被標記為錯誤例如
extern const double pi = 3.1416
;// 定義
const double pi
;//
錯誤:重複定義pi
關鍵字extern
也可以在函式宣告中指定
惟一的影響是將該宣告的隱式屬性
在其他地方定義
變為顯式的
這樣的宣告有下列形式
extern void putvalues
(int*
,int )
一般是在乙個原始檔如
1.cpp
裡定義變數,
如cstring str
;(這是定義,只能有乙個定義)
在其他檔案中要用使用時,可以在標頭檔案如
1.h裡宣告:
extern cstring str
;(宣告,可以有多處),然後
include
「1.h
」就行了,不用再定義,否則定義重複,也可以不用宣告;
include
「1.h
」中已經宣告。
例如:-----------------------------------------
1.h原始碼:
extern cstring str;//
這是宣告,表示這個變數在其他檔案裡有定義,這裡是
1.cpp.
一定要有個檔案裡有它的定義。 ……
------------------------------------------
1.cpp
原始碼:
include 「1.h」
…… cstring str
;// 定義
…… -----------------------------------------
2.cpp原始碼
include
「1.h
」//
宣告了變數
cstringstr
,並且在
1.cpp
裡定義了
str = "……"
;//
直接使用,
include
「1.h
」中已經宣告。
----------------------------------------- .h
檔案裡若沒有
extern
,表示定義;
.cpp
檔案裡有相同定義就是重複定義了; .h
檔案裡加了
extern
後,表示宣告,要有地方有它的定義(實現)。
2.宣告函式的編譯和鏈結方式
extern
後可以跟」
c」或」
c++
extern 「c」 voidadd( int a, int b);
extern 「c++」void sum(int* ia, int leng);
void sum(int*ia, int leng);
其中的extern
「c++
」可以省略,它是在
c++中預設的鏈結方式,即後面兩種宣告方式是等效的。這種宣告有兩種含義:首先,宣告這些函式使用外部鏈結方式,其實現不在本編譯單元之內;另一種含義,則是告訴編譯器編譯方式,如
extern 「c
」則是告訴編譯器使用
c語言的編譯方式編譯該函式。
c++支援函式過載,所以引數不同在編譯後生成的函式名也不同,如:
int max(int a,int b);
int max(float a,float b);
在編譯時生成的函式名可能分別為
_max_int_int
、_max_float_float
,通過在函式名後加上引數型別來區分不同的函式,如果使用
c語言方式,則生成的函式名中不包含引數資訊,只生成
_max
,所以無法實現過載,也就是說在
extern 「c
」中不能出現函式名過載,例如:
extern 「c」
非法,編譯器將報錯。而
c++標準中並沒有定義
extern「c
」與extern
「c++
」的具體實現方式,不同編譯器生成的符號規則可能不同。
需要注意的是,如果函式宣告使用了
extern「c
」,則函式定義必須使用
c編譯器編譯,或者使用
extern 「c
」來修改函式的編譯方式,一般地將
extern 「c
」宣告的函式的定義所在的源程式副檔名使用
.c即可,而
c++**放在
.cpp
檔案中。如果將
extern 「c
」宣告的函式實現也放在
.cpp
中,則需要使用
extern 「c
」來宣告函式編譯方式
,例如:
extern 「c」 }
只有在c++
中使用c
語言的庫或者兩種語言混合程式設計的時候才會用到
extern 「c
」,而在
c語言中是不支援
extern 「c
」的,所以為了標頭檔案通用,需要使用巨集來控制,例如:
#ifndef max_h //
防止重複引用
#define max_h
#ifdef__cplusplus
extern"c"
#endif
#endif 其中
__cplusplus
為c++
定義的巨集,凡是
c++的編譯器都定義了該預編譯巨集,通過它來檢測當前編譯器是否使用的是
c++編譯器。
C 中extern 的用法
前段時間看了extern 的用法,今天試了一下出現了如下問題,我在乙個標頭檔案1中定義了全域性常量,然後在標頭檔案2中定義了同樣的全域性變數,然後把兩個標頭檔案包含在另外乙個cpp裡面出現了了重新定義的錯誤,去掉頭檔案2中的全域性定義,undeclared identifier 的錯誤。最後把2中的...
C 中extern 的用法
前段時間看了extern 的用法,今天試了一下出現了如下問題,我在乙個標頭檔案1中定義了全域性常量,然後在標頭檔案2中定義了同樣的全域性變數,然後把兩個標頭檔案包含在另外乙個cpp裡面出現了了重新定義的錯誤,去掉頭檔案2中的全域性定義,undeclared identifier 的錯誤。最後把2中的...
C 中extern的用法
1.宣告外部實體 宣告外部全域性變數或物件,一般用於標頭檔案中,表示在其它編譯單元內定義的變數,鏈結時進行外部鏈結,如 extern int ivalue 此時的extern是必須的,省略了extern編譯器將視為定義而不是宣告,一般地在源 中定義變數並進行初始化,在標頭檔案中使用extern宣告變...