不完全型別和複雜宣告
c語言的型別分為函式型別、物件型別和不完全型別三大類。物件型別又分為標量型別和非標量型別。指標型別屬於標量型別,因此也可以做邏輯與、或、非運算的運算元和if、for、while的控制表示式,null指標表示假,非null指標表示真。不完全型別是暫時沒有完全定義好的型別,編譯器不知道這種型別該佔幾個位元組的儲存空間,例如:
具有不完全型別的變數可以通過多次宣告組合成乙個完全型別,比如陣列str宣告兩次:
當編譯器碰到第乙個宣告時,認為str是乙個不完全型別,碰到第二個宣告時str就組合成完全型別了,如果編譯器處理到程式檔案的末尾仍然無法把str組合成乙個完全型別,就會報錯。讀者可能會想,這個語法有什麼用呢?為何不在第一次宣告時就把str宣告成完全型別?有些情況下這麼做有一定的理由,比如第乙個宣告是寫在標頭檔案裡的,第二個宣告寫在.c檔案裡,這樣如果要改陣列長度,只改.c檔案就行了,標頭檔案可以不用改。
不完全的結構體型別有重要作用:
truct s和struct t各有乙個指標成員指向另一種型別。編譯器從前到後依次處理,當看到struct s ;時,認為struct t是乙個不完全型別,pt是乙個指向不完全型別的指標,儘管如此,這個指標卻是完全型別,因為不管什麼指標都佔4個位元組儲存空間,這一點很明確。然後編譯器又看到struct t ;,這時struct t有了完整的定義,就組合成乙個完全型別了,pt的型別就組合成乙個指向完全型別的指標。由於struct s在前面有完整的定義,所以struct s *ps;也定義了乙個指向完全型別的指標。
這樣的型別定義是錯誤的:
編譯器看到struct s ;時,認為struct t是乙個不完全型別,無法定義成員ot,因為不知道它該佔幾個位元組。所以結構體中可以遞迴地定義指標成員,但不能遞迴地定義變數成員,你可以設想一下,假如允許遞迴地定義變數成員,struct s中有乙個struct t,struct t中又有乙個struct s,struct s又中有乙個struct t,這就成了乙個無窮遞迴的定義。
以上是兩個結構體構成的遞迴定義,乙個結構體也可以遞迴定義:
當編譯器處理到第一行struct s ;時,struct s成了乙個完全型別,next也成了乙個指向完全型別的指標。類似這樣的結構體是很多種資料結構的基本組成單元,如鍊表、二叉樹等,我們將在後面詳細介紹。下圖示意了由幾個struct s結構體組成的鍊錶,這些結構體稱為鍊錶的節點(node)。
head指標是鍊錶的頭指標,指向第乙個節點,每個節點的next指標域指向下乙個節點,最後乙個節點的next指標域為null,在圖中用0表示。
可以想像得到,如果把指標和陣列、函式、結構體層層組合起來可以構成非常複雜的型別,下面看幾個複雜的宣告。
這個宣告來自signal(2)。sighandler_t是乙個函式指標,它所指向的函式帶乙個引數,返回值為void,signal是乙個函式,它帶兩個引數,乙個int引數,乙個sighandler_t引數,返回值也是sighandler_t引數。如果把這兩行合成一行寫,就是:
在分析複雜宣告時,要借助typedef把複雜宣告分解成幾種基本形式:
t *p;,p是指向t型別的指標。
t a;,a是由t型別的元素組成的陣列,但有乙個例外,如果a是函式的形參,則相當於t *a
t1 f(t2, t3...);,f是乙個函式,引數型別是t2、t3等等,返回值型別是t1。
我們分解一下這個複雜宣告:
1、fp和*號括在一起,說明fp是乙個指標,指向t1型別:
2、t1應該是乙個函式型別,引數是void *,返回值是t2型別:
3、t2和*號括在一起,應該也是個指標,指向t3型別:
顯然,t3是乙個int陣列,由10個元素組成。分解完畢。
C 刪除不完全型別陣列
看智慧型指標的時候遇到一組函式蠻有意思的,即checked delete t x 和checked array delete t x 這兩個函式的作用是安全刪除引數所指向的變數或陣列。templateinline void checked delete t x templateinline void...
C 中的「不完全型別」
用delete刪除乙個只有宣告但無定義的型別的指標,是危險的。這通常導致無法呼叫析構函式 包括物件本身的析構函式 成員 基類的析構函式 從而洩露資源。示例 引用 class c 在另乙個cpp檔案中定義 c createc 在另乙個cpp檔案中定義 int main 初步分析 型別c沒有被定義,所以...
資料格式描述語言的不完全列表
我是從事測控工作的,在工作中經常需要檢視各種記錄資料。裝置上用的軟體來自不同廠家,軟體記錄的資料格式也各不相同。有的軟體又沒有提供資料瀏覽工具,或是工具不太好用。我們自己編了資料檢視工具,但是對不同的資料檔案都要編寫不同的 很是頭痛。為了找到一種可以較好的描述資料格式檔案的技術,我在網上搜尋了一下,...