枚舉
什麼是枚舉?
枚舉是一種用戶定義的數據類型,它用關鍵字 enum 以如下語法來聲明: enum 枚舉類型名字 {名字0, …, 名字n} ;
簡單的說,就是把一個事物的可能的結果一一列舉出來
怎樣使用枚舉?
下面舉個例子
例1:
# include <stdio.h>
enum WeekDay {
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
};
int main(void) {
enum WeekDay day1, day2;
day1 = Monday;
day2 = Sunday;
printf("Monday = %d\n", day1);
printf("Sunday = %d\n", day2);
return 0;
}
輸出結果爲:
需要說明的是,本程序的第3到5行代碼,只是定義了一個數據類型,並沒有定義變量,該數據類型爲 enum WeekDay
而之所以輸出是0和6,是因爲枚舉中的元素是從0開始依次遞增的,當然,如果指定元素的值,其後的元素依舊會依次遞增下去,示例如下
例2:
# include <stdio.h>
enum WeekDay {
Monday = 1, Tuesday, Wednesday = 7, Thursday, Friday, Saturday, Sunday
};
int main(void) {
enum WeekDay day1, day2, day3, day4;
day1 = Monday;
day2 = Tuesday;
day3 = Wednesday;
day4 = Sunday;
printf("Monday = %d\n", day1);
printf("Tuesday = %d\n", day2);
printf("Wednesday = %d\n", day3);
printf("Sunday = %d\n", day4);
return 0;
}
輸出結果爲:
爲什麼要使用枚舉?
在回答這個問題前。先要說的一個概念是常量符號化,所謂常量符號化,即用符號而不是具體的數字來表示程序中的數字,這個可以使用const和define實現,但是一個個的const和define相對繁瑣,而枚舉在此處有些便利之處,因爲枚舉元素一般按常量處理
如例1的enum量如果是使用const或define表示,則是這樣
int const Monday = 0;
int const Tuesday = 1;
int const Wednesday = 2;
int const Thursday = 3;
int const Friday = 4;
int const Saturday = 5;
int const Sunday = 6;
或
# define Monday 0
# define Tuesday 1
# define Wednesday 2
# define Thursday 3
# define Friday 4
# define Saturday 5
# define Sunday 6
枚舉類型名字通常並不真的使用,要用的是在大括號裏的名字,因爲它們就是就是常量符號,它們的類型是int,值則依次從0 到n。如:enum colors { red, yellow, green } ; 就創建了三個常量,red的值是0,yellow是1,⽽而green是2。當需要⼀一些可以排列起來的常量值時,定義枚舉的意義就是給了這些常量值名字。
枚舉類型可以跟上enum作爲類型,但是實際上是以整數來做內部計算和外部輸入輸出的
枚舉的優缺點
雖然枚舉類型可以當作類型使⽤用,但是實際上 很少(不好)用,如果有意義上排比的名字,用枚舉比const int方便,枚舉比宏(macro)好,因爲枚舉有int類型
如果想要對枚舉元素計數,則可在正常定義的枚舉元素後加一個表示有用的元素個數,例如,enum color{ red, yellow, green, blue, purple, Num };,Num的值爲5,其可以表示這個枚舉中有效元素的個數,在對枚舉元素進行遍歷等操作時,就可以用到這個
聯合體(也叫共用體)
關鍵字爲union,其所有的成員共享一個內存空間,同一時間只有一個成員是有效的,其大小即其所佔內存最大的成員所佔的內存
其格式與結構體相似,可以這樣定義——
union data {
int i;
char c;
} a, b, c;
也可以這樣——
union data {
int i;
char c;
};
union data a, b, c;
還可以這樣——
union {
int i;
char c;
}a, b, c;
這與結構體表面上是一樣的類型
下面舉幾個例子
例3:
# include <stdio.h>
union data {
int i;
char c;
} a;
int main(void) {
a.i = 3;
a.c = 'A'; //A的ASCLL值是65
printf("%d\n", a.i);
printf("a.i的地址爲:%p\na.c的地址爲:%p\n", &a.i, &a.c);
return 0;
}
輸出結果爲:
由結果可以更好地理解上面的話,最終輸出的是a.c,所以說,同一時間只有一個成員是有效的;而最終輸出的union data和a.i的地址相同,也證明了“其大小即其所佔內存最大的成員所佔的內存”這句話的正確
還有就是,聯合體不能作爲函數的參數,也不能作爲函數的返回類型,這點是和結構體不一樣的,不過,依舊可以使用指向聯合體變量的指針(與結構體變量的用法類似),並且它也可以出現在結構體中,還可以定義聯合體數組,當然,結構體和數組也可以出現在聯合體中
例4:
# include <stdio.h>
# include <stdlib.h>
union data {
int i;
char c;
} a, * p;
int main(void) {
int s, k = 1;
char ch = 'A';
union data t[3];
p = (union data *)malloc(sizeof(union data));
p->i = 10;
p->c = 'A';
for (s=0; s<3; s++) {
t[s].i = k++;
t[s].c = ++ch;
}
for (s=0; s<3; s++) {
printf("%d ", t[s].c);
}
return 0;
}
輸出結果爲:
14、15、16行不會報錯
【所有代碼均在windows系統下dev c++下運行通過】
(如有錯誤,敬請指正)