enum

enum是C语言中的一个关键字,enum叫枚举数据类型,枚举数据类型描述的是一组整型值的集合(这句话其实不太妥当),枚举型是预处理指令#define的替代,枚举和宏其实非常类似,宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值,

我们可以将枚举理解为编译阶段的宏,使用格式:

enum typeName{ valueName1, valueName2, valueName3, ...... };

typeName枚举类型的名字,花括号里面的元素(枚举成员)是常量而不是变量,这个一定要搞清楚,因为枚举成员的是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量

枚举类型(枚举标签)、枚举成员(枚举常量)、枚举变量之间的区别

当枚举类型和枚举变量放在一起定义时,枚举类型的名字(就是enum week中的week)可以省略不写,意思是上图的有两种写法

第一种:

enum week{Mon = , Tues, Wed, Thurs}num;

第二种:

enum {Mon = , Tues, Wed, Thurs}num;

这一点其实和结构体中的无名结构很相似,虽然定义枚举类型变量和定义结构类型变量看起来很相似,但是两者的区别还是蛮大的,一个结构体类型变量里面包含若干个成员,相当于一个打包好的快递盒子,

而枚举类型变量就不一样了,枚举类型变量不是一个包含若干个成员的集合,枚举类型变量和int、char类型的变量其实差不多,只不过枚举类型变量的赋值只能用自身的枚举成员来赋值,以上面的例子来说,

num的赋值就只能用枚举成员Mon、Tues、Wed、Thurs,而不能用其他枚举类型的枚举成员来赋值

定义枚举变量和定义结构体变量相同,有两种定义方法

第一种:(定义枚举类型的同时定义枚举变量)

enum week{Mon = , Tues, Wed, Thurs}num;

第二种:(先定义枚举类型,再定义枚举变量)

enum week{Mon = , Tues, Wed, Thurs};
enum week num;

枚举类型的特点

下面将用不同的示例来说明枚举类型的特点

示例一:(不显式说明枚举常量的值)

enum week{Mon, Tues, Wed, Thurs, Fri, Sat, Sun};

在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1,所以Mon=0,Tues=1,····Sun=6,下面来验证一下

enum week{Mon, Tues, Wed, Thurs, Fri, Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);

运行结果:

示例二:(显示说明部分枚举常量的值)

enum week{Mon = , Tues, Wed, Thurs, Fri, Sat, Sun};

上面的代码中,只显式说明了枚举常量Mon的值为1,未指定的枚举名的值将依着最后一个指定值向后依次递增(注意是最后一个指定值)

enum week{Mon = , Tues, Wed, Thurs, Fri, Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);

运行结果:

对上面的代码稍加修改

enum week{Mon = , Tues, Wed, Thurs, Fri = , Sat, Sun};
printf("Mon=%d\nTues=%d\nWed=%d\nThurs=%d\nFri=%d\nSat=%d\nSun=%d\n", Mon, Tues, Wed, Thurs, Fri, Sat, Sun);

运行结果:

示例三:(对枚举变量进行赋值)

enum week{Mon = , Tues, Wed, Thurs}num;

num = (enum week);
printf("%d", num);

一个整数不能直接赋值给一个枚举变量,必须用该枚举变量所属的枚举类型进行类型强制转换后才能赋值,上面的代码中,在对枚举变量赋值10的时候进行的强制类型转换,将整型常量10转换成了enum week类型再赋值给num变量,

运行结果:

总结:

1、在没有显示说明的情况下,枚举常量(也就是花括号中的常量名)默认第一个枚举常量的值为0,往后每个枚举常量依次递增1

2、在部分显示说明的情况下,未指定的枚举名的值将依着之前最有一个指定值向后依次递增

3、一个整数不能直接赋值给一个枚举变量,必须用该枚举变量所属的枚举类型进行类型强制转换后才能赋值

4、同一枚举类型中不同的枚举成员可以具有相同的值

5、同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员(枚举常量)

enum与typedef配合使用

typedef enum week my;

或者

typedef enum week{Mon = , Tues, Wed, Thurs}my;

上面typedef也可以省略week

typedef enum{Mon = , Tues, Wed, Thurs}my;

上面两种形式中,my都是enum week的别名(意思是my和enum week等价),需要注意的是如果将第二句的typedef去掉那么my就变成了enum week类型的变量,如果加上typedef那么my就是enum的别名,这点要注意区分

在定义了enum week的别名my后,后面就可以使用my来定义枚举类型变量

my num;

num = (enum week);
printf("%d", num);

上述语句中的(enum week),可以改为(my),两者效果是一样的

补充:对上面总结的第五点:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的枚举成员(枚举常量)进行验证

enum m1{m1, m2};
enum m2{m3, m4};
enum m1{m5, m6};

上述代码定义的枚举类型enum m1多次定义,是不允许的,编译器会报错还有一种特殊情况,即使定义了同名的枚举类型,编译器也不会报错

enum m1{m1, m2};
enum m2{m3, m4};
enum m1;

