文档章节

C语言枚举类型

jockchou
 jockchou
发布于 2015/06/10 19:15
字数 1777
阅读 15
收藏 0
点赞 0
评论 0

C语言枚举类型


在讲枚举之前,我们先来看一个案例,它能帮助我们更好的理解C设计枚举的意图。假设我们在程序中要分别表示星期一到星期天这一周,也许我们可以这样做:

#include<stdio.h>
#include<string.h>

#define	MON	1
#define	TUE	2
#define	WED	3
#define	THU	4
#define	FRI	5
#define	SAT	6
#define	SUN	7

void printf_today(int day);

int main(void) {
	
	int today = FRI;
	printf_today(today);
	
	return 0;
}

void printf_today(int day) {
	char today[10];
	
	switch(day) {
		case MON:
			strcpy(today, "monday");
			break;
			
		case TUE:
			strcpy(today, "tuesday");
			break;
			
		case WED:
			strcpy(today, "wednesday");
			break;
			
		case THU:
			strcpy(today, "thursday");
			break;
			
		case FRI:
			strcpy(today, "friday");
			break;
			
		case SAT:
			strcpy(today, "saturday");
			break;
		
		case SUN:
			strcpy(today, "sunday");
			break;
		
		default:
			strcpy(today, "unknowday");
	}
	
	printf("today is %s\n", today);
}

上例程序用来打印今天是星期几,定义一系列的宏的好处是,即使把星期对应的数值改掉,也不用修改printf_today()函数中的代码。也就是说,你以后可以把宏定义改成这样:

#define	SUN	0
#define	MON	1
#define	TUE	2
#define	WED	3
#define	THU	4
#define	FRI	5
#define	SAT	6

无论怎么修改宏定义,都不会影响以上程序的功能。但是也有一个缺点,需要定义好多个宏才能完成工作。C语言定义一种新的数据类型,希望它能完成同样的工作,这种新的数据类型叫枚举型。

我们先来看枚举是如何改善以上程序的:

#include<stdio.h>
#include<string.h>

enum days {SUN, MON, TUE, WED, THU, FRI, SAT};

void printf_today(int day);

int main(void) {
	
	int today = FRI;
	printf_today(today);
	
	return 0;
}

void printf_today(int day) {
	/*...省略...*/
}

以上程序只是简单地把宏定义换成enum days {SUN, MON, TUE, WED, THU, FRI, SAT};枚举定义,运行结果仍然是一样的。从以上程序我们可以看出枚举类型中的成员是一些命名的整型常量。

枚举的概念

枚举是一种自定义的数据类型,它用来存储一系列命名整型常量的值,可以通过成员名字来引用这些值,这些值默认是signed int类型。 虽然枚举能表示一系列的整型常量,但是每次只能使用其中一个具体的常量值。也就是说一个枚举变量的值只能是枚举中的一个命名常量的值。从这个角度理解,枚举更像是定义了一种取值范围有限的整型。

定义枚举类型

下面的代码定义一种枚举类型:

#include<stdio.h>

enum fruit {grape, cherry, lemon, kiwi};

int main(void) {
	
	printf("grape  = %d\n", grape);
	printf("cherry = %d\n", cherry);
	printf("lemon  = %d\n", lemon);
	printf("kiwi   = %d\n", kiwi);
	
	return 0;
}

输出结果:

grape  = 0
cherry = 1
lemon  = 2
kiwi   = 3

上例定了一个枚举fruit,它包含四个整型常量值,grape, cherry, lemon, kiwi。从输出结果可以看出它们的值依次是0,1,2,3。修改上例程序:

#include<stdio.h>

enum fruit {grape, cherry, lemon, kiwi};
enum more_fruit {banana = -17, apple, blueberry, mango};

