C 中extern的用法

2021-07-15 13:07:18 字數 4246 閱讀 5359

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宣告變...