上面的代码中,第二个enum m1没有定义枚举成员,在编译阶段是不会报错的(估计是编译器并不认为定义了枚举成员的enum m1 和 没有定义枚举成员的enum m1是同名的枚举类型

enum的赋值范围

这个也是无意间注意到的,文章在开头提到枚举类型描述的是一组整型值的集合,枚举类型的占的字节数是4个字节,所以我们可以用INT_MAX和INT_MIN来测试枚举类型的赋值范围,赋值的最大值应该是INT_MAX(也就是2147483647),下面用代码来测试一下

enum test{m1=INT_MAX};
printf("%d\n%d\n", m1, INT_MAX);

运行结果:

上面的代码没有问题,下面来测试一下越界的赋值

enum test{m1=INT_MAX+};
printf("%d\n%d\n", m1, INT_MAX);

编译器在编译阶段会有警告,测试了枚举类型的最大值,下面来测试下枚举类型的最小值

enum test{m1=INT_MIN};
printf("%d\n%d\n", m1, INT_MIN);

运行结果:

上面的代码没有问题,下面来测试一下越界的赋值

enum test{m1=INT_MIN-};
printf("%d\n%d\n", m1, INT_MIN);

和上面相同,编译器也会有警告

为什么“枚举类型描述的是一组整型值的集合”其实不太妥当?

上面这句话很容易让读者以为enum类型和int类型是等价的,好像可以把int型的数据直接赋值给enum变量,实际上是不行的,需要进行强制类型转换,C语言提供了一种称为“枚举”的类型,其中一个枚举常量的占的字节数为4个字节,恰好和int类型的变量占的字节数相同,假设把这些枚举常量说明为整型,字符型或其他类型显然是不妥当的,因为枚举类型是一种基本数据类型,而不是一种构造类型,它不能再分解为什么基本类型

枚举类型enum详解——C语言的更多相关文章

  1. Java 枚举(enum) 详解7种常见的用法

    Java 枚举(enum) 详解7种常见的用法 来源 https://blog.csdn.net/qq_27093465/article/details/52180865 JDK1.5引入了新的类型— ...

  2. 详解 Go 语言中的 time.Duration 类型

    swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...

  3. Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  4. 详解go语言的array和slice 【二】

    上一篇已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制sl ...

  5. JS类型转换规则详解

    JS类型转换规则详解 一.总结 一句话总结:JS强制类型转换中的类型名强制类型转换和其它语言不同,是类型类的构造方法,Number(mix) 一句话总结(JS类型本质):因为js是弱类型语言,所以它相 ...

  6. 详解Go语言调度循环源码实现

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...

  7. Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  8. 【转】java枚举类型enum的使用

    原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...

  9. C# 中的枚举类型 enum (属于值类型)

    原文 C# 中的枚举类型 enum (属于值类型) C# 支持两种特殊的值类型:枚举和结构. 声明枚举:声明时要声明所有可能的值. using System; using System.Collect ...

随机推荐

  1. 离线部署 pm2 管理node程序

    在服务器不能联网的情况下: 在可以联网的机器上: npm install pm2 -g 全局安装pm2: 然后查看一下本地安装的默认路径: npm config get prefix, 在其  lib ...

  2. push() 方法将一个或多个元素添加到数组的末尾,并返回新数组的长度

    var numbers = [1, 2, 3]; numbers.push(4); console.log(numbers); // [1, 2, 3, 4] numbers.push(5, 6, 7 ...

  3. Beta冲刺——第四天

    beat冲刺:第四天 各个成员今日完成的任务 成员 冯晓.马思远 彭辉.王爽 吴琼.郝延婷 今日完成任务 ·管理员功能模块的代码规范与测试 ·后台审稿系统代码规范 ·代码规范 ·系统审稿模块功能测试 ...

  4. cdn是否缓存了网站内容,如何查看

    查看网站是否缓存,本例以cdnbest的节点程序,浏览器是firefox为例 打开浏览器后按 F12键,再打开网站,如下图显示 HIT就表示有缓存,没有缓存就会显示MISS

  5. Pandas分组

    GroupBy技术 分组运算的过程可以用下面的流程图表示出来 import pandas as pd from pandas import Series import numpy as np df = ...

  6. 【VBA】セールの値は配列に変換方法

    方法一 Sub test1() //変数の定義 Dim a() As Integer, iRow As Long, i As Integer //非空白のセールまでの行を取得 iRow = Cells ...

  7. 一 分析easyswoole源码(启动服务)

    分析easyswoole源码 1以启动为例 //检查是否已经安装 installCheck();//检查锁文件是否存在,不存在结束 //启动服务 serverStart showLogo();//显示 ...

  8. jsp相关笔记(一)

    1.在html中调整两个<p>标签之间的间距,可以用margin属性: p { margin: 0.2em 0;} 2.在jsp中要对页面分成上.左.右三栏时,可以用<framese ...

  9. tomcat源码分析-初始化过程

    digester 说明: https://www.cnblogs.com/devilwind/p/8192304.html

  10. mysql的innodb和myisam的区别和应用场景

    1. 区别: (1)事务处理: MyISAM是非事务安全型的,而InnoDB是事务安全型的(支持事务处理等高级处理): (2)锁机制不同: MyISAM是表级锁,而InnoDB是行级锁: (3)sel ...