int main(void) {
	
	printf("grape  = %d\n", grape);
	printf("cherry = %d\n", cherry);
	printf("lemon  = %d\n", lemon);
	printf("kiwi   = %d\n", kiwi);
	
	printf("\n");

	printf("banana     = %d\n", banana);
	printf("apple      = %d\n", apple);
	printf("blueberry  = %d\n", blueberry);
	printf("mango      = %d\n", mango);
	
	return 0;
}

输出结果:

grape  = 0
cherry = 1
lemon  = 2
kiwi   = 3

banana     = -17
apple      = -16
blueberry  = -15
mango      = -14

从以上两例可以看出,枚举中值默认是从0开始的,后一个值在前一个基础上自动加1,你也可以手动指定其中某一个量的值。再次修改程序:

#include<stdio.h>

enum fruit {grape, cherry, lemon, kiwi};
enum more_fruit {banana = -17, apple, blueberry, mango};
enum yet_more_fruit {kumquat, raspberry, peach, plum = peach + 2};
						  
int main(void) {
	
	printf("grape  = %d\n", grape);
	printf("cherry = %d\n", cherry);
	printf("lemon  = %d\n", lemon);
	printf("kiwi   = %d\n", kiwi);
	
	printf("\n");
	
	printf("banana     = %d\n", banana);
	printf("apple      = %d\n", apple);
	printf("blueberry  = %d\n", blueberry);
	printf("mango      = %d\n", mango);
	
	
	printf("\n");
	
	printf("kumquat		= %d\n", kumquat);
	printf("raspberry	= %d\n", raspberry);
	printf("peach		= %d\n", peach);
	printf("plum		= %d\n", plum);
	
	return 0;
}

输出结果:

grape  = 0
cherry = 1
lemon  = 2
kiwi   = 3

banana     = -17
apple      = -16
blueberry  = -15
mango      = -14

kumquat         = 0
raspberry       = 1
peach           = 2
plum            = 4

上例说明,枚举定义中一个枚举成员值可以引用另一个,正确的讲应该是后面的可以引用前面的。

声明枚举变量

定义枚举类型后,你可以声明一个枚举类型的变量。下面的例子声明了一个枚举变量,枚举类型的定义和变量的声明可以在一个语句中完成:

/*定义类型同时声明变量*/
enum fruit {banana, apple, blueberry, mango} my_fruit;

/*定义类型*/
enum fruit {banana, apple, blueberry, mango};
/*声明变量*/
enum fruit my_fruit;

虽然在前面我们讲枚举实际上取值范围有限的整型,但这只是C语言推荐的一种类型,它并不会检查枚举类型变量的取值是否是枚举中定义过的值。C语言把这些检查交给程序员去做,这也体验了C高性能的设计决策。如下例所示:

#include<stdio.h>

enum fruit {grape, cherry, lemon, kiwi};
						  
int main(void) {
	
	enum fruit myf = cherry;
	
	myf = 30;
	
	printf("myf = %d\n", myf);
	
	return 0;
}
/* 输出结果: myf = 30 */

这样我们就能看到C语言枚举类型的本质就是一个整型,枚举成员只是为了更好的辅助编程,提高可读性和拓展性。枚举成员就是一系列的命名整型常量。它们的值是只读的,不能被修改。另外,在switch语句中使用枚举对编译器比较友好,如果你忘掉在switch中处理一些枚举成员的分支,有的编译器会给你一个警告信息。

你还可以使用typedef来定义枚举类型的别名:

#include<stdio.h>
#include<string.h>

typedef enum { 
	SUN, 
	MON,
	TUE,
	WED,
	THU,
	FRI,
	SAT
} days;

void printf_today(int day);

int main(void) {

    days today = FRI;
    printf_today(today);

    return 0;
}

void printf_today(int day) {
	/*...省略...*/
}

聪明的你,可以再看看下面的程序,或许能得到一些启发:

#include<stdio.h>

typedef enum { FALSE, TRUE, false = 0, true } boolean;

