struct Book
{
//成員
//結構體的成員可以是不同型別的變數
char name[20];
char author[20];
short price;
}b1;//全域性變數
這是一個錯誤的寫法
struct Node
{
int data;
struct Node n;
};
應該這樣去寫(連結串列)
struct Node
{
int data;//資料域
struct Nade* next;//指標域
};
舉一個例子,內涵結構體的巢狀
struct S
{
int a;
int b;
double c;
};
struct A
{
char q;
struct S s;//巢狀
short ss;
};
int main()
{
struct A a = { "d",{11,22,33.3},4 };//初始化
printf("%1f\n", a.s.c);
return 0;
}
結構體在計算大小時,會發生對齊
結構體對齊的規則:
1、第一個成員在與結構體變數偏移量為0的地址處。
其他成員變數要對齊到某個數位(對齊數)的整數倍的地址處。
2、對齊數 = 編譯器預設的一個對齊數與該成員大小的較小值。VS中預設的值為8,Linux中的預設值為4
3、結構體總大小為最大對齊數(每個成員變數都有一個對齊數)的整數倍。
4、如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
#include<stdio.h>
struct S1
{
char c1;//對齊數:1
int i;//對齊數:4
char c2;//對齊數:1
};
int main()
{
struct S1 s1;
printf("%d\n", sizeof(s1));//輸出值要是4的倍數,所以為12
return 0;
}
struct S1
{
char c1;//1
char c2;//1
int i;//4
};
將佔用記憶體小的成員放在一起,可以有效的避免記憶體的浪費
為什麼記憶體要對齊?
1、平臺原因(移植原因): 不是所有的硬體平臺都能存取任意地址上的任意資料的;某些硬體平臺只能在某些地址
處取某些特定型別的資料,否則丟擲硬體異常。
2、效能原因: 資料結構(尤其是棧)應該儘可能地在自然邊界上對齊。原因在於,為了方位未對齊的記憶體需要兩次記憶體存取,而對齊的只需要一次
就是那空間換取時間
結構體在對齊方式不合適的時候我們可以自自己修改預設對齊數
#pragma pack(1)//設定預設對齊數
struct S1
{
char c1;//1
int i;//4
char c2;//1
};
#pragma pack()//恢復預設對齊數
//輸出結果為6
列舉型別的定義
enum Sex//型別
{
//列舉型別可能取的值
MALE,//0
FEMALE,//1
SECRET//2
};
enum RGB
{
RED,//0
GREEN=5,//5
BLUE//6
};
初始值預設為0,一次遞加1,也可以賦值
1、增加程式碼的可讀性和可維護性
2、和#define定義的識別符號比較列舉有型別檢查,更加嚴謹。
3、防止了命名汙染(封裝)
4、便於偵錯
5、使用方便,一次可以定義多個常數
enum RGB
{
RED=1,
GREEN=3,
BLUE=5
};
enum RGB clr = GREEN;//只能拿列舉常數給列舉變數賦值,才不會出現型別的差異
clr=5
i和c會佔用同一塊i空間
union Un
{i
char c;//1
int i;//4
};
union Un u;
printf("%d\n", sizeof(u));//值為4
1、聯合的大小至少是最大成員的大小。
2、當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍
union U
{
char arr[6];//6 對齊數為1
int i;//4 對齊數為4
};
int main()
{
union U u;
printf("%d\n", sizeof(u));//輸出為8
return 0;
}