我必须存储我将通过串行接收的指令和命令。 命令长度为8位。
我需要保持命令名称及其值之间的透明度。 这样可以避免将串行接收的8位数转换成任何类型。
我想在我的代码中使用Enumerations来处理它们。 只有枚举对应于此平台上的16位整数。
该平台是Butterfly demo board上的AVR ATmega169V微控制器。 它是一个8位系统,对16位操作提供一些有限的支持。 它不是一个快速的系统,有大约1KB的RAM。 它没有像文件I / O或操作系统那样的任何奢侈品。
那么有关我应该用什么类型来存储8位命令的任何建议? 必须有比#defines的大量标题更好的东西。
答案 0 :(得分:36)
gcc
的{{1}}可能有用:
仅分配为“枚举”类型 需要很多字节 声明的可能值范围。 具体来说,“枚举”类型将是 相当于 具有足够空间的最小整数类型。
事实上,here是一个包含大量相关信息的页面。我希望你遇到许多你从未知道的GCC开关。 ;)
答案 1 :(得分:7)
您正在尝试解决不存在的问题。
您的问题被标记为C.在C语言中,值上下文中的枚举类型与整数类型完全兼容,其行为与其他整数类型一样。在表达式中使用时,它们与其他整数类型完全相同。考虑到这一点之后,您应该意识到如果要将枚举常量描述的值存储为8位整数类型,您所要做的就是选择合适的通用8位整数类型(比如{{1并使用它而不是枚举类型。通过将枚举常量值存储在类型为int8_t
的对象中(与使用枚举类型显式声明的对象相反),您绝对不会失去任何东西。
您描述的问题将存在于C ++中,其中枚举类型与其他整数类型分开得更远。在C ++中,为了节省内存而使用整数类型代替枚举类型更加困难(尽管可能)。但不是在C中,它不需要任何额外的努力。
答案 2 :(得分:3)
我不明白为什么枚举不起作用。与枚举进行比较和分配应该都可以正常使用默认扩展。请注意,您的8位值已正确签名(我认为您需要无符号扩展名。)
你将以这种方式进行16位比较,我希望这不会是性能问题(它不应该是,特别是如果你的处理器是16位,就像听起来那样)。
答案 3 :(得分:1)
Microsoft的C编译器允许您执行类似的操作,但它是一个扩展(它是C ++ 0x中的标准):
enum Foo : unsigned char {
blah = 0,
blargh = 1
};
由于您标记了GCC,我不完全确定是否可以使用相同的内容,但是GCC可能在gnu99
模式下有扩展名或者其他内容。给它一个旋转。
答案 4 :(得分:0)
我建议在任何情况下保持枚举,原因如下:
首先,您不应该关心真实的类型宽度。只有当你真的需要有效的存储方式时,才应该在GNU编译器上使用编译器标志,例如-fshort-enums,但我不推荐它们,除非你真的需要它们。
作为最后一个选项,您可以将'enum'定义为命令的表示数据,并使用转换为字节,通过2个简单的操作将命令值存储到存储器/从存储器恢复(并将其封装在一个位置)。那这个呢?这些操作非常简单,因此您甚至可以内联它们(但是这允许您真正使用1个字节进行存储,而另一侧则使用您喜欢的最可用枚举来执行操作。
答案 5 :(得分:0)
与 ARC编译器相关的答案 (引自DesignWare MetaWare C / C ++程序员ARC指南;第11.2.9.2节)
枚举的大小枚举类型的大小取决于toggle * Long_enums *的状态。
■如果切换* Long_enums *已关闭,则枚举类型将映射到一个,两个或四个字节中的最小值,以便可以表示所有值。
■如果启用了切换* Long_enums *,则枚举将映射到 四个字节(匹配AT& T Portable C Compiler约定)。