题
我必须存储我将通过串行接收的说明,命令。命令将长8位。
我需要保持命令名称及其值之间的透明度。以避免必须将串行中收到的8位编号转换为任何类型。
我想用枚举在我的代码中处理它们。只有枚举对应于该平台上的一个16位整数。
该平台是AVR ATMEGA169V微控制器 蝴蝶演示板. 。这是一个8位系统,对16位操作的支持有限。它不是一个快速的系统,有大约1KB的RAM。它没有任何奢侈品,例如文件I/O或操作系统。
因此,关于我应该使用哪种类型来存储8位命令的任何建议?
必须有比#Defines的巨大标题更好的东西。
解决方案
gcc
' -fshort-enums
可能有用:
分配给“枚举”仅键入尽可能多的字节,即可为声明的可能值范围键入。具体而言,“枚举”类型将等同于具有足够空间的最小整数类型。
实际上, 这里'SA页面带有许多相关信息。我希望您遇到许多您从未知道的GCC开关。 )
其他提示
您正在尝试解决不存在的问题。
您的问题被标记为C.在价值上下文中的C语言枚举类型中,与积分类型完全兼容,并且与其他积分类型一样。当在表达式中使用时,它们会受到与其他积分类型完全相同的积分促销。考虑到这一点后,您应该意识到,如果要以8位积分类型中描述的枚举常数存储值,那么您要做的就是选择合适的通用8位积分类型(例如 int8_t
)并使用它代替枚举类型。通过将枚举恒定值存储在类型的对象中,您将绝对不会失去任何东西 int8_t
(而不是用枚举类型明确声明的对象)。
您描述的问题将存在于C ++中,其中枚举类型与其他积分类型更远。在C ++中使用积分类型代替枚举类型,以保存内存更困难(尽管可能)。但不在C中,不需要任何额外的努力。
我不明白为什么枚举不起作用。与枚举的比较和作业的比较,都应在默认加宽方面正常工作。请注意正确签名8位值(我认为您需要未签名的扩展名)。
您将通过这种方式进行16位比较,我希望这不会是性能问题(不应该这样,尤其是如果您的处理器是16位,听起来像是这样)。
Microsoft的C编译器允许您执行类似的操作,但这是一个扩展程序(C ++ 0x中的标准):
enum Foo : unsigned char {
blah = 0,
blargh = 1
};
由于您标记了GCC,因此我不确定是否可以使用同样的事情,但是GCC可能有一个扩展名 gnu99
模式或其他东西。给它旋转。
由于以下原因,我建议在任何情况下保持枚举:
- 该解决方案允许您将命令值直接映射到串行协议的期望。
- 如果您真的使用16位体系结构,则没有太大的优势移至8位类型。考虑其他方面,然后保存1个内存字节。
- 在某些编译器上,我使用的实际枚举大小使用了最小数量的位(可以适合仅使用字节的枚举,然后是16位,然后32位)。
首先,您不应该关心实际的类型宽度。只有当您确实需要有效的存储方式时,您才应该使用编译器标志,例如GNU编译器上的-Fshort -Enums,但是除非您真的需要它们,否则我不建议它们。
作为最后一个选项,您可以将“枚举”定义为命令的呈现数据,并使用转换到具有2个简单操作的字节,以存储 /还原命令值to / from Memory(并将其封装在一个位置)。那这个呢?这些是非常简单的操作,因此您甚至可以将它们嵌入式操作(但这允许您真正使用1个字节进行存储,而另一侧则使用最适合的枚举来执行操作。
答案与 弧编译器 (从Designware Metaware C/C ++的ARC程序指南引用;第11.2.9.2节)
枚举的大小,枚举类型的大小取决于切换 *long_enums *的状态。
■如果切换 * long_enums *已关闭,则枚举类型映射到一个,两个或四个字节中的最小,以表示所有值可以表示。
■如果toggle * long_enums *已打开,则枚举映射到四个字节(与AT&T Portable C编译器约定匹配)。