enum in c language

今天说说C语言中的枚举。

参考:Enumeration (or enum) in C

1 定义

定义一个枚举类型很容易:

enum aa { a1, a2, a3 };

这里

  • enum是关键字
  • aa是枚举变量,也就是我们自定义类型
  • a1,a2,a3是枚举成员

然后怎么使用呢?

首先,它就像结构体struct和联合体union那样,是一个自定义的数据类型,用它定义变量,也是一样的:

enum aa abc; 	// 定义变量
enum aa *en_p; 	// 定义指针

是的,它跟基本数据类型以及结构体等特殊数据类型一样,都可以定义变量和定义指针

所以,和int一样,如果仅仅定义,而没有赋值和使用,编译后它就没了,变量定义本身不占地方,赋值了才占地方。

另外,和struct一样,它只是一个结构,这个结构是C语言层级的声明,编译后不存在这个结构的,汇编层级没有的。

所以,下面我们先说说,变量的赋值

2 变量的赋值

枚举类型的赋值其实是比较复杂的,先说最常用的。

2.1 默认值

enum aa { a1, a2, a3 };

对于上述枚举类型,它的a1 a2 a3, 在默认情况下,会被赋值为

a1 = 0;
a2 = 1;
a3 = 2;

2.2 赋初值

enum aa { a1 = 1, a2 = 3, a3 = 5 };

可以对其任意赋初值,这样,三个枚举成员的值就对应了你指定的值了。

我们看看多种情况:

情况1:全都赋初值

enum aa { a1 = 1, a2 = 3, a3 = 5 };

情况2:有重复的初值

这种情况的完全可以的。

enum aa { a1 = 1, a2 = 1, a3 = 5 };

情况3:部分赋初值,部分不赋值

enum aa { a1 = 1, a2, a3 };

对于此时,a2 = 2 a3 = 3,也就是说,后面没有赋值的,是默认根据前面赋值的累加的

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };

那这种情况呢?

  • 根据a1累加:a2 = 2 a3 = 3 a4 = 4
  • 根据a4累加:a5 = 11 a6 = 12

赋值范围

与int类型赋值范围一样!赋值-1什么的也可以,与int类型的范围一样的。

2.3 变量赋值

其实就是定义一个变量,然后给它赋值,这里不一样的是,枚举成员本身,就代表值

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };
enum aa abc = a2;

这个时候,abc = 2a2就代表数值2.

从其他角度理解,enum aa abc = a2;的含义就是

int a2 = 2;
int abc = a2;

就是这么个意思。

2.4 指针赋值

enum aa abc = a2;  
enum aa *enu_p = &abc;
printf("%d\n", *enu_p);		

没啥好说的,跟基本数据类型指针待遇一样的。

3 谈谈枚举成员

3.1 作用范围

首先,结构体本身

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };

它的作用范围,跟struct一样,跟int也一样,{ } 里面就是局部变量,在最外面就是全局变量,对于aa这个自定义类型标识符,也是一样的,不多说了。

比较需要注意的是,枚举成员也是标识符

3.2 枚举成员也是标识符

我们上面的例子,a1,a2,a6这些,在其作用域内,也是标识符,也就是相当于你定义了一个int a1;一样,在作用域内不能重复定义了!并且,这个标识符本身代表了一个int值。

int main(){enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };int a1; // error!重定义了!上面定义过a1了!enum bb {a2,a4}; // error!
}

4 enum与int

enum中的枚举成员,都是int类型的变量,也代表int类型的值,值的范围也是int的范围。

5 enum与#define

5.1 共同点

下面两段代码基本来说是等价的:

#define Working 0
#define Failed 1
#define Freezed 2
enum state  {Working, Failed, Freezed};

5.2 enum的优势

#define是全局的,而enum则是与基本数据类型一样,范围非常灵活。

5.3 #define的优势

enum只能定义int类型值,define什么都可以等价,任何值,以及函数,都可以。

6 enum的大小(size)

6.1 变量的大小

注意:讨论enum结构本身大小没必要,因为其变量,就是这个结构的实例化,这一点和struct一样的!

enum aa { a1 = 10, a2, a3 };
enum aa abc = a2;
printf("size = %d\n", sizeof(enum aa)); // 4 
printf("size = %d\n", sizeof(abc));		// 4

