c語言除了可以使用基本資料型別以外,也可以自定義新的資料型別。新的資料型別由多個基本資料型別組成的,自定義資料型別分為 結構體 聯合體(共用體) 列舉
1.結構體
(1)基本語法
在實際問題中,比如表示乙個學生,學生本身包含學號(整型),姓名(字串),身高(浮點型),分數(浮點型)…,這些屬性不應該分開,而是構成乙個整體來代表乙個完整的學生。
c語言中可以使用結構體來將多個不同的資料型別組合起來,形成某種意義上的自定義的資料型別。
使用結構體前必須先宣告(型別),宣告結構體使用struct關鍵字
宣告語法:
struct 結構體型別名;
比如:struct student;
//結構體宣告不分配記憶體空間,所以成員變數在宣告不能初始化
//struct 結構體型別名 代表新定義的結構體型別
宣告結構體變數(不能省略struct):
struct 結構體型別名 結構體變數名;
也可以在宣告結構體型別時同時宣告結構體變數,通常不這麼做
struct 結構體型別名 結構體變數名;
(2)結構體變數的初始化
結構體變數的初始化有兩種語法,第一種是使用陣列初始化的方法進行初始化。
struct student stu = ;
第二種結構體初始化方法對指定的成員分別進行初始化。這種初始化的語法不要求初始化順序,而且允許只初始化一部分成員,方便對結構體進行擴充套件
struct student stu = ;
//未被初始化的成員將被初始化為0
(3)結構體成員的訪問
結構體相當於乙個集合,內部有多個成員,每個成員都可以單獨訪問,訪問結構體成員需要使用乙個新的運算子 --------- .(成員運算子)
語法如下:
結構體變數.成員變數名;
比如:stu.id = 100;
= 「zkk」;//錯誤
strcpy(std.name,「zkk」);
stu.height = 155.5f;
(4)結構體宣告語法的擴充套件
結構體宣告通常使用typedef對結構體型別起別名,語法如下:
typedef struct 結構體型別名 結構體型別別名;
比如:typedef struct student stu;
//stu 等價於 struct student
使用typedef時可以省略結構體型別名,語法如下:
typedef struct 結構體型別別名;
比如:typedef struct stu;
宣告結構體時可以省略結構體型別名,這種結構體叫匿名結構體,匿名結構只能使用一次。
//匿名結構體
struct 結構體變數名;
(5)結構體指標與陣列
結構體指標可以記錄結構體變數的位址,型別為 結構體型別 *
通過結構體指標也可以訪問結構體變數,通過箭頭運算子(->)
stu *pstu = (stu *)malloc(sizeof(stu));
pstu->id = 100;
strcpy(pstu->name,「zzy」);
pstu->height = 161.5f;
使用結構體作為陣列元素型別構成結構體陣列,訪問語法和普通陣列沒有區別,將每個元素當成結構體使用。
struct student s[5];//擁有5個元素的學生結構體陣列
s[0].id = 10;
(&s[0])->id = 100;
(s+1)->id = 10;//第2各元素的id成員
(*(s+1)).id = 100;
(6)結構體作為函式形參和返回值
結構體變數可以直接作為形參使用
不應該直接使用結構體變數作為函式的形參而應該使用結構體指標
結構體變數可以直接作為返回值使用
不應該直接使用結構體變數作為函式的返回值而應該使用結構體指標
結構體可以巢狀,結構體的成員也可以是結構體。
2.結構體的資料對齊
計算機儲存資料要求資料對齊,目的是提高訪問效率
計算機記憶體中資料的位址要求應該是資料自身大小的整數倍,這個規則就叫資料對齊。
由於結構體有多個成員變數組成,成員變數本身要求對齊,這樣救就會造成結構體各個變數之間可能有空隙,意味著整個結構體的大小不一定是所有成員大小之和。
//第乙個成員自動對齊,可以認為從0開始
struct a;
struct b;
結構體對齊的規則有兩個:
1.每個成員的首位址必須是自身大小的整數倍(可以認為位址從0開始),如果不是就後移對齊
2.整個結構體的大小必須是最大成員大小的整數倍,不夠在最後補齊
注:32位系統double只需要4位元組對齊和補齊
c語言提供了語法強制按照指定規則對齊,使用一條預處理指令
#pragma pack(n)//表示資料最多按n位元組對齊
比如#pragma pack(1)//按1位元組對齊
單個資料對齊的值叫m值,比如double型別m=8
整個結構體對齊的值叫m值,m是最長元素的m值
3.聯合體(共用體)
聯合也可以定義新的資料型別,宣告聯合使用關鍵字union
宣告聯合體的語法和結構體完全一樣,僅僅是關鍵字不同
union 聯合型別名;
聯合體中所有的成員變數儲存在記憶體中的起點都一樣
整個聯合體的大小是其中最大成員變數的大小
聯合中所有的成員變數互相影響,修改其中乙個會影響其他成員變數的值
聯合可以用不同方式使用同一段空間,當任何時候只會使用多個資料中的其中乙個是,就可以使用聯合。
4.列舉
列舉也可以自定義資料型別,宣告列舉使用enum關鍵字。
列舉型別規定了一組固定的名稱(應該大寫),這些名稱實際上是用數字儲存的,在程式可以當數字使用。
宣告列舉型別語法:
enum 列舉型別名;
//列舉型別預設給第乙個名字分配0數字,後面的明書代表的數字依次遞增
enum 列舉型別名;
//也可以直接指定某個名字對應的數字,改名字後面的名字對應的數字將同時發生變化
宣告列舉變數語法:
enum 列舉型別名 列舉變數名;
//列舉變數可以記錄型別中某個名字
typedef同樣可以用於列舉
使用列舉變數的目的是增加程式的可讀性。
如果名字代表的數字有意義,選擇使用巨集定義,否則選擇使用列舉
自定義資料型別 結構體
陣列是一種資料形式,其特點是多個相同型別的元素集合起來 結構體是另一種重要的資料形式,特點是將不同型別的成員組合起來 陣列和結構體形成了兩種風格迥異的聚合方式,通過他們以及相互組合,巢狀的機制可以構造出複雜的,滿足應用要求的自定義資料型別 結構體允許將不同型別的資料元素組合到一起形成一種新的資料型別...
自定義資料型別 結構型別
c 中自定義資料型別還有一種稱為結構型別,並且把該型別的各種資料型別一一整合到其中。學號 型別 姓名 字串 學生年齡 整型 院系 字串 平均成績 浮點型 每個學生的資訊成為了乙個整體,雜亂的資料和每個學生一一對應了起來,方便管理。如果需要建立學生型別,就可以這樣寫。include using nam...
C C 學習 自定義資料型別(結構體,共用體)
struct student 1 結構體型別宣告一般放在程式檔案開頭,此時這個宣告是全域性的。在全域性作用域內,該宣告處處可見,因此同作用域內的所有函式都可以使用它。2 結構體型別的宣告也可以放在函式內部,此時這個宣告是區域性的。說明 1 結構體型別和普通資料型別 eg int char doubl...