extern 與 static 用法總結

2021-06-20 12:26:25 字數 4463 閱讀 9970

資料1

1、  概念基礎:

區域性變數:函式內部定義的變數(包括定義在函式內部復合語句中的變數)。

全域性變數:定義在函式外部的變數。

作用域:任何識別符號(包括變數、函式名、符號常量及新的資料名)都有它的作用範圍,此範圍稱為該識別符號的作用域。比如符號常量的作用域是從定義符號 常量的地方開始到包含這個#define命令(作用於該符號常量)的檔案末尾或者遇到#undef命令(作用於該符號常量)為止。

2、  對於變數:

static關鍵字:static可以用於修飾區域性變數以擴充套件區域性變數的生存期 ,被static關鍵字修飾的區域性變數的生存期為:在呼叫該變數所在的函式前已生成,直到程式退出才消亡,因此在呼叫該區域性變數所在的函式後該變數仍然存在並保持最後使用的值。雖然static關鍵字可以改變區域性變數的生存期,但是不能改變區域性變數的作用域,該區域性變數仍然只能在定義它的函式中使用。

static關鍵字也可可用於修飾全域性變數,此時它的作用在於限制該全域性變數的作用域,只能在定義該全域性變數的檔案中才能使用。

extern關鍵字:只能用於擴充套件沒有被static關鍵字修飾的全域性變數 。 預設情況下全域性變數只能在定義它的檔案中使用(從定義該全域性變數開始到所在檔案的檔案尾),但如果在另乙個檔案中將這個變數宣告為外部變數,那麼這個變數 的作用域將被擴充套件到另外乙個檔案中。也可以在定義全域性變數之前宣告該變數,從而在檔案中可以在定義該全域性變數前使用該全域性變數。

3、  對於函式:

static關鍵字:在定義函式時在函式首部的最左邊加上static可以把該函式宣告為內部函式(又叫靜態函式),這樣該函式就只能在其定義所在的檔案中使用,如果在不同的檔案中有同名的內部函式,則互不干擾。

extern關鍵字:在定義函式時如果在函式首部的最左端冠以關鍵字extern,則表示此函式是外部函式,可供其他檔案呼叫。c語言規定,如果在定義函式時省略extern,則隱含為外部函式。

在檔案中要呼叫其他檔案中的外部函式,則需要在檔案中用extern宣告該外部函式,然後就可以使用。

資料2

1、用static、extern可以宣告變數1.1 可用static宣告全域性變數和區域性變數(包括陣列)。

(1)用static宣告的區域性變數只能被定義該變數的函式識別,在退出函式時該區域性變數仍然保持其值,

e.g. void temp()

static int array; //靜態區域性變數

用static宣告區域性陣列可以避免在每次呼叫函式時都建立和初始化陣列,以及在每次退出函式時撤銷陣列,縮短程式執行時間。

(2)用static宣告靜態外部變數,可以限定外部變數只被本檔案引用 ,不會被其他檔案引用.為檔案的模組化、通用性提供方便.

e.g. file1.c(file1檔案)

static int a; //靜態外部變數

main()

注意:外部變數和靜態外部變數都是靜態儲存的,只是作用範圍不同.

1.2 儲存類別說明符extern

extern外部變數的作用域是從變數定義處開始,到本程式檔案的末尾.

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

用extern宣告外部變數以擴充套件它在程式檔案中的作用域

e.g. main()

extern int a,b; //外部變數宣告

int a=14,b=-3; //定義外部變數

(2)在多檔案的程式中宣告外部變數

如乙個程式包含多個檔案,在乙個檔案中定義外部變數,在其他檔案中extern做外部變數宣告.

e.g. 檔案file1.c中定義

int a;

檔案file2.c中

extern int a; //作用域擴大,不再分配記憶體

2、用static、extern可以宣告函式

(1)內部函式(靜態函式)-用static宣告

用static宣告的內部函式,只能被本檔案中的其他函式呼叫,呼叫範圍只侷限與所在檔案,不同檔案中有同名的內部函式,互不干擾.

e.g. static int fun(int a,int b)

(2)外部函式-用extern宣告

★用extern宣告的外部函式可供其他檔案呼叫.一般沒有任何宣告的函式都是外部函式.

e.g. extern int fun(int a,int b)

★在需要呼叫此函式的檔案中.用extern宣告所用的函式是外部函式.

e.g. file1.c(file1檔案)

