天天看點

iOS開發系列--C語言之構造類型概述結構體枚舉共用體

在第一節中我們就提到c語言的構造類型,分為:數組、結構體、枚舉、共用體,當然前面數組的内容已經說了很多了,這一節将會重點說一下其他三種類型。

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#struct">結構體</a>

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#enum">枚舉</a>

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#union">共用體</a>

數組中存儲的是一系列相同的資料類型,那麼如果想讓一個變量存儲不同的資料類型就要使用結構體,結構體定義類似于c++、c#、java等進階語言中類的定義,但事實上它們又有着很大的差別。結構體是一種類型,并非一個變量,隻是這種類型可以由其他c語言基本類型共同組成。

對于上面的例子需要做出如下說明:

可以在定義結構體類型的同時聲明結構體變量;

如果定義結構體類型的同時聲明結構體變量,此時結構體名稱可以省略;

定義結構體類型并不會配置設定記憶體,在定義結構體變量的時候才進行記憶體配置設定(同基本類型時類似的);

結構體類型的所占用記憶體大型等于所有成員占用記憶體大小之和(如果不考慮記憶體對齊的前提下);

iOS開發系列--C語言之構造類型概述結構體枚舉共用體

表格具體來源請觀看下面的視訊(注意由于錄制軟體的原因前幾秒不清晰但是不影響分析):

接下來看一下結構體數組、指向結構體的指針:

結構體作為函數參數傳遞的是成員的值(值傳遞而不是引用傳遞),對于結構體指針而言可以通過”-&gt;”操作符進行通路。

枚舉類型是比較簡單的一種資料類型,事實上在c語言中枚舉類型是作為整形常量進行處理的,通常稱為“枚舉常量”。

需要注意的是枚舉成員預設值從0開始,如果給其中一個成員指派,其它後面的成員将依次指派,例如上面如果summer手動指定為8,則autumn=9,winter=10,而sprint還是0。

共用體又叫聯合,因為它的關鍵字是union(貌似資料庫操作經常使用這個關鍵字),它的使用不像枚舉和結構體那麼頻繁,但是作為c語言中的一種資料類型我們也有必要弄清它的用法。從前面的分析我們知道結構體的總長度等于所有成員的和(當然此時還可能遇到對齊問題),但是和結構體不同的是共用體所有成員共用一塊記憶體,順序從低位址開始存放,一次隻能使用其中一個成員,union最終大小由共用體中最大的成員決定,對某一成員指派可能會覆寫另一個成員。

這裡需要重點解釋一個問題:為什麼t.a、t.b、t.c輸出結果分别是4、260、65796,當然t.c等于65796并不奇怪,但是t.a前面指派為’a’不應該是97嗎,而t.b不應該是10嗎?其實如果弄清這個問題共用體的概念基本就清楚了。

根據前面提到的,共用體其實每次隻能使用其中一個成員,對于上面的代碼經過三次指派最終使用的其實就是t.c,而通過上面的輸出結果我們也确實看到c是有效的。共用體有一個特點就是它的成員存儲在同一塊記憶體區域,這塊區域的大小需要根據它的成員中長度最大的成員長度而定。由于上面的代碼是在64位編譯器下編譯的,具體長度:char=1,short int=2,int=4,是以得出結論,type的長度為4,又根據上面輸出的位址,可以得到下面的存儲資訊(注意資料的存儲方式:高位址存儲高位,低位址存儲地位):

iOS開發系列--C語言之構造類型概述結構體枚舉共用體

當讀取c的時候,它的二進制是“00000000  00000001  00000001  00000100”,換算成十進制就是65796;而經過三次指派後,此時b的存儲就已經被c成員的低位資料覆寫,b的長度是二,是以從起始位址取兩個位元組得到的二進制資料此時是“00000001  00000100”(b原來的資料已經被c低2位資料覆寫,其實此時就是c的低2位資料),換算成十進制就是260;類似的a此時的資料就是c的低一位資料”00000100”,換算成十進制就是4。