1.結構體的概念與初始化
當我們在儲存資料的時候,往往會發現,資料不是單一的、用乙個陣列就能加以儲存的。有的時候,我們需要將各種資料打包起來形成乙個整體。如一包零食的資訊:生產日期、加工手藝、新增劑、保質期等。再如一名學生的資訊:性別、年齡、成績、家庭住址等。
在這個時候,我們就需要重新尋找乙個型別來使得我們的資料更好、更方便的儲存。結構體struct這個關鍵字,就是將相互關聯的資料打包成乙個整體,方便使用。
struct
a;struct point
b,*p;
關鍵字struct引入結構宣告,由包含花括號在內的一系列宣告組成。struct後面的名字是靈活的,被稱作結構標記(這裡是point)。
(1)這裡的
struct
a;
和
int a;
是相同的。均把a宣告為指定型別的變數,開闢了一塊空間。
這裡的p是乙個指標,它指向這個型別的結構。
但這兩個宣告被編譯器認為是兩種不 同的結構體,儘管它們成員列表完全相同。所以,變數 a和變數 b的型別與p的型別是不同的。
(2)或者也可以使用下面的方法:
struct point x;
struct point y,*ps;
這些宣告使用了標籤struct point來建立變數。現在,x,y,ps都是同一型別的結構變數了。
當結構體要進行初始化時,可在定義的後面使用初值表進行。初值表中同每個成員對應的初值必須是常量表示式,例如:
struct point ps =;
2.結構成員的訪問
(1)結構成員的直接訪問
結構成員的訪問是通過操作符(.)訪問的。點操作符的左邊是結構變數的名稱,右邊是需要訪問的成員的名字。如下面的宣告:
結構名.成員
如:ps.x;
ps.y = 3;
ps.z = 10;
(2)結構成員的間接訪問
當結構體中,存在乙個指向其他結構體的指標時,該如何訪問這個結構的成員呢?如:乙個函式的引數是指向結構的指標,
void func(struct point *ps)
我們可以先對指標執行間接訪問操作,然後使用點操作符來訪問它的成員。
(*ps).f;
但這樣就有點麻煩了,所以我們可以採用另一種更加簡便的方法———— ->操作符(箭頭操作符)。如
ps->f;
3.結構體的記憶體對齊
結構在記憶體中是如何儲存的呢?在編譯器的安排下面,按照成員列表乙個接乙個的給每個成員分配記憶體。當儲存成員需要滿足邊界對齊的要求時,會出現額外的填充記憶體空間。
下面我們舉個例子說明一下這個情況:
struct point
;
成員 c1必須儲存在能夠被4整除的位置。c1 的下乙個成員是int 型別,所以它必須跳過3個位元組到達合適的邊界。在int 型別之後是乙個char 型別。直接儲存即可。但最後的struct 結構體的大小卻為12.這是因為在滿足結構體成員型別的同時,還需要滿足:
- 第乙個成員在與結構體變數偏移量為0的位址處。
- 其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。
- 結構體的總大小為最大對齊數(每個成員對應乙個對齊數)的整數倍。
- 如果是巢狀了其他結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的總大小是所有對齊數(含巢狀結構體的最大對齊數)的整數倍。
接下來,在結構體的傳參過程中,我們是按照傳值呼叫還是按照傳址呼叫呢?
從函式呼叫來看,如果是傳遞結構體物件時,結構體過大,引數壓棧時會呼叫過多的系統來處理,影響系統效能。
所以,結構體傳參時,優先考慮結構體的位址。
#### 4.位段
在結構中,我們不得不提到乙個概念,那就是位段。位段的宣告和結構類似,但位段的成員是乙個或多個位的字段。
首先,位段的成員必須宣告為 int ,signed int 或者unsigned int型別。其次,在成員的後面是乙個冒號和乙個整數,這個整數表示該位段所占用的位的數目。
struct a
;
該位段的大小為sizoef(struct a)=8;
這是因為位段上空間的大小是按照需要以4位元組或者1位元組的方式來開闢的。
#### 聯合(共用體)
聯合和結構體的宣告類似,但其儲存方式卻不相同。聯合的所有成員使用的是記憶體中的相同位置。當我們想把不同的東西存在同乙個位置時,就可以使用聯合。
還記得求計算機大小端時,我們是怎麼思考的嗎?我們是使用指標來檢視:
int i = 1;
char *a = null;
a = (char *)&i;
if (*a)
printf("小端!\n");
else
printf("大端!\n");
在這裡,我們又多了一種新的方法來判斷大小端,就是利用聯合:
union a
;int main()
;
花括號中的內容是列舉的可能取值,叫做列舉常量。這些列舉常量都是有值的,預設從零開始依次遞增1。
也可以在定義的時候進行賦值:
enum
color
;
自定義型別
typedef型別 typedef 已有型別 新建型別 示例 typedef double area,volume typedef int number number i1 area a enum enum 列舉型別名 enum week 預設sun 0,可以比較 如果修改必須形如enum week...
自定義型別
下面列舉幾種c語言中常用的自定義資料型別 1.結構體型別 當描述乙個整型變數時,可以用int,描述字元型變數時,可以用char,但要描述乙個學生時,因為這個學生包含的資訊很多,比如姓名,性別,年齡等,不能通過單一的型別來描述,所以,這裡引入結構體型別,將某個事物的共有屬性集合在一起,宣告乙個結構體型...
自定義型別
列舉從字面意思理解就是將可能取的值一一枚舉出來,列舉型別沒有成員 可言,裡邊存放的是可能取值。列舉型別的定義 enum day enum color printf d n red printf d n green printf d n blue 執行結果 day和color都是定義的列舉型別,中的內...