前言
在C語言的自定義數據類型中,除了我們最為常用的結構體之外,還有兩個比較少用的自定義數據類型,分別為枚舉和聯合體(也可以稱為共用體)。
今天,我們一起看學習一下相關的知識吧!
枚舉
什么是枚舉?
顧名思義,就是一一列舉,把所有的情況,所有的取值,一一列舉出來。
在我們生活中,有不少的東西是可以全部列舉出來的。
如一個星期有七天,一年有十二個月,性別有男和女,評價有優秀、良好、及格和不及格等等。
當某些數據的值只有固定的幾種可能取值的時候,我們就可以使用枚舉類型。
枚舉類型的定義
enum 枚舉類型名 { 枚舉值1 ,枚舉值2,… ,枚舉值n };
枚舉類型的定義和結構體類似,先使用enum這個關鍵字,后面加上枚舉類型的名字,括號內是枚舉的值,最后別忘記分號。
還有,最后的一個枚舉值后面不需要逗號!
一般定義枚舉類型的方法如下:
注意:這是定義枚舉類型,而不是定義枚舉變量!
例如如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
enum Day //星期 { Mon, Tues, Wed, Thur, Fri, Sat, Sun }; enum Sex //性別 { MALE, FEMALE, SECRET }; enum Color //顏色 { RED, GREEN, BLUE }; |
此外,還有其他的一些定義的方法。
枚舉類型的優點
那么我們來思考一個問題,為什么需要枚舉呢?
我們其實可以通過#define的方式來定義常量,那么我們還需要定義枚舉嗎?
其實是需要的。
在有些情況下,枚舉可以讓我們的代碼更加清晰明了。
比如,我們在需要打印菜單的時候,就需要有不同的選項,那么每一個選項就對應一個值,那么我們可以使用枚舉讓數值與對應的含義對上號,那么這就可以讓我們在實現每一個具體的細節的時候,知道這一種case情況對應的具體含義。
此外,還有別的優點:
- 防止了命名污染(封裝)
- 便于調試
- 使用方便,一次可以定義多個常量
枚舉類型的使用
通過枚舉類型,我們可以定義枚舉變量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
enum Color //顏色 { RED, GREEN, BLUE }; //使用方法和其他類型一直,就像int a;一樣 enum Color clr; //使用枚舉值來給枚舉類型賦值 clr = RED; //注意,一般我們給枚舉賦值的時候,都用枚舉值,而不用其他的值,否則就沒有什么意義了 |
我們一般使用結構體的時候,都像上面的栗子一樣。
先創建好枚舉的模板,燃用這個模板來創建變量。
此外,還有其他的方法:
創建模板的同時定義枚舉變量
1
2
3
4
5
6
|
enum Color //顏色 { RED, GREEN, BLUE }clr1,clr2; //在最后這里,我們定義了兩個枚舉變量 |
省略枚舉類型名字,匿名創建枚舉變量
1
2
3
4
5
6
|
enum { RED, GREEN, BLUE }clr1,clr2; //這里定義了兩個枚舉變量 |
上面的兩個變量依舊可以使用,只是,我們沒有寫出該枚舉類型的名字,就只能這樣來定義變量,以后不能在利用這個模板來創建變量了
使用typedef來給枚舉類型重命名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
typedef enum Color //顏色 { RED, GREEN, BLUE }cr; //注意,這里的cr是新的枚舉類型名字,不是定義的枚舉變量 //還可以匿名重命名 typedef enum { RED, GREEN, BLUE }cr; |
枚舉中需要注意的點
- 枚舉值只能是整型的數據,如字符、整數等,不能是浮點型
- 枚舉類型變量賦值的時候,一般用枚舉值來賦值,不適用其他的數值來賦值
- 枚舉值本身是一個常量,我們可以對枚舉變量的值進行修改,但不能對枚舉值進行修改
- 枚舉值被處理的時候,會被看成整數數值,因此枚舉變量可以算術運算、關系運算等
聯合體
聯合體類型的定義
union 聯合體類型名 { 數據類型 成員名1 , 數據類型 成員名 2 , … , 數據類型 成員名n;};
聯合體也叫共用體,這個也是一種特殊的數據類型。
這種類型定義的變量也包含一系列的成員,特征是這些成員公用同一塊空間。
栗子如下:
1
2
3
4
5
|
union Un { char c; int i; }; |
聯合體的特點
聯合體變量的成員是使用共同的一塊空間的。
聯合體的大小,至少是成員中最大成員的大小。
(這里的至少我們后面再說)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include<stdio.h> union Un { int i; char c; }; union Un un; int main() { // 下面輸出的結果是一樣的嗎? printf ( "%p\n" , &un); printf ( "%p\n" , &(un.i)); printf ( "%p\n" , &(un.c)); return 0; } |
運行上面的代碼,我們會發現三個地址都相同
成員變量i是第一個成員,該地址和聯合體的地址相同我們可以理解,c作為第二個成員變量,其地址也是和第一個成員變量的地址相同,那么這就說明,它們確實使用的是同一塊空間
聯合體的使用
聯合體類型定義變量的方法,和結構體、枚舉類似,都有多種方法
先創建模板,在定義變量
1
2
3
4
5
6
|
union Un { int i; char c; }; union Un un; |
創建模板的同時定義變量
1
2
3
4
5
|
union Un { int i; char c; }un; //此處的un是一個聯合體變量 |
匿名定義聯合體變量
1
2
3
4
5
|
union { int i; char c; }un; //此處的un是一個聯合體變量 |
同樣的,由于聯合體類型名的省略,我們只可以這樣來定義變量,后面就再也不能使用該模板來定義變量了
typedef重命名聯合體類型名
1
2
3
4
5
6
7
8
9
10
11
12
|
typedef union Un { int i; char c; }un; typedef union { int i; char c; }un; |
聯合體存在內存對齊
上面說到,聯合體的大小,至少是最大成員變量的大小。為什么是至少呢?
我們先來看下面的栗子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
union Un { char arr[6]; short s; }; union Un u; int main() { // 下面輸出的結果是一樣的嗎? printf ( "%u" , sizeof ( union Un)); return 0; } |
上面的代碼輸出的結果為6
如果我們把字符數組的大小改成5,會發現大小還是6
這是因為,聯合體中也存在著對齊
上面的栗子中,會認為字符數組的默認對齊數為1,而short的默認對其數位2,但是成員變量的大小會根據數組的大小來計算,而不是根據數組的元素類型。假如你是元素個數為6的字符數組,那么大小就是6,元素個數為5的字符數組,大小就是5,而int、short等數據類型就按照默認的大小來計算。
首先需要聯合體的大小至少是最大成員變量的大小。
然后要求大小應該為各個成員變量中,最大對齊數的倍數,如果不是倍數,那么對齊到整數倍處。
這就能說明,為什么上面的代碼把字符數組的大小改為5個元素的時候,聯合體的大小仍然為6.
結語
今天的分享到這里就結束啦!
由于本人能力有限,難免會有出錯的地方,還希望各位能夠指出!
希望各位能給我點個贊、點個收藏哦~
謝謝支持!
到此這篇關于C語言關于自定義數據類型之枚舉和聯合體詳解的文章就介紹到這了,更多相關C語言 自定義數據類型內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_61021362/article/details/120961494