void printf_bool(boolean b) {
	if (b)
		printf("b = %4d, boolean val is TRUE\n", b);
	else
		printf("b = %4d, boolean val is FALSE\n", b);
	
}

int main(void) {

    boolean b = TRUE;
	printf_bool(b);
	
	b = FALSE;
	printf_bool(b);
	
	b = -100;
    printf_bool(b);
	
	b = 0;
	printf_bool(b);
	
	b = 0.0;
	printf_bool(b);
	
	b = false;
	printf_bool(b);
	
	b = true;
	printf_bool(b);
	
    return 0;
}

上面的程序通过枚举的形式实现了boolean类型,但是它有一个坑,当作条件判断时,如果使用if (b == TRUE)这种语法,会跟意想的有错误。因为TRUE在上面程序员被定义成值为1的常量。b = 100当然不会==1啦。但b == 100关系表达式的值确为真。因为本质是整数,两个为真的整数 == 比较的结果不一定为真,所以应该写成if (b)即可。如下:

#include<stdio.h>

typedef enum { FALSE, TRUE, false = 0, true } boolean;

void printf_bool(boolean b) {
	if (b)
		printf("b = %4d, boolean val is TRUE\n", b);
	else
		printf("b = %4d, boolean val is FALSE\n", b);
	
}

int main(void) {

    boolean b;
	printf_bool(b);
	
	b = -100;
    printf_bool(b);
	
	/* 应该写成if (b) */
	if (b == TRUE) {
		printf("b is TRUE\n");
	} else {
		printf("b is FALSE\n");
	}
	
    return 0;
}

© 著作权归作者所有

共有 人打赏支持
jockchou
粉丝 29
博文 38
码字总数 28900
作品 1
深圳
高级程序员
二十二、枚举

说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略 上一讲介绍了结构体...

长平狐
2013/03/28
29
0
C语言基础-14-枚举

上一讲介绍了结构体类型,这讲就介绍C语言中的另一种数据类型---枚举类型。枚举类型在iOS中也是很常用的,用法跟Java中的枚举类似。 一、枚举的概念 枚举是C语言中的一种基本数据类型,并不是...

Corwien
2016/03/16
9
0
【iOS】Swift中的函数、断言、枚举等

函数与方法、枚举等的书写格式与用法较OC还是变化很大的。 一、函数 1.1 无返回值, 无形参 func myTest2(){ } 1.2 有返回值,有形参 func myTest1( num1:Int , num2:Int ) -> String{ } 1.3...

xn4545945
2014/09/15
0
0
NDK开发---C++学习(一):基础知识

前言 C++是从C语言发展演变而来的,它在C语言的基础上引入了类(class)的概念,并增加了抽象与封装、继承、重载和多态等面向对象的语言处理机制。C++向前兼容了C语言程序设计,使得绝大部分C...

浮生若梦zp
2017/11/20
0
0
Effective OC : 1-5

1,了解Objective-C语言的起源: OC为C语言的超集,为C加入了面向对象的特性。 要理解C中的指针和内存模型。 2.在类文件里尽量少引入其它头文件: 引入过多头文件。将借口暴露,添加耦合度。这...

技术mix呢
2017/10/11
0
0
ASN.1编码规则(数据类型)

ASN.1中定义的数据类型既有简单的基本数据类型,也有复杂的结构类型。 基本类型是不可再再分的,包括: 布尔型(BOOLEAN) 整型(INTEGER) 实型(REAL) 位串类型(BITSTRING) 8位位组类型...

DayDayUpCQ
2013/07/05
0
0
C语言结构体、枚举以及位域的讲解

谨记 什么是价值?或许没有多少人能够明白,其实价值并不是实际存在的,它应该是一种体现,比如为城市点缀最美好的一面而起早摸黑的打扫的城市清洁工的大妈大爷;为中国航天事业而几个月没回...

长风留言
2017/11/20
0
0
iOS开发系列--Swift语言

