前述
C語言中存在這樣一種類型,名叫不完整類型(Incomplete types),雖然我們可能不太理解,或許也沒有仔細(xì)研究過,但是在實(shí)際的編程中,我們卻已經(jīng)用到過很多次了。
接下來我們就共同學(xué)習(xí)一下,內(nèi)容比較簡單,一看就懂,一學(xué)就會(huì)。
不完整類型
不完整類型(Incomplete types)是缺少足夠信息來確定該類型對象大小的對象類型,不完整類型可以在翻譯單元的某些點(diǎn)完整。
聽起來可能比較繞口,簡單來說就是,不完整類型是不知道對象所占空間大小,此時(shí)是無法使用sizeof()的。但是可以通過后續(xù)再補(bǔ)充完整。
不完整類型主要有下面三種。
已聲明但未定義的類類型
內(nèi)容未知的結(jié)構(gòu)體或聯(lián)合體類型。在同一作用域的后面,定義同一結(jié)構(gòu)體或聯(lián)合體的內(nèi)容的聲明能使之完整。
struct?node?{ ??struct?node?*next;?//?struct?node?在此點(diǎn)不完整 };?//?struct?node?在此點(diǎn)完整
未知邊界數(shù)組
簡單來說就是大小未知的數(shù)組,之后指定大小的聲明能使之完整,接下來看一個(gè)示例。
#includeextern?int?a[];??//此時(shí)a類型為int?[]是不完整類型 void?fun1()?{ ??printf("sizeof?a?=?%d ",?sizeof(a));?//?error ??a[0]?=?88;??//OK } int?a[3]?=?{1,2,3};??//此時(shí)a類型為int?[3]是完整類型 void?fun2()?{ ??printf("sizeof?a?=?%d ",?sizeof(a));??//OK ??a[0]?=?3;??//OK } int?main(int?argc?,char?**argv)?{ ??fun1(); ??fun2(); ??return?0; }
如果在fun1函數(shù)中打印數(shù)組a的長度編譯時(shí)就會(huì)報(bào)如下錯(cuò)誤:
invalid application of 'sizeof' to incomplete type 'int[]'
因?yàn)榇藭r(shí)a為不完整類型,即不知道a的長度,所以無法使用sizeof。
但有的小伙伴卻有疑問了,為什么在fun1函數(shù)中卻可以設(shè)置a[0]的值?
雖然這里使用了數(shù)組a,但是它會(huì)被轉(zhuǎn)換成指向其首元素的指針,而且這個(gè)轉(zhuǎn)換并不需要知道數(shù)組的大小。
而且C語言也不會(huì)檢查數(shù)組是否越界,他選擇相信程序員,把重心放在了程序的執(zhí)行效率上,這也是為什么C語言執(zhí)行效率高運(yùn)行快的原因。
感興趣可以參考:為什么C語言執(zhí)行效率高,運(yùn)行快?
其實(shí)在外部聲明的時(shí)候可以完整聲明,例如上述示例我可以改為:extern int a[3];
此時(shí)在編譯程序fun1就不會(huì)有編譯報(bào)錯(cuò)提示了。
因?yàn)閿?shù)組元素不能具有未知邊界數(shù)組類型,所以多維數(shù)組只能在第一個(gè)維度中有未知邊界:
extern?int?a[][2];?// OK:邊界未知的含有【2 個(gè) int 元素的數(shù)組】元素的數(shù)組 extern?int?b[2][];?// error:數(shù)組有不完整類型
void 類型
可由 CV 限定,有別于其他不完整類型, void 不能補(bǔ)充聲明為完整類型。
總結(jié)
不完整類型有三種:
void類型(不能被完整)
數(shù)組長度未知(可被完整)
已聲明但未定義的類類型(可被完整)
參考鏈接
https://en.cppreference.com/w/c/language/type
https://en.cppreference.com/w/cpp/language/type
編輯:黃飛
?
評(píng)論
查看更多