8位枚举,在C中

时间:2009-11-09 06:38:27

标签: c avr avr-gcc winavr avr-studio4

我必须存储我将通过串行接收的指令和命令。 命令长度为8位。

我需要保持命令名称及其值之间的透明度。 这样可以避免将串行接收的8位数转换成任何类型。

我想在我的代码中使用Enumerations来处理它们。 只有枚举对应于此平台上的16位整数。

该平台是Butterfly demo board上的AVR ATmega169V微控制器。 它是一个8位系统,对16位操作提供一些有限的支持。 它不是一个快速的系统,有大约1KB的RAM。 它没有像文件I / O或操作系统那样的任何奢侈品。

那么有关我应该用什么类型来存储8位命令的任何建议? 必须有比#defines的大量标题更好的东西。

6 个答案:

答案 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)

我建议在任何情况下保持枚举,原因如下:

  • 此解决方案允许您将命令值直接映射到串行协议所期望的内容。
  • 如果你真的使用16位架构,那么移植到8位类型的优势就不那么大了。想想保存1个内存字节以外的其他方面。
  • 在某些编译器中,我使用的实际枚举大小使用的最小位数(可以在字节中使用的枚举仅使用字节,然后是16位,然后是32)。

首先,您不应该关心真实的类型宽度。只有当你真的需要有效的存储方式时,才应该在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约定)。