main()

extern printf_string(char str); //宣告在本函式中要呼叫其他檔案中的函式

file2.c(file2檔案)

void printf_string(char str)

注意:extern可以省略,如使用#include,可在檔案中直接呼叫其中的函式.

3、識別符號有四種作用域:函式作用域、檔案作用域、塊作用域、函式原型作用域。

(1)標號(跟有冒號的識別符號,如start:)是唯一具有函式作用域的識別符號。編號可用於函式中任何地方,但不能在函式之外引用。用在swtich結構(case:)和goto語句中。

(2)函式之外的全域性變數、函式宣告和函式原型具有檔案作用域,

e.g. extern x=10;

void temp(void);

(3)static宣告的區域性變數具有塊作用域,

e.g. void temp(void)

static int x=10;

(4)用在函式原型引數列表中的識別符號具有函式原型作用域,

e.g. void temp(const ,int);

1、陣列傳遞給函式,模擬傳引用呼叫的方式自動把陣列傳遞給函式,意味著被呼叫的函式能夠修改原是陣列的元素值,

e.g. int hourly[24]; //陣列定義

void modify(int ,int ); //函式原型

modify(hourly,24); //函式呼叫,陣列名即陣列第乙個元素的位址

注意:為了防止函式中修改陣列的值,採用型別限定符const做字首,陣列元素成為函式體中的常量,函式體中任何修改陣列元素的企圖都會導致編譯錯誤,

e.g. void modify(const int ,int );

2、字元陣列

字串顯示:printf("%s",string1);

e.g. char string1="good girl"; //字串

char string1=; //上下宣告等價

注意:'空字元'='/0',終止符,用printf("%s",string1)輸出,得到good girl。

3、多維陣列

e.g. int a[3][4]=,,};

假設陣列起始位址2000,則

表示形式 含義 位址

a 指向a[0],即0行首位址。 2000

a[0],*(a+0),*a 第0行第0列元素位址 2000

a+1,&a[1] 第1行首位址 2008

a[1],*(a+1) 第1行第0列元素位址 2008

a[1]+2,*(a+1)+2,&a[1][2] 第1行第2列元素位址 2012

*(a[1]+2),*(*(a+1)+2),a[1][2] 第1行第2列元素的值 7

在二維陣列中,a+i=a[i]=*(a+i)=&a[i]=&a[i][0],即他們的的位址值是想等的。

資料3de>檔案a. c

static

int i; //只在a檔案中用

int j;   //在工程裡用

static

void init(

)         //只在a檔案中用

void callme(

)          //在工程中用

de>

上 面的全域性i變數和init()函式只能用在a.c檔案中,全域性變數sum的作用域只在callme裡。變數j和函式callme()的全侷限擴充到整個工 程檔案。所以可以在下面的b.c中用extern關鍵字呼叫。extern告訴編譯器這個變數或者函式在其他檔案裡已經被定義了。

de>檔案b. c

extern

int j;    //呼叫a檔案裡的

extern

void callme(

); //呼叫a檔案裡的

int main(

)de>

extern的另外用法是當c和c++混合程式設計時如果c++呼叫的是c原始檔定義的函式或者變數,那麼要加extern來告訴編譯器用c方式命名函式:

de>檔案a. cpp呼叫a. c裡面的變數i和函式callme(

)extern

"c" //在c++檔案裡呼叫c檔案中的 變數

int main(){

callme();

de>

static與extern的用法

static是c 中常用的修飾符,它被用來控制變數的存貯方式和可見性。extern,c 是使c 能夠呼叫c寫作的庫檔案的乙個手段,如果要對編譯器提示使用c的方式來處理函式的話,那麼就要使用extern c 來說明。一.c語言中的static關鍵字 在c語言中,static可以用來修飾區域性變數,全域...

c語言static與extern的用法

一,static和extern 大工程下我們會碰到很多原始檔。檔案a.c static int i 只在a檔案中用 int j 在工程裡用 static void init 只在a檔案中用 void callme 在工程中用 上面的全域性i變數和init 函式只能用在a.c檔案中,全域性變數sum的...

c語言static與extern的用法

一,static和extern 大工程下我們會碰到很多原始檔。檔案a.c static int i 只在a檔案中用 int j 在工程裡用 static void init 只在a檔案中用 void callme 在工程中用 上面的全域性i變數和init 函式只能用在a.c檔案中,全域性變數sum的...