概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言、ObjC的特性,且克服了C语言的兼容性问题。Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其...

jianxin160
2015/08/18
0
0
《Effective Java读书笔记》--C语言结构的替代

用类来代替enum结构 在要求使用一个枚举类型的环境下,我们首先应该考虑类型安全枚举模式。 // 这是类型安全枚举模式的一个简单实现。public class Suit {private final String name;privat...

7分04秒
2014/05/03
0
0
C语言数据类型和变量的实质

c语言分为: 基本数据类型 整数 整形 -- int 占四个字节 短整型 -- short int 占两个字节 长整形 -- long int 占八个字节 浮点数【实数】 单精度浮点数 -- float 占四个字节 双精度浮点数 --...

天道酬勤VIP
2017/11/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

设计神器 - 摹客设计系统上线了 | 晒出你的设计规范,赢iPad Pro!

在国内,设计规范也许还是个不太常用的概念,但是如果你正好有参与互联网公司的产品设计,你应该早就已经体会到设计规范的重要性了。UI设计师总是要花费大量的时间和精力向开发描述一大堆设计...

mo311
5分钟前
0
0
Thymeleaf 使用过程中的一些记录

Thymeleaf格式化时间: th:value="${#dates.format(gw.regDT,'yyyy-MM-ddHH:mm:ss')}" Thymeleaf select反选: <select id="status" name="status" th:field="${gw.status}" th:value="${gw.......

惊尘大人
8分钟前
0
0
istio源码分析之pilot-discovery模块分析

本文分析的istio代码版本为0.8.0,commit为0cd8d67,commit时间为2018年6月18日。 本文为Service Mesh深度学习系列之一: Service Mesh深度学习系列part1—istio源码分析之pilot-agent模块分...

xiaomin0322
13分钟前
0
0
数据库基本操作:增删改查及联表操作

所用软件:SQL Server Management Studio 首先第一步,建立一个表。在这里命名为T1。并在里面填入几条数据。如图: T1 一.查询 查询所有:select * from T1; 按条件查询:select * from T1 ...

小_橙_子
17分钟前
0
0
Crontab作业时间设置

今天,遇到这么一个题目,周一到周五的9:00-16:59之间,每隔两分钟将某个命令运行一次。给的答案是: */2 9-16 * * 1-5 /usr/sbin/somecommand dosomething 乍一看,这个答案不对,应...

大别阿郎
22分钟前
0
0
ES17-JAVA API文档管理

1.保存文档 可以通过json工具把java对象转换成json字符串进行保存,也可以通过内置的帮助类直接构建json格式 /** * 获取客户端 * * @return */public static TransportClie...

贾峰uk
23分钟前
0
0
Python代码规范和命名规范

前言 Python 学习之旅,先来看看 Python 的代码规范,让自己先有个意识,而且在往后的学习中慢慢养成习惯 一、简明概述 1、编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头...

blackfoxya
25分钟前
0
0
联动滑动之一:NestScrollChild和NestedScrollingParent

NestScrollChild和NestedScrollingParent 吐槽一下开源中国竟然标题字数有限制 由于项目中使用了CoordinateLayout来解决联动以及实现炫酷的UI效果,那么必须就要研究一波源码了,毕竟知其然知...

JerryLin123
43分钟前
1
0
cloudera spark2.2 读写hbase

cloudera spark2.2 读写hbase 例子 host = 'bigdata-03,bigdata-05,bigdata-04'conf = { "hbase.zookeeper.quorum": host, "hbase.mapreduce.inputtable": "student1"}k......

osenlin
47分钟前
0
0
数据库规范化

转载自 一个小时学会MySQL数据库 地址:http://www.cnblogs.com/best/p/6517755.html 截取其中 1.4 部分 用于自己学习使用 感谢作者:张果 1.4、数据库规范化 经过一系列的步骤,我们现在终于...

十万猛虎下画山
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部