extern關鍵詞詳解

2021-06-01 02:00:20 字數 4347 閱讀 3974

1. 用extern宣告外部變數

(1)在乙個檔案內宣告的外部變數

(2)在多個檔案中宣告外部變數

(3)在多個檔案中宣告外部結構體變數

2. 用extern宣告外部函式

3. 總結

1. 

用extern宣告外部變數

定義:外部變數是指在函式或者檔案外部定義的全域性變數。外部變數定義必須在所有的函式之外,且只能定義一次。

(1) 

在乙個檔案內宣告的外部變數

作用域:如果在變數定義之前要使用該變數,則在用之前加extern宣告變數,作用域擴充套件到從宣告開始,到本檔案結束。

例子:#include

int max(int x,int y); 

//函式提前宣告

int main(int argc,char *argv[ ] )

int x = 10; 

//定義外部變數

int y = 20;

int max(int x, int y)

其中,用extern宣告外部變數時,型別名可以省略。例如,「extern int x;」,可以改寫成「extern x;」。

小結:這種用方法簡單,實用性不大。

(2) 

在多個檔案中宣告外部變數

作用域:如果整個工程由多個檔案組成,在乙個檔案中想引用另外乙個檔案中已經定義的外部變數時,則只需在引用變數的檔案中用extern關鍵字加以宣告即可。可見,其作用域從乙個檔案擴充套件到多個檔案了。

例子:檔案a.c的內容:

#include

int base=2; 

//變數定義

int exe(int x);  

//外部函式提前宣告

int main(int argc, char *agrv)

檔案b.c的內容:

#include

extern base; 

//外部變數宣告

int exe(int x)

return ret; }

利用gcc工具編譯gcc a.c b.c –o demo,再執行./demo,結果為2^10 = 1024。其中,在a.c檔案中定義base=2,在b.c中引用base時,需要用extern關鍵字宣告其為外部變數,否則編譯會找不到該變數。

小結:對於多個檔案的工程,可以採用這種方法來操作。實際工程中,對於模組化的程式檔案,在其檔案中可以預先留好外部變數的介面,也就是只採用extern宣告變數,不定義變數,也通常在模組程式的標頭檔案中宣告,在使用該模組時,只需要在使用時定義一下即可,如上述b.c檔案,做好相應的函式介面,留好需要改變base值的宣告,在需要使用該模組時,只需要在呼叫的檔案中定義具體的值即可。

引用外部變數和通過函式形參值傳遞變數的區別:用extern引用外部變數,可以在引用的模組內修改其值,而形參值傳遞的變數則不能修改其值,除非是位址傳遞。

因此,如果多個檔案同時對需要應用的的變數進行同時操作,可能會修改該變數,類似於形參的位址傳遞,從而影響其他模組的使用,因此,要慎重使用。

(3) 

在多個檔案中宣告外部結構體變數

前面一節中,只是適合一般變數的外部宣告,但是對於宣告外部結構體變數時,則有些不同,需要加以注意。

例子:檔案a.c的內容:

#include

#include "b.h"

#include "c.h"

a_class local_post=; 

//全域性變數

a_class next_post=; 

//全域性變數

int main(int argc,char *argv)

檔案b.h的內容:

#ifndef __b_h

#define __b_h

#if  1

typedef structa_class;

#endif

extern a_class local_post;  //外部結構體變數宣告

extern a_class fun(int x,int y,int z); 

//介面函式宣告

#endif

檔案b.c的內容:

#include

#include "b.h"

a_class fun(a_class first,a_class next)

檔案c.h的內容:

#ifndef __c_h

#define __c_h

extern int print(char *,a_class post);

#endif

檔案c.c的內容:

#include

#include "b.h"

int print(char *str,a_class post)

利用gcc工具編譯gcc a.c b.c c.c–o demo,再執行./demo,結果為

first point : (1,2,3)

second point : (10,9,8)

the vector is (9,8,5)

