區分c++中的宣告與定義
C++編碼過程中,我們經常談及“定義”和“宣告”,二者是程式設計過程中的基本概念。我們需要使用一個變數、型別(類、結構體、列舉、共用體)或者函式時,我們需要提前定義和宣告。定義和宣告的過程,就像我們向圖書館借閱書籍一般,需要先完成書籍的印刷,即創造出書籍,這是一個定義的過程,有了書籍,我們需要到圖書館完成借閱的登記手續,這是申明的過程。完成了申明,我們有了使用書籍的許可權,就可以盡情的暢遊在知識的海洋。如果說書籍是自己委託印刷廠印刷的,那麼你無需向他人借閱,即無需宣告,可以直接使用書籍。一本書籍只需要印刷一次,但是可以被多人多次借閱,也就是說定義只需要一次,但是宣告可以有多次。這裡的書籍指代的是“定義”和“宣告”作用的物件,即變數、型別和函式。C/C++中,使用一個變數、型別或者函式必須先在使用前完成定義和宣告。
定義和宣告是容易混淆的概念,但通過上面的類比說明,可以看出:
(1)“定義”和“宣告”的本質區別是宣告可以出現多次,而定義只能出現一次;
(2)把宣告的東西放在標頭檔案,把定義的東西放在原始檔(.c或者.cpp檔案);
(3)型別的定義應該放在標頭檔案,因為型別不具有外部連線性,不同原始檔擁有相同的型別定義不會報編譯錯誤,但標頭檔案不能重複包含。
1.變數的定義與宣告
定義變數,指明變數所屬型別、名稱、分配記憶體空間與初始化其初始值,如
int a=1; int a(1);
如果不顯示初始化,則按照編譯器預設進行初始化。
宣告變數,指明變數所屬型別與變數名稱,如:
extern int a;
有一點需要注意,對於區域性變數以及全域性靜態變數是不能通過extern進行前置申明的,即不能在定義之前通過宣告來引用,因為區域性變數的作用域是當前程式碼塊,全域性靜態變數的作用域是當前原始檔,都不是全域性作用域,所以不能通過extern進行前置宣告。全域性變數允許在定義之前通過前置宣告進行引用。參見如下程式碼片段。
#include <stdio.h> extern int a; extern static int b; //報錯 int main() { extern int c; //報錯 printf("a=%d,b=%d,c=%d",a,b,c); int c=2; } int a=0; static int b=1;
2.型別的定義與宣告
定義型別,指明型別的名稱和內容。
struct test{int a;}
或者給已經存在的型別起個別名。
typedef int int32;
注意,型別的作用域是原始檔,即型別不具有外部連線性質,因此可以在不同原始檔定義相同名稱的型別,比如定義同名的類是不會報重定義錯誤的,這也說明了型別的定義應該放在標頭檔案中,但在同一個原始檔定義相同名稱的型別則編譯器會報重定義錯誤。
宣告型別,只給出型別的名稱。
class A;
型別被宣告之後,可以用於宣告其他的識別符號,但不能利用它來定義物件,也不能使用型別的成員。
class A; //先宣告類 void show(A& a); //申明函式 class A //後定義 { public: int a; char b; };
以上程式碼沒有錯誤。但如下程式碼將報錯:
class A; //先宣告 int main(int argc,char* argv[]) { A classA; classA.a=5; return 0; } class A //後定義 { public: int a; char b; };
該程式無法通過編譯,原因是類A的所有成員的有效範圍均是從定義類的地方開始,故使用未知的建構函式初始化其成員變數是錯誤的,會報使用未定義的 class “A”錯誤。
使用型別之前給出其定義式即可,即給出型別的名稱和內容,或者利用typedef給一個型別起個別稱。雖然說是定義型別,但還是將型別的定義放在標頭檔案,即使被不同的原始檔包含,因為型別不具有外部連線特性,所以不會報重定義錯誤的,這和變數和函式不同,不能將變數和函式的定義放在標頭檔案!切記!這裡所說的外部連線與內部連線的區別在於連結器接的時候是否將當前目標檔案中的定義與其它目標檔案對比,並報告是否有重定義錯誤。內連線不會進行對比,故不同原始檔中定義相同名稱的型別是不會報錯的。
3.函式的定義與宣告
定義函式,指明函式返回型別、函式名稱、函式引數和函式體。
int test(char a,int b) { return a+b }
宣告函式,指明函式返回型別,函式名稱和函式引數。
int test(char a,int b); //或者無需給出形參名稱,只需要型別即可 int test(char,int);
從上面可以看出,函式定義與函式宣告的區別是主要有兩點:
(1)函式定義需要給出函式體,即函式的具體實現,函式宣告不需要;
(2)函式定義必須給出形參名稱,宣告可以只給出形參型別。
以上就是區分c++中的宣告與定義的詳細內容,更多關於c++ 宣告與定義的資料請關注我們其它相關文章!