C C 中的static和extern關鍵字

2021-09-16 13:54:51 字數 4112 閱讀 9571

1.首先,關於宣告和定義的區別

這種寫法(函式原型後加;號表示結束的寫法)只能叫函式宣告而不能叫函式定義,只有帶函式體的宣告才叫定義,比如下面

只有分配儲存空間的變數宣告才叫變數定義,其實函式也是一樣,編譯器只有見到函式定義才會生成指令,而指令在程式執行時當然也要佔儲存空間。那麼沒有函式體的函式宣告有什麼用呢?它為編譯器提供了有用的資訊,編譯器在翻譯**的過程中,只有見到函式原型(不管帶不帶函式體)之後才知道這個函式的名字、引數型別和返回值,這樣碰到函式呼叫時才知道怎麼生成相應的指令,所以函式原型必須出現在函式呼叫之前,這也是遵循「先宣告後使用」的原則。

識別符號的鏈結屬性(linkage)有三種

外部鏈結(externallinkage)

如果最終的可執行檔案由多個程式檔案鏈結而成,乙個識別符號在任意程式檔案中即使宣告多次也都代表同乙個變數或函式,則這個識別符號具有external linkage。具有external linkage的識別符號編譯後在符號表中是global的符號。

內部鏈結(internallinkage)

如果乙個識別符號在某個程式檔案中即使宣告多次也都代表同乙個變數或函式,則這個識別符號具有internal linkage。具有internal linkage的識別符號編譯後在符號表中是local的符號。

無鏈結(nolinkage)

除以上情況之外的識別符號都屬於no linkage的,例如函式的區域性變數,以及不表示變數和函式的其它識別符號。

宣告和定義的次數限制

凡是被多次宣告的變數或函式,必須有且只有乙個宣告是定義,如果有多個定義,或者乙個定義都沒有,鏈結器就無法完成鏈結。顯然,宣告可以有很多次。

2.用extern和static修飾函式

測試案例2.1

測試案例2.1結果:

編譯不能通過,error c2129: 靜態函式「void print_03(void)」已宣告但未定義因為print_03在extern_static_test1.h中被宣告為static。

當static修飾函式的時候,說明此函式只能被自己內部的檔案使用,即具有internal linkage.因此main不能呼叫extern_static_test1.h中被static修飾的函式。

如有有這樣幾個檔案a.h, a.cpp, main.cpp。其中a.h被a.cpp和main.cpp所包含,那麼a.h中用static修飾的函式只能被a.cpp中的函式呼叫,不能被main.cpp中的函式呼叫.這個internal linkage屬性就被確定了。即使你故意在main.cpp中進行一次external的宣告(如extern void print_03(void);)也不能改變此internal linkage鏈結屬性。

測試案例2.2

為了修正測試案例2.1的錯誤,在main.cpp中刪除print_03();其它檔案保持不變

則編譯沒有錯誤了,執行結果是:

測試案例2.2結果:

print_02()說明,函式被宣告為external後,才能做到在多個檔案中多次宣告的情況下,依然指示同乙個定義。

print_01()說明,函式宣告如果不加external,也不加static,則預設為external.

print_04()說明,如果函式宣告使用了static修飾符,則這個函式具有internallinkage,只能被宣告所在的檔案內部呼叫。所以這裡的print_04()呼叫了宣告為static的print_03()。print_04()不具有static屬性,所以在main.cpp中能夠被呼叫。

測試案例2.3

在main.cpp中強制用extern修飾符宣告print_03();其它檔案保持不變會發生什麼?

測試案例2.3結果:

依然出現編譯錯誤。說明,在a.h中已經被宣告為static的檔案,被main.cpp包含之後,main.cpp中不能修改它的屬性為external。

3.用extern和static修飾變數

測試案例3.1

由於是變數定義,所以不寫在extern_static_test1.h中,extern_static_test1.h和上文保持基本一致,為了簡化,只保留了乙個函式。

變數定義寫在了extern_static_test1.cpp中,如下:

現在來看看main.cpp檔案:

測試案例3.1結果:

編譯發現,var1和var3都出現了編譯錯誤。這說明,雖然已經在這裡喪心病狂地對3個變數的生命都寫明了extern.extern int var1;extern int var2;extern int var3但是,因為在extern_static_test1.cpp的檔案中,var3已經被定義為了static,所以它具有internallinkage了,只能在extern_static_test1.cpp中被使用了,不能在main.cpp中被使用了;因為在extern_static_test1.cpp的檔案中,var1沒有修飾符,變數如果沒有鏈結屬性的修飾符,預設是static。

這和函式正好相反,函式如果沒有鏈結屬性的修飾符,預設是external。想想,這樣設定是符合實際需求的,函式就是用來進行操作,被呼叫的,預設external更方便,變數不應該被隨意使用,而應該被函式操作,這樣才安全。main.cpp修改之後,正確:

測試案例3.2

如果把main.cpp中external宣告的關鍵字external去掉,extern_static_test1.h和extern_static_test1.cpp保持不變,這樣是否正確呢?

測試案例3.2結果

出現編譯錯誤,說明,如果要使得乙個變數具有external linkage,必須在定義時和宣告時都得加上external修飾符,比如這裡需要在extern_static_test1.cpp中var2的定義和main.cpp中的var2的宣告中都寫上external修飾符。因為變數預設是static,你要不特別說明它是external,那就預設是static了。

二者的一些定性說明:

static:

一、在c中,static主要定義全域性靜態變數、定義區域性靜態變數、定義靜態函式。

1、定義全域性靜態變數:在全域性變數前面加上關鍵字static,該全域性變數變成了全域性靜態變數。全域性靜態變數有以下特點。

2、定義區域性靜態變數:

在區域性變數前面加上關鍵字static,其特點如下:

3、定義靜態函式:在函式返回型別前加上static關鍵字,函式即被定義為靜態函式,其特點如下:

二、在c++中新增了兩種作用:

定義靜態資料成員或靜態函式成員。

定義靜態資料成員:

C C 中Static和Const的作用

尊重 一 const的作用 const是c語言的一種關鍵字,它所限定的變數是不允許被改變的,從而起到保護的作用!const關鍵字可以用於修飾變數,引數,返回值,甚至函式體。const可以提高程式的健壯性,減少程式出錯。一 const用於定義常量和修飾變數 當定義某個變數時,用const修飾,則該變數...

c c 中static和extern使用

在c c 中static和extern都能夠用來修飾函式和變數,可是是有差別的。內部函式和內部變數 僅僅能在檔案內使用的函式和變數。外部函式和外部變數 可以被其他檔案使用的函式和變數。static 1 對函式 定義乙個內部函式 static void test 宣告乙個內部函式 static voi...

C C 中static的用法

c c 的static有兩種用法 面向過程程式設計中的static和物件導向程式設計中的static。前者應用於普通變數和函式,不涉及類 後者主要說明static在類中的作用。一 面向過程設計中的static 1 靜態全域性變數 在全域性變數前,加上關鍵字static,該變數就被定義成為乙個靜態全域...