小結:在a.c檔案中定義全域性變數a_class local_post結構體,並且呼叫b.c中的介面函式a_class fun(int x,int y,int z)和c.c中int print(char *str,a_class post),在b.h中宣告外部結構體變數local_post,同時,需要對其型別a_class進行實現,在b.h檔案中,如果遮蔽掉a_class的實現,而在b.h以外的檔案中實現,此時編譯時就會出錯,由於c.c檔案中用到a_class定義的型別,所以需要在該檔案中包含b.h。

這裡需要說明的是,如果呼叫外部結構體等多層結構體變數時,需要對這種變數進行實現,使用時,加上模組的標頭檔案即可,否則會報錯。

實際工程中,模組化程式檔案,一般提供乙個.c和乙個.h檔案,其中.h檔案被.c檔案呼叫,.h檔案中實現。

2. 用extern宣告外部函式

a. 定義函式時,在函式返回值型別前面加上extern關鍵字,表示此函式時外部函式,可供其他檔案呼叫,如extern int func (int x,int y),c語言規定,此時extern可以省略,**為外部函式。

b.  呼叫此函式時,需要用extern對函式作出宣告。

作用域:使用extern宣告能夠在乙個檔案中呼叫其他檔案的函式,即把被呼叫函式的作用域擴充套件到本檔案。c語言中規定,宣告時可以省略extern。

例子:檔案a.c的內容:

#include

#include "b.h"

int main()

檔案b.h的內容:

#ifndef __f_h

#define __f_h

extern int add(int x,int y);

extern int sub(int x,int y);

extern int mult(int x,int y);

extern int div(int x,int y);

#endif

檔案b.c的內容:

#include

int add(int x,int y)

int sub(int x,int y)

int mult(int x,int y)

int div(int x,int y)

printf("mult() fail!the second para can not be zero!\n ");

return(-1); }

利用gcc工具編譯gcc a.c b.c –o demo,再執行./demo,結果為

x = 10,y = 5

x + y = 15

x - y = 5

x * y = 50

x / y = 2。

小結:由上面簡單的例子可以看出,在b.h檔案中宣告好b.c的函式,使用時,只需要在a.c中包含#include 「b.h」標頭檔案即可,這樣就可以使用b.c的介面函式了,在實際工程中,通常也是採用這種方式,.c檔案中實現函式,.h檔案中宣告函式藉口,需要呼叫.c檔案的函式介面時,只需包含.h標頭檔案即可。

3. 

總結

在實際工程中,有兩種情況比較多。一是利用extern只宣告外部函式,不需要傳遞需要外部宣告的變數,乙個模組化介面檔案對應乙個宣告介面的標頭檔案,需要呼叫介面函式時,只需要包含其標頭檔案。二是利用用extern宣告外部函式,同時宣告需要傳遞的外部變數,做法和第一種情況一樣,宣告都放在標頭檔案中,但是,模組檔案也需要包含該標頭檔案。另外,如果結構體等比較複雜的變數,則需要包含其定義的標頭檔案。另外,定義的外部變數屬於全域性變數,其儲存方式為靜態儲存,生存週期為整個程式的生存週期。

關鍵詞密度

百科名片 目錄 隱藏 什麼是增加keywords密度的最好方式 關鍵字堆砌 keyword stuffing 的定義 關鍵字堆砌 keyword stuffing 關鍵字堆砌 keyword stuffing 是指在乙個網頁中非常密集地放置關鍵字。一般說來,如果關鍵字的出現過於頻繁,就會蓋過網頁的其...

關鍵詞提取

隱含主題模型優缺點 隱含主題模型可以很好地表示文件和標籤主題,有效降低標籤系統中噪音的影響。但是另外乙個方面,隱含主題相對於詞而言粒度較粗,對於具體實體 如人名 地名 機構名和產品名 的標籤沒有辦法做到很好地區分,因此對這些細粒度標籤推薦效果較差 典型的聚類演算法 層次聚類 hierarchical...

常用關鍵詞

保留字是指在程式語言中,暫時還沒有賦予含義,不過也不能用於定義變數名和類名,因為後續再公升級過程中可能會用到的單詞。final 繼承的出現提高了 的復用性,並方便開發。但隨之也有問題,有些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。final修類類不可以被繼承,但...