1、結構體基礎知識
定義:不同或相同型別元素的集合
宣告:直接上例子會更清楚
成員:可以是變數、陣列、指標甚至其它結構體成員。
struct stu
;//分號不能丟
特殊宣告(匿名結構體型別,並不建議省略結構體型別名,知道有這麼回事就好了)
struct
x;
注意:有n個結構體就有n種型別,即使兩個結構體成員完全一樣,但依然是兩種型別
2、結構體的自引用
錯誤引用vs正確引用
錯誤原因:並不知道結構體空間大小,無法開啟空間。要自引用就必須引用自身變數的指標,因為指標不管是什麼型別都佔四個位元組。
struct a struct a
; 錯誤 };正確
3、結構體變數的定義和初始 訪問:允許集體初始化,不允許集體賦初值
struct stu
;struct stu s=;
c中不允許成員列表為空
printf("%s\n",s.name);//通過結構體變數進行訪問
printf("%s\n",s->name);//通過結構體指標進行訪問
4、結構體內存對齊,敲黑板了
1、為什麼要存在記憶體對齊:
平台原因(移植原因): 不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。
效能原因:資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在於:為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問,而對齊的記憶體訪問僅需要做一次訪問。
2、對齊規則:
(1) 第乙個成員在與結構體變數偏移量為0的位址處。
(2)其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處。
(3) 結構體總大小為最大對齊數(每個成員變數都有乙個對齊數)的整數倍。
(4)如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
(5)乙個變數對齊數為自身的大小,任何編譯器都沒有預設對齊數。
省空間小秘籍:盡量把佔空間小的往一塊兒放。
修改預設對齊數
#pragma pack(8)//設定預設對齊數為8
位段
1、位段的宣告:成員屬於整形家族(int char unsigned int signed int)
2、位段的成員名後面有乙個冒號和乙個數字(所佔位元位)
struct a
;sizeof的結果是8;
3、位段可以很好的節省空間,但有跨平台問題存在。並且有很多的不確定性,常用於網路協議。
**列舉:顧名思義就是列舉,**比如
enum color
;//其中的內容稱為列舉常量
預設從0開始,依次遞增一,也可以在定義的時候賦初值。
列舉優點
a、增加**的可讀性和可維護性
b、和#define定義的識別符號比較,列舉有型別檢查,更加嚴謹。
c、防止了命名汙染。
d、便於除錯。
e、使用方便,一次可以定義多個常量。
聯合(共用體)
聯合體所有變數共享空間,所有成員都是第乙個成員,聯合體的大小至少是最大成員的大小,當最大成員的大小不是最大對齊數的整數倍時候,就要對齊到最大對齊數的整數倍處。
自定義型別 結構體 位段 列舉 聯合
include include include 1 結構體 結構是一些值的集合,這些值稱為結構體成員,結構體的每個成員可以是不同型別的變數 struct stu 結構體的自引用 struct node 錯誤的,結構體內不能包含結構體自身 struct node 正確 指標是四個位元組 結構體內存對齊...
自定義型別(結構體 位段 列舉和聯合)
結構體常用於資料的大體模板相同,但具體的內容不同。例如 學生的資訊都包括學號,姓名,年齡等資訊,但是每個學生的資訊的內容不同。這時就要用到結構體的建立。1.定義結構體變數 以學生資訊為例 struct stu student 也可以用struct stu student 來定義結構體變數。當然也可以...
自定義型別詳解(結構體,位段,列舉, 聯合)
1.1 結構體宣告 結構體是一些值的集合,這些值稱為成員變數,這些值可以是不同的型別 struct tag variable list include include 結構體是一些值的集合,這些值稱為成員變數,結構的每個成員可以是不同型別的變數。一般宣告 struct stu 特殊宣告 匿名結構體型...