我正在使用具有32K内存的嵌入式设备,使用IAR EWARM v6.30以纯C语言编写。
为了使代码更具可读性,我想定义一些枚举类型,例如
{RIGHT_BUTTON, CENTER_BUTTON, LEFT_BUTTON}
而不是使用0,1,2值,但我担心它会占用额外的内存,而且已经很少了。
所以我有两个问题: 1)我可以强制枚举为int的短或字节类型inte? 2)定义枚举类型的确切记忆印记是什么?
答案 0 :(得分:6)
在完全符合ISO C的情况下,枚举常量的大小和类型是signed int
的大小和类型。一些嵌入式系统编译器故意不将其作为优化或扩展。
在ISO C ++中“枚举的基础类型是一个整数类型,它可以表示枚举中定义的所有枚举器值。”,因此编译器可以自由使用尽可能小的类型,大多数人都这样做,但没有义务这样做。
在您的情况下(IAR EWARM),手册明确指出:
无需任何选项,实际上您需要使用--enum_is_int
强制执行合规行为。其他编译器可能表现不同或具有不同的扩展,编译指示或选项来控制它。这些事情通常会在文档中定义。
答案 1 :(得分:2)
如果您确实需要将数据大小保持在char
,那么您始终可以使用一组#define
常量值来表示enum
个状态,并且只能使用这些值在你的作业和考试中。
答案 2 :(得分:2)
对于符合标准的编译器,枚举常量始终为int
类型(等效于signed int
)。但是这些常量通常不会存储在内存中,因此它们的类型可能不会对内存需求产生太大影响。
枚举类型的声明对象本身是枚举类型,它与char
或某些有符号或无符号整数类型兼容。类型的选择是实现定义的(即,编译器可以选择,但它必须记录它如何做出选择);唯一的要求是类型必须能够存储所有常量的值。
奇怪的是,常量是int
类型而不是枚举类型,但这就是语言的定义方式(原因是历史的,C ++有不同的规则)。
例如,给定:
enum foo { x, y, z };
enum foo obj;
obj = z;
表达式z
的类型为int
,其值为2(就像十进制常量2
),但对象obj
的类型为{{1}并且可能小到一个字节,具体取决于编译器。作业enum foo
涉及从obj = z;
到int
的隐式转换(转换可能需要也可能不需要其他代码)。
某些编译器可能会提供一些非标准方法来指定要为枚举类型选择的类型。有些甚至可能以某种方式违反标准。查阅编译器的文档,打印出enum foo
的值,并在必要时检查生成的代码。
您的编译器可能会在语言强加的约束内做出合理的决定。对于针对内存不足的嵌入式系统的编译器,编译器特别可能选择小型,或者让您指定一个。请参阅编译器的文档。
正如Ian的回答所示,如果您想自己控制内存使用,可以使用sizeof (enum foo)
或char
个对象。但是,您仍然可以使用unsigned char
定义来定义常量。例如:
enum
参考:C standard的第6.7.2.2节。该链接是2011年ISO C标准最新草案的1.7兆字节PDF;这个特殊的部分自1989年以来没有发生重大变化。
答案 3 :(得分:1)
ANSI C编译器始终将枚举表示为int
来表示enum
类型的变量。
http://en.wikipedia.org/wiki/Enumerated_type#C_and_syntactically_similar_languages
在程序中使用int
的一个选项是使用它们来定义值,但在实际使用时转换为char
char value = (char)Buttons.RIGHT_BUTTON;