區(qū)分c++中的聲明與定義
C++編碼過程中,我們經(jīng)常談及“定義”和“聲明”,二者是編程過程中的基本概念。我們需要使用一個變量、類型(類、結(jié)構(gòu)體、枚舉、共用體)或者函數(shù)時,我們需要提前定義和聲明。定義和聲明的過程,就像我們向圖書館借閱書籍一般,需要先完成書籍的印刷,即創(chuàng)造出書籍,這是一個定義的過程,有了書籍,我們需要到圖書館完成借閱的登記手續(xù),這是申明的過程。完成了申明,我們有了使用書籍的權(quán)限,就可以盡情的暢游在知識的海洋。如果說書籍是自己委托印刷廠印刷的,那么你無需向他人借閱,即無需聲明,可以直接使用書籍。一本書籍只需要印刷一次,但是可以被多人多次借閱,也就是說定義只需要一次,但是聲明可以有多次。這里的書籍指代的是“定義”和“聲明”作用的對象,即變量、類型和函數(shù)。C/C++中,使用一個變量、類型或者函數(shù)必須先在使用前完成定義和聲明。
定義和聲明是容易混淆的概念,但通過上面的類比說明,可以看出:
(1)“定義”和“聲明”的本質(zhì)區(qū)別是聲明可以出現(xiàn)多次,而定義只能出現(xiàn)一次;
(2)把聲明的東西放在頭文件,把定義的東西放在源文件(.c或者.cpp文件);
(3)類型的定義應(yīng)該放在頭文件,因為類型不具有外部連接性,不同源文件擁有相同的類型定義不會報編譯錯誤,但頭文件不能重復(fù)包含。
1.變量的定義與聲明
定義變量,指明變量所屬類型、名稱、分配內(nèi)存空間與初始化其初始值,如
int a=1; int a(1);
如果不顯示初始化,則按照編譯器默認(rèn)進(jìn)行初始化。
聲明變量,指明變量所屬類型與變量名稱,如:
extern int a;
有一點需要注意,對于局部變量以及全局靜態(tài)變量是不能通過extern進(jìn)行前置申明的,即不能在定義之前通過聲明來引用,因為局部變量的作用域是當(dāng)前代碼塊,全局靜態(tài)變量的作用域是當(dāng)前源文件,都不是全局作用域,所以不能通過extern進(jìn)行前置聲明。全局變量允許在定義之前通過前置聲明進(jìn)行引用。參見如下代碼片段。
#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.類型的定義與聲明
定義類型,指明類型的名稱和內(nèi)容。
struct test{int a;}
或者給已經(jīng)存在的類型起個別名。
typedef int int32;
注意,類型的作用域是源文件,即類型不具有外部連接性質(zhì),因此可以在不同源文件定義相同名稱的類型,比如定義同名的類是不會報重定義錯誤的,這也說明了類型的定義應(yīng)該放在頭文件中,但在同一個源文件定義相同名稱的類型則編譯器會報重定義錯誤。
聲明類型,只給出類型的名稱。
class A;
類型被聲明之后,可以用于聲明其他的標(biāo)識符,但不能利用它來定義對象,也不能使用類型的成員。
class A; //先聲明類 void show(A& a); //申明函數(shù) 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的所有成員的有效范圍均是從定義類的地方開始,故使用未知的構(gòu)造函數(shù)初始化其成員變量是錯誤的,會報使用未定義的 class “A”錯誤。
使用類型之前給出其定義式即可,即給出類型的名稱和內(nèi)容,或者利用typedef給一個類型起個別稱。雖然說是定義類型,但還是將類型的定義放在頭文件,即使被不同的源文件包含,因為類型不具有外部連接特性,所以不會報重定義錯誤的,這和變量和函數(shù)不同,不能將變量和函數(shù)的定義放在頭文件!切記!這里所說的外部連接與內(nèi)部連接的區(qū)別在于鏈接器接的時候是否將當(dāng)前目標(biāo)文件中的定義與其它目標(biāo)文件對比,并報告是否有重定義錯誤。內(nèi)連接不會進(jìn)行對比,故不同源文件中定義相同名稱的類型是不會報錯的。
3.函數(shù)的定義與聲明
定義函數(shù),指明函數(shù)返回類型、函數(shù)名稱、函數(shù)參數(shù)和函數(shù)體。
int test(char a,int b) { return a+b }
聲明函數(shù),指明函數(shù)返回類型,函數(shù)名稱和函數(shù)參數(shù)。
int test(char a,int b); //或者無需給出形參名稱,只需要類型即可 int test(char,int);
從上面可以看出,函數(shù)定義與函數(shù)聲明的區(qū)別是主要有兩點:
(1)函數(shù)定義需要給出函數(shù)體,即函數(shù)的具體實現(xiàn),函數(shù)聲明不需要;
(2)函數(shù)定義必須給出形參名稱,聲明可以只給出形參類型。
以上就是區(qū)分c++中的聲明與定義的詳細(xì)內(nèi)容,更多關(guān)于c++ 聲明與定義的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C字符串操作函數(shù)的實現(xiàn)詳細(xì)解析
以下是對C語言中字符串操作函數(shù)的實現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下2013-08-08C語言中的setlinebuf()、utmpname()、rewind函數(shù)使用
這篇文章主要介紹了C語言中的setlinebuf()、utmpname()、rewind函數(shù)使用,是C語言中操作文件的一些基本函數(shù),需要的朋友可以參考下2015-08-08C++超詳細(xì)講解函數(shù)參數(shù)的默認(rèn)值
在C++中,定義函數(shù)時可以給形參指定一個默認(rèn)的值,這樣調(diào)用函數(shù)時如果沒有給這個形參賦值(沒有對應(yīng)的實參),那么就使用這個默認(rèn)的值。也就是說,調(diào)用函數(shù)時可以省略有默認(rèn)值的參數(shù)2022-05-05