试一下就知到了,都是4字节。这俩肯定相等,一个是模板,一个是实例

为什么是4呢?

因为enum这里面的值,其实就是int类型的,那不就是4吗!然后这个枚举变量,值只能有一个吧,那就占一个4字节空间足够了。

像struct那是可以有多个值,所以每个变量都占空间,这个就没必要,一堆里面选一个就可以了。

另外就是,不要试图获取枚举成员的地址,因为它有没有用上场都不一定呢,它只是C语言层级的一个值而已,不一定被分配

在这里插入图片描述

好吧,没人这么闲的没事干。

7 奇奇怪怪

enum aa abc = 100;
printf("***%d\n", abc); // 100

这种情况下,就真的当int用了,其实也没啥,反正编译器允许,不过一般没人这么干。

8 最后,说说真正常用的地方

说实话,说了这么多,基本都很少用得到!常用的地方也就固定套路,内些野路子你看看就好。

就比如你定义个月份什么,星期什么的。

#include<stdio.h>enum year{Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};int main()
{int i;for (i=Jan; i<=Dec; i++)      printf("%d ", i);return 0;
}

另外还有就是,编译原理中的,词法分析器的单词表,需要把编号和名称对应起来,enum是天然适合的结构,使用struct嵌套enum和其他,就很完美很方便。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信号量SIGCHLD的使用,如何让父进程得知子进程执行结束,如何让父进程区分多个子进程的结束

本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常编译和执行&#xff0c;说明您系统和工具版本与我的不匹配&#xff0c;请自行查阅资料。 0 概述 先给出该信号的描述&#xff1a; SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent …

UNIX哲学

参考&#xff1a; 对比Linux与Windows 使用Linux想要做某些事情的时候&#xff0c;就拆开想&#xff0c;想想我需要哪些功能&#xff0c;需要哪些工具&#xff0c;依次怎么执行&#xff0c;然后用管道建立连接&#xff0c;让数据依次流过不同的工具&#xff0c;从而得到最终结果…

fork创建多个子进程

references: [1] how to create two processes from a single Parent [2] fork() in C [3] linux中fork同时创建多个子进程的方法 fork的本质&#xff0c;就是复制&#xff0c;把当前进程复制一份&#xff0c;然后两个进程并发地执行fork后面的语句&#xff0c;区别就是&#x…

wait系统调用

reference:Wait System Call in C 只强调几点&#xff0c;剩下的直接看参考链接内容就好了&#xff0c;不是偷懒&#xff0c;而是里面内容写的很好了&#xff0c;没必要再写一遍了&#xff0c;这种东西就是单纯的系统调用而已&#xff0c;理解了功能&#xff0c;就完事了&#…

正则表达式特别需要注意的点:“空“字符的匹配

在正则表达式中&#xff0c;[...]代表1个字符&#xff0c;不管里面有多少字符&#xff0c;最终这个东西的结果都是1个字符。 对于表达式[^a]表达的匹配除了a之外的字符&#xff0c;并且是1个字符。 需要注意的是&#xff0c;有些特殊字符是不会被匹配的。 我们看一个示例&am…

vim多列操作--插入/删除

插入 How to insert text at beginning of a multi-line selection in vi/VimVim Commands 删除 ctrl v使用上下左右键选中一片区域按d删除

vim进行行内某部分的复制剪切粘贴

ctrl v使用方向键选中你要复制的部分 按d&#xff08;剪切&#xff09;或者按y&#xff08;复制&#xff09;再移动到你的目标位置&#xff0c;按p粘贴&#xff08;在正常模式下才行&#xff0c;如果不是&#xff0c;先按esc&#xff09; 这个过程与你操作word文档的复制粘贴…

函数调用堆栈

基于孟宁老师的Linux内核分析 1 int g(int x){ 2 int y x 3;3 return y;4 }5 6 int f(int x){7 int z x 10;8 return g(z);9 }10 11 int main(){12 int a f(8) 1;13 return 0;14…

Vivado提高综合和实现的速度

让计算机的资源尽可能给vivado&#xff0c;综合、实现的时候修改一个参数 jobs改为你的计算机的最大值&#xff0c;我的计算机是12核的。 速度会快很多&#xff01;

安装Ubuntu RISC V toolchain失败(网速、git配置原因)

git获取大容量工程出错&#xff1a;RPC failed&#xff1b; curl GnuTLS recv error : Decryption has failed. error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.fatal: The remote end 官方GitHub仓库 gitee镜像仓库 如果网速不够&#xff0…

VirtualBox Ubuntu个人配置

注意这里VT-x启用&#xff0c;除了在BIOS启用CPU虚拟化&#xff0c;还得在命令行设置一次才可以勾选。 F:\>cd F:\VirtualBox # 进入VirtualBox安装目录F:\VirtualBox>VBoxManage.exe list vms # 查找所有虚拟机 "rhel64" {240f96d8-6535-431d-892e-b70f3dc4…

Ubuntu停止维护版本的软件源配置和系统升级方法

这里以Ubuntu 20.10版本为例&#xff08;当前是2022.2.14&#xff0c;该版本已经停止维护&#xff09;&#xff0c;我们现在需要正常使用该版本&#xff0c;并且期待升级到21.10版本&#xff0c;我们需要 配置正确是软件源升级该版本 配置正确的软件源 配置国内镜像源 我们…

diff and colordiff on Ubuntu

在Ubuntu中使用diff来对比文件差异&#xff0c;但是不是很好用&#xff0c;尤其是着色方面&#xff0c;用起来很麻烦&#xff0c;因此可以安装colordiff。 我们有两个文件file1和file2&#xff0c;使用命令 colordiff file1 file2 -y -B -W 140就可以对比文件差异&#xff0c…

帮助你成为高手的视频和资料

1. 为什么大多数人不会真正成功 博客链接 视频链接 2. TED演讲&#xff1a;真正拉开你与周围人之家差距的&#xff0c;是自学能力 视频链接 3 埃隆马斯克&#xff1a;第一性原理&#xff0c;少用类比&#xff0c;类比多了就不能抓住本质了 4 如何成为一个顶尖高手 文章链…

【数据结构】快速排序非递归算法及其改进

在学数据结构中排序这一章节的时候&#xff0c;有一道有关快速排序的作业题描述如下&#xff1a; 按下述要求编写快速排序的非递归算法&#xff1a; 定义一个栈&#xff08;或队列&#xff09;&#xff0c;把整个序列的上、下界入栈&#xff08;或队列&#xff09;。当栈&#…

【数据结构】对快速排序原理的理解(图解,通俗易懂)

学习数据结构时&#xff0c;书本上直接给出了快速排序的过程以及代码&#xff0c;对其原理解释的不够详细&#xff0c;琢磨代码后&#xff0c;发现其原理其实十分简单&#xff0c;简述如下&#xff1a; &#xff08;1&#xff09;在待排序列中找一个“中枢元素”&#xff08;书…

【离散数学】图论基础知识

文章目录1 图的基本概念2 图的连通性3 图的矩阵表示4 几种特殊的图4.1 二部图4.2 欧拉图4.3 哈密顿图4.4 平面图5 无向树6 生成树1 图的基本概念 无向图&#xff1a; 简而言之&#xff0c;边不带方向的图就是无向图。 有向图&#xff1a; 简而言之&#xff0c;边带方向的图就…

【运筹与优化】单纯形法解线性规划问题(matlab实现)

文章目录单纯形法步骤&#xff1a;1.将线性规划问题化为标准形式2.列出单纯形表3.进行最优性检验4.从一个基可行解转换到另一个目标值更大的基可行解&#xff0c;列出新的单纯形表5.重复3、4直到计算结束为止举例单纯形法matlab实现单纯形法是一种解线性规划问题的算法&#xf…

【Linux系统编程学习】 GCC编译器

此为牛客网Linux C课程1.2&1.3的课程笔记。 0. 简介 1. gcc和g的安装 sudo apt install gcc g2. gcc常用参数选项 3. gcc工作流程 首先是预处理器对源代码进行预处理&#xff08;后缀名.i&#xff09;&#xff0c;主要做以下事情&#xff1a; 把头文件加入到源代码当中删…

Spring5底层原理之BeanFactory与ApplicationContext

目录 BeanFactory与ApplicationContext BeanFactory ApplicationContext 容器实现 BeanFactory实现 ApplicationContext实现 ClassPathXmlApplicationContext的实现 AnnotationConfigApplicationContext的实现 AnnotationConfigServletWebServerApplicationContext的实…