Skip to content

Commit 9e42bbe

Browse files
author
yangjingjing
committed
init blog
1 parent 57fd612 commit 9e42bbe

9 files changed

Lines changed: 2328 additions & 0 deletions
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
---
2+
layout: post
3+
categories: [C]
4+
description: none
5+
keywords: C
6+
---
7+
# C语言关键字enum
8+
9+
## 关键字enum的定义
10+
enum是C语言中的一个关键字,enum叫枚举数据类型,枚举数据类型描述的是一组整型值的集合(这句话其实不太妥当),枚举型是预处理指令#define的替代,枚举和宏其实非常类似,宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值,
11+
12+
我们可以将枚举理解为编译阶段的宏,使用格式:
13+
```
14+
enum typeName { valueName1, valueName2, valueName3, ...... };
15+
```
16+
typeName是枚举类型的名字,花括号里面的元素(枚举成员)是常量而不是变量,这个一定要搞清楚,因为枚举成员的是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量。
17+
18+
枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。
19+
20+
接下来我们举个例子,比如:一星期有 7 天,如果不用枚举,我们需要使用 #define 来为每个整数定义一个别名:
21+
```
22+
#defineMON 1
23+
#defineTUE 2
24+
#defineWED 3
25+
#defineTHU 4
26+
#defineFRI 5
27+
#defineSAT 6
28+
#defineSUN 7
29+
```
30+
这个看起来代码量就比较多,接下来我们看看使用枚举的方式:
31+
```
32+
enum DAY
33+
{
34+
MON=1, TUE, WED, THU, FRI, SAT, SUN
35+
};
36+
```
37+
这样看起来是不是更简洁了。
38+
39+
需要注意的两点是:
40+
1) 枚举列表中的 Mon、Tues、Wed 这些标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。
41+
42+
2) Mon、Tues、Wed 等都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。
43+
44+
枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。
45+
46+
总结:
47+
(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
48+
49+
(2)DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
50+
51+
(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。在当前值没有赋值的情况下,枚举类型的当前值总是前一个值+1.
52+
53+
(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。
54+
55+
(5) 枚举型是预处理指令#define的替代。
56+
57+
(6) 类型定义以分号;结束。
58+
59+
## 枚举变量的定义
60+
前面我们只是声明了枚举类型,接下来我们看看如何定义枚举变量。
61+
62+
我们可以通过以下三种方式来定义枚举变量
63+
64+
### 先定义枚举类型,再定义枚举变量
65+
```
66+
enum DAY
67+
{
68+
MON=1, TUE, WED, THU, FRI, SAT, SUN
69+
};
70+
enum DAY day;
71+
```
72+
73+
### 定义枚举类型的同时定义枚举变量
74+
```
75+
enum DAY
76+
{
77+
MON=1, TUE, WED, THU, FRI, SAT, SUN
78+
} day;
79+
```
80+
81+
### 省略枚举名称,直接定义枚举变量
82+
```
83+
enum
84+
{
85+
MON=1, TUE, WED, THU, FRI, SAT, SUN
86+
} day;
87+
```
88+
注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。错误示例如下所示:
89+
90+
错误声明一:存在同名的枚举类型
91+
```
92+
typedef enum
93+
{
94+
wednesday,
95+
thursday,
96+
friday
97+
} workday;
98+
typedef enum WEEK
99+
{
100+
saturday,
101+
sunday = 0,
102+
monday,
103+
} workday;
104+
```
105+
106+
错误声明二:存在同名的枚举成员
107+
```
108+
typedef enum
109+
{
110+
wednesday,
111+
thursday,
112+
friday
113+
} workday_1;
114+
typedef enum WEEK
115+
{
116+
wednesday,
117+
sunday = 0,
118+
monday,
119+
} workday_2;
120+
```
121+
122+
## 使用枚举类型的变量
123+
124+
1. 对枚举型的变量赋值
125+
实例将枚举类型的赋值与基本数据类型的赋值进行了对比:
126+
127+
方法一:先声明变量,再对变量赋值
128+
```
129+
#include<stdio.h>
130+
/* 定义枚举类型 */
131+
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };
132+
void main()
133+
{
134+
/* 使用基本数据类型声明变量,然后对变量赋值 */
135+
int x, y, z;
136+
137+
x = 10;
138+
y = 20;
139+
z = 30;
140+
141+
/* 使用枚举类型声明变量,再对枚举型变量赋值 */
142+
enum DAY yesterday, today, tomorrow;
143+
144+
yesterday = MON;
145+
today = TUE;
146+
tomorrow = WED;
147+
printf("%d %d %d \n", yesterday, today, tomorrow);
148+
}
149+
```
150+
151+
方法二:声明变量的同时赋初值
152+
```
153+
#include <stdio.h>
154+
/* 定义枚举类型 */
155+
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };
156+
void main()
157+
{
158+
/* 使用基本数据类型声明变量同时对变量赋初值 */
159+
int x=10, y=20, z=30;
160+
/* 使用枚举类型声明变量同时对枚举型变量赋初值 */
161+
enum DAY yesterday = MON,
162+
today = TUE,
163+
tomorrow = WED;
164+
printf("%d %d %d \n", yesterday, today, tomorrow);
165+
}
166+
```
167+
168+
方法三:定义类型的同时声明变量,然后对变量赋值。
169+
```
170+
#include <stdio.h>
171+
/* 定义枚举类型,同时声明该类型的三个变量,它们都为全局变量 */
172+
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } yesterday, today, tomorrow;
173+
/* 定义三个具有基本数据类型的变量,它们都为全局变量 */
174+
int x, y, z;
175+
void main()
176+
{
177+
/* 对基本数据类型的变量赋值 */
178+
x = 10; y = 20; z = 30;
179+
180+
/* 对枚举型的变量赋值 */
181+
yesterday = MON;
182+
today = TUE;
183+
tomorrow = WED;
184+
printf("%d %d %d \n", x, y, z); //输出:10 20 30
185+
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
186+
}
187+
```
188+
189+
方法四:类型定义,变量声明,赋初值同时进行。
190+
```
191+
#include <stdio.h>
192+
/* 定义枚举类型,同时声明该类型的三个变量,并赋初值。它们都为全局变量 */
193+
enum DAY
194+
{
195+
MON=1,
196+
TUE,
197+
WED,
198+
THU,
199+
FRI,
200+
SAT,
201+
SUN
202+
}
203+
yesterday = MON, today = TUE, tomorrow = WED;
204+
/* 定义三个具有基本数据类型的变量,并赋初值。它们都为全局变量 */
205+
int x = 10, y = 20, z = 30;
206+
void main()
207+
{
208+
printf("%d %d %d \n", x, y, z); //输出:10 20 30
209+
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
210+
}
211+
```
212+
213+
对枚举型的变量赋整数值时,需要进行类型转换。
214+
```
215+
#include <stdio.h>
216+
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };
217+
void main()
218+
{
219+
enum DAY yesterday, today, tomorrow;
220+
yesterday = TUE;
221+
today = (enum DAY) (yesterday + 1); //类型转换
222+
tomorrow = (enum DAY) 30; //类型转换
223+
//tomorrow = 3; //错误
224+
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:2 3 30
225+
}
226+
```
227+
228+
使用枚举型变量
229+
```
230+
#include<stdio.h>
231+
enum
232+
{
233+
BELL = '\a',
234+
BACKSPACE = '\b',
235+
HTAB = '\t',
236+
RETURN = '\r',
237+
NEWLINE = '\n',
238+
VTAB = '\v',
239+
SPACE = ' '
240+
};
241+
enum BOOLEAN { FALSE = 0, TRUE } match_flag;
242+
void main()
243+
{
244+
int index = 0;
245+
int count_of_letter = 0;
246+
int count_of_space = 0;
247+
char str[] = "I'm Ely efod";
248+
match_flag = FALSE;
249+
for(; str[index] != '\0'; index++)
250+
if( SPACE != str[index] )
251+
count_of_letter++;
252+
else
253+
{
254+
match_flag = (enum BOOLEAN) 1;
255+
count_of_space++;
256+
}
257+
258+
printf("%s %d times %c", match_flag ? "match" : "not match", count_of_space, NEWLINE);
259+
printf("count of letters: %d %c%c", count_of_letter, NEWLINE, RETURN);
260+
}
261+
输出:
262+
match 2 times
263+
count of letters: 10
264+
Press any key to continue
265+
```
266+
267+
## 枚举类型的大小
268+
```
269+
#include <stdio.h>
270+
enum escapes
271+
{
272+
BELL = '\a',
273+
BACKSPACE = '\b',
274+
HTAB = '\t',
275+
RETURN = '\r',
276+
NEWLINE = '\n',
277+
VTAB = '\v',
278+
SPACE = ' '
279+
};
280+
enum BOOLEAN { FALSE = 0, TRUE } match_flag;
281+
void main()
282+
{
283+
printf("%d bytes \n", sizeof(enum escapes)); //4 bytes
284+
printf("%d bytes \n", sizeof(escapes)); //4 bytes
285+
printf("%d bytes \n", sizeof(enum BOOLEAN)); //4 bytes
286+
printf("%d bytes \n", sizeof(BOOLEAN)); //4 bytes
287+
printf("%d bytes \n", sizeof(match_flag)); //4 bytes
288+
printf("%d bytes \n", sizeof(SPACE)); //4 bytes
289+
printf("%d bytes \n", sizeof(NEWLINE)); //4 bytes
290+
printf("%d bytes \n", sizeof(FALSE)); //4 bytes
291+
printf("%d bytes \n", sizeof(0)); //4 bytes
292+
}
293+
```
294+
通过上面的实例,发现输出都为4。实际上,枚举类型在存储时,是按照int型存储的,在我的系统中也就是4字节方式存储。
295+
296+
## 综合举例
297+
```
298+
#include<stdio.h>
299+
enum Season
300+
{
301+
spring, summer=100, fall=96, winter
302+
};
303+
typedef enum
304+
{
305+
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
306+
}
307+
Weekday;
308+
void main()
309+
{
310+
/* Season */
311+
printf("%d \n", spring); // 0
312+
printf("%d, %c \n", summer, summer); // 100, d
313+
printf("%d \n", fall+winter); // 193
314+
Season mySeason=winter;
315+
if(winter==mySeason)
316+
printf("mySeason is winter \n"); // mySeason is winter
317+
318+
int x=100;
319+
if(x==summer)
320+
printf("x is equal to summer\n"); // x is equal to summer
321+
printf("%d bytes\n", sizeof(spring)); // 4 bytes
322+
/* Weekday */
323+
printf("sizeof Weekday is: %d \n", sizeof(Weekday)); //sizeof Weekday is: 4
324+
Weekday today = Saturday;
325+
Weekday tomorrow;
326+
if(today == Monday)
327+
tomorrow = Tuesday;
328+
else
329+
tomorrow = (Weekday) (today + 1); //remember to convert from int to Weekday
330+
}
331+
```
332+
333+
## 枚举与#define 宏的区别
334+
下面再看看枚举与#define 宏的区别:
335+
336+
1)#define 宏常量是在预编译阶段进行简单替换。枚举常量则是在编译的时候确定其值。
337+
338+
2)一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
339+
340+
3)枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

0 commit comments

Comments
 (0)