在C语言中为内存定义枚举数据类型

3
我找不到一个直接的答案,但是在C语言中是否有可能强制指定enum的某种数据类型?例如,我有一个状态机的enum,它只会保留一些状态,所以为了内存和性能问题,定义一个enum为字节或更短的数据类型将是很好的选择。在C语言甚至Arduino IDE中是否有提供这种行为的方法?任何帮助都将不胜感激。

2
枚举本身实际上只是编译时整数常量。无论你有多少个,枚举本身在运行时都不会占用任何空间。 - Some programmer dude
2
你需要多少个状态变量?就像我所说的,枚举的数量并不重要,因此如果您只有一个状态变量,则在具有32位int的平台上,它将占用所有空间。无论您有1个还是10000个状态枚举,都不重要,它仍然只是一个单一的int。也许您应该考虑设计以在其他地方节省空间? - Some programmer dude
1
你是指生成的代码太大,无法存储在FLASH内存中吗?因此,您需要优化代码大小吗?还是只是一个简单的过早优化问题? - Some programmer dude
2
如果这是原始的Atmel AVR Arduino,int不会是32位。 - Lundin
2
Arduino IDE 使用 C++,在最近几个版本中也使用了 C++11 标准(我不确定确切的版本,但应该是从版本 1.6.8 开始)。因此可以定义具有其基础类型的枚举:enum Something : uint8_t { ... };。更多信息:Enumeration declaration - KIIV
显示剩余9条评论
4个回答

6
C标准规定,枚举常量即枚举类型的“成员”必须与类型int兼容。但是,枚举变量本身可以是其他整数类型。如果你认为这没有任何意义,那是因为确实如此:在枚举方面,C标准是不合理的。
至于如何选择枚举变量对应的整数类型,不幸的是,这是由编译器而不是程序员决定的。在8位Atmel上,枚举变量要么是8位,要么是16位。
一些编译器提供了通过非标准编译器选项设置枚举大小的选项。无论如何使用这些功能可能都不是一个好主意,因为这会使代码不可移植。
然而,无论枚举的大小如何,编译器都可以(并很可能)优化包含枚举的表达式,就像它可以优化任何包含小整数类型的表达式一样,以避免使用int进行计算,因为这是C标准通过整数提升所规定的。
如果您有非常极端的性能要求,请不要使用枚举,而是使用uint8_t。但是,如果您真的有极端的性能要求,那么首先您不会使用业余爱好者的8位MCU!所以你不用担心这个问题。
放心使用枚举,并让编译器担心优化。

为什么即使在业余爱好的微控制器上追求最佳性能也不会成为一个问题?我认为无论情况如何,人们都应该尽力创造最优秀、最节省内存的代码。 - Kev1n91
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Lundin
1
最后,你的程序有实时要求:它要么足够快,要么不够快。从“足够快”到“更快”并没有增加任何价值。这就是为什么在考虑手动优化之前,应该始终对编译器优化的代码进行基准测试的原因。 - Lundin

5
如前所述,枚举常量基本上是整数常量。它们不占用自身空间,也不在可执行代码中列出。
然而,如果您使用枚举类型定义变量,则该变量可能占用与int变量一样多的空间。如果需要节省此空间,则可以使用任何其他能够存储所需范围的整数类型。例如,可以使用以下方法代替:
enum state {S1, S2, S3, S4};

enum state stack[1000];
...
stack[i] = S2;
... 

您可以编写:

enum state {S1, S2, S3, S4};
typedef unsigned char my_state_type;

my_state_type stack[1000];
...
stack[i] = S2;
...

不幸的是,C语言不允许我们声明一个既是我们想要的整数类型,又限制在枚举值范围内的变量。stack[i]= 5 将会被标记。 - Paul Ogilvie

2

枚举类型并不像变量一样占用内存空间存储。枚举类型主要用于语句中,这些语句在编译后(机器码、汇编代码),枚举类型会被替换成其对应的值。例如,一个名为MY_ENUM1且值为1的枚举常量,在汇编代码中会被替换成:

    mov ax, 1

因此,它们将占用所需指令操作数最小的内存空间。

1
拿着代码 enum myEnum {e1, e2}; struct s {myEnum e;}; int main(int, char *[]){ printf("%d", sizeof(s)); } 我得到了4,这与你的答案相矛盾。 - Colin
1
@Colin-s,在你的例子中,枚举被用在一个结构体中,因此需要为变量占用存储空间。然后它被转换成整数。 - Paul Ogilvie

0

在C语言中,枚举类型的主要价值似乎在于更具描述性的代码,这样做可能更容易阅读和维护。与使用一堆#define语句相比,使用枚举并没有任何真正的好处。即使声明一个类型为enum color的变量,例如my_hue,编译器(至少是gcc)也不会显示错误,如果你将一个“无效”的值(-100或+100)赋给my_hue。而且作为一个不良的副作用,编译器会选择在完全合理的循环中不起作用的变量类型。


3
这并没有以任何方式回答原来的问题。OP的问题是关于数据类型、内存和性能的,假定是在极度受限的嵌入式设备环境下。你的回答与这个问题毫无关系。 - TomServo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接