难倒高手了,c语言枚举end的作用是什么?

2024-05-18 17:48

本文主要是介绍难倒高手了,c语言枚举end的作用是什么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击上方 “小麦大叔” ,选择 “置顶/星标公众号”

福利干货,第一时间送达

大家好,我是小麦。
我在知乎上看到这个问题,一开始,也有一些疑惑,后面查了一些资料,对于这个问题,简单的说一下我的看法。 bd80aac29d013853f8abc1bc367f350a.png

枚举有多大

枚举类型到底有多大,占多少空间呢?这个要具体情况具体分析,编译器会视情况而定。

下面是我测试用的编译器版本。

gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

当我写下这段代码的时候,实际的输出会是多少呢

7fbb27debe2ec5dfa46af7f53a7bd837.png

有人会说是 1,有人会说是 4,我最终运行的确实是4

2c9288e6558ee15ba7a94db3287ce4f8.png
输出结果

但是这个结果并不是唯一的,它取决于你的编译器,另外还取决于编译器参数,gcc这里有个编译器参数 -fshort-enums,如果我们在编译的时候加上这个,那么编译出来是什么呢?

572fff4729c58f058e363bf7c7a87078.png
短枚举的输出结果

最终结果变成了1

现在我在原先的代码中,加入CMD_MAX_16BIT = 0xFFFF,下面看看输出结果是多少。

716759dee8ad63336a6152706fb41856.png
增带值范围

运行输出结果如下:

8a2597f8297f741772b5aca0b08007f3.png
输出结果

是的,它变成了2。因此我们可以得出结论就是:

编译器将为枚举分配足够的内存大小,来保存我们所声明的任何值。所以,如果我们的代码中只使用低于 256(8位的范围是0~255) 的值,我们的枚举应该是 8 位宽,也就是一个字节,而后面的0xFFFF显然是16位,两个字节,所以最终输出为2

为此我参考了一下gcc user manual,如下;

https ://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fshort-enums

Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type is equivalent to the smallest integer type that has enough room.

Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.

所以,我们需要明确的是编译器是否会默认执行 -fshort-enums这个命令,大多数是不会的,这里我还测试了一些clang,具体结果和gcc相同。

但是在嵌入式编程中需要注意,这里我查了一下,IAR的编译器默认会执行 -fshort-enums

电脑上没有IAR,这里我参考了IAR 的 ARM C 编译器的文档IAR C/C++ Development Guide

13f3fe33d73e30c6bc9a15d5653be3ee.png

可以看到enum类型默认的规定,如果要强制为int类型的话,需要编译的时候提那就--enum_is_int的编译参数,如下所示;

ec37bb59ab3522a1037eb0013b6c2501.png
枚举类型
06c9db05efd26390e843e84f9297f7ad.png

所以这里为了避免编译器的优化,以及不同的硬件平台和不同编译器,从而导致枚举分配内存空间的变化,所以上述增加了一个0xFFFFFFFF,强制编译器为枚举分配4个字节的空间。

0816c432d1231107e45894eee91bb85e.png
设置最大范围为4字节

最终的输出结果都是4,如下图所示;

c1605db8698a1c29e977007d92cd8603.png
输出结果比较

看来虽然是一个很小的知识点,但是这中间的坑还真不少,好了,本期的文章就到这里了,我们下期再见。

如果感觉文章帮到了您,动手三连,让文章帮到更多的人。

—— The End ——

往期推荐

30个单片机常见问题解决办法!一般人我不告诉他们

马斯克的脑机接口,一块树莓派就能做出来?

高手常用的3个开源库,让单片机开发事半功倍

看似简单的代码,却暗藏玄机...

如何防止破解?MCU加密技术揭秘

加入嵌入式技术交流群一起进步

点击名片关注我

70beace7ff1770c7deecc3c9f4dd32da.png

你点的每个好看,我都认真当成了喜欢

这篇关于难倒高手了,c语言枚举end的作用是什么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995611

相关文章

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Kotlin 枚举类使用举例

《Kotlin枚举类使用举例》枚举类(EnumClasses)是Kotlin中用于定义固定集合值的特殊类,它表示一组命名的常量,每个枚举常量都是该类的单例实例,接下来通过本文给大家介绍Kotl... 目录一、编程枚举类核心概念二、基础语法与特性1. 基本定义2. 带参数的枚举3. 实现接口4. 内置属性三、

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

Go语言网络故障诊断与调试技巧

《Go语言网络故障诊断与调试技巧》在分布式系统和微服务架构的浪潮中,网络编程成为系统性能和可靠性的核心支柱,从高并发的API服务到实时通信应用,网络的稳定性直接影响用户体验,本文面向熟悉Go基本语法和... 目录1. 引言2. Go 语言网络编程的优势与特色2.1 简洁高效的标准库2.2 强大的并发模型2.

C#之枚举类型与随机数详解

《C#之枚举类型与随机数详解》文章讲解了枚举类型的定义与使用方法,包括在main外部声明枚举,用于表示游戏状态和周几状态,枚举值默认从0开始递增,也可手动设置初始值以生成随机数... 目录枚举类型1.定义枚举类型(main外)2.使用生成随机数总结枚举类型1.定义枚举类型(main外)enum 类型名字

Go语言使用sync.Mutex实现资源加锁

《Go语言使用sync.Mutex实现资源加锁》数据共享是一把双刃剑,Go语言为我们提供了sync.Mutex,一种最基础也是最常用的加锁方式,用于保证在任意时刻只有一个goroutine能访问共享... 目录一、什么是 Mutex二、为什么需要加锁三、实战案例:并发安全的计数器1. 未加锁示例(存在竞态)

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1