在 C 中为内存定义枚举的数据类型
Define data type of enum in C for memory
我找不到对此的直接答案,但是否可以在 C 中为 enum
强制使用某种数据类型?
例如,我有一个 enum
用于状态机,它只会保存一些状态,因此对于内存和性能问题,最好将 enum
定义为一个字节或一个较短的数据类型。有没有办法在 C 甚至 Arduino IDE 中提供这种行为?
感谢任何帮助
枚举不是 "stored",因为变量使用内存位置。枚举用于语句中。这些语句被编译并在编译结果(机器代码、汇编器)中,枚举被替换为它们的值。例如,名为 MY_ENUM1
且值为 1
的枚举常量将在汇编程序中替换为
mov ax, 1
因此,它们将占用指令操作数所需的最小内存量。
C标准说枚举常量,也就是enum的"members",必须兼容类型int
。但是枚举变量本身是允许其他整数类型的。如果您认为这没有任何意义,那是因为它没有:C 标准在枚举方面是不合理的。
至于如何选择枚举变量对应的整数类型,很遗憾,这是由编译器决定的,而不是由程序员决定的。在 8 位 Atmel 上,枚举变量是 8 位或 16 位。
一些编译器提供了通过非标准编译器选项设置枚举大小的选项。无论如何,使用这些功能可能不是一个好主意,因为这会使代码不可移植。
但是,无论枚举的大小如何,编译器都可以(并且很可能会)优化存在枚举的表达式,就像它可以优化任何包含小整数类型的表达式以不使用 int
用于计算,因为 C 标准另外要求通过整数提升。
如果您有非常极端的性能要求,请不要使用枚举,而是 uint8_t
。但是,如果您有极端的性能要求,那么您首先就不会使用业余爱好者 8 位 MCU!原来你的担心不是问题。
继续使用枚举,让编译器担心优化。
如前所述,枚举常量基本上是整型常量。他们自己不带 space,他们没有在可执行代码的某处列出。
但是,如果您使用枚举类型来定义变量,那么该变量可能与 int 变量一样多 space。如果你需要保存这个 space 你可以使用任何其他能够存储必要范围的整数类型。例如,而不是:
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 中枚举的主要价值似乎是更具描述性的代码,大概更易于阅读和维护。与使用一堆#define 语句相比,使用枚举似乎没有任何真正的好处。即使声明了枚举颜色类型的变量,比如 my_hue,编译器,至少 gcc,如果您将 'invalid' 值(-100 或 +100)分配给 [=13=,则不会显示错误].作为一个不良的副作用,您让编译器选择了不能在完全合理的循环中工作的变量类型。
我找不到对此的直接答案,但是否可以在 C 中为 enum
强制使用某种数据类型?
例如,我有一个 enum
用于状态机,它只会保存一些状态,因此对于内存和性能问题,最好将 enum
定义为一个字节或一个较短的数据类型。有没有办法在 C 甚至 Arduino IDE 中提供这种行为?
感谢任何帮助
枚举不是 "stored",因为变量使用内存位置。枚举用于语句中。这些语句被编译并在编译结果(机器代码、汇编器)中,枚举被替换为它们的值。例如,名为 MY_ENUM1
且值为 1
的枚举常量将在汇编程序中替换为
mov ax, 1
因此,它们将占用指令操作数所需的最小内存量。
C标准说枚举常量,也就是enum的"members",必须兼容类型int
。但是枚举变量本身是允许其他整数类型的。如果您认为这没有任何意义,那是因为它没有:C 标准在枚举方面是不合理的。
至于如何选择枚举变量对应的整数类型,很遗憾,这是由编译器决定的,而不是由程序员决定的。在 8 位 Atmel 上,枚举变量是 8 位或 16 位。
一些编译器提供了通过非标准编译器选项设置枚举大小的选项。无论如何,使用这些功能可能不是一个好主意,因为这会使代码不可移植。
但是,无论枚举的大小如何,编译器都可以(并且很可能会)优化存在枚举的表达式,就像它可以优化任何包含小整数类型的表达式以不使用 int
用于计算,因为 C 标准另外要求通过整数提升。
如果您有非常极端的性能要求,请不要使用枚举,而是 uint8_t
。但是,如果您有极端的性能要求,那么您首先就不会使用业余爱好者 8 位 MCU!原来你的担心不是问题。
继续使用枚举,让编译器担心优化。
如前所述,枚举常量基本上是整型常量。他们自己不带 space,他们没有在可执行代码的某处列出。
但是,如果您使用枚举类型来定义变量,那么该变量可能与 int 变量一样多 space。如果你需要保存这个 space 你可以使用任何其他能够存储必要范围的整数类型。例如,而不是:
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 中枚举的主要价值似乎是更具描述性的代码,大概更易于阅读和维护。与使用一堆#define 语句相比,使用枚举似乎没有任何真正的好处。即使声明了枚举颜色类型的变量,比如 my_hue,编译器,至少 gcc,如果您将 'invalid' 值(-100 或 +100)分配给 [=13=,则不会显示错误].作为一个不良的副作用,您让编译器选择了不能在完全合理的循环中工作的变量类型。