【问题标题】:8 bit enum, in C8位枚举,C语言
【发布时间】:2009-11-09 06:38:27
【问题描述】:

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

我需要保持命令名称及其值之间的透明度。 从而避免必须将串行接收的 8 位数字转换为任何类型。

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

该平台是 AVR ATmega169V 微控制器,位于Butterfly demo board。 它是一个 8 位系统,对 16 位操作的支持有限。 它不是一个快速的系统,并且有大约 1KB 的 RAM。 它没有文件 I/O 或操作系统之类的奢侈品。

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

【问题讨论】:

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


    【解决方案1】:

    gcc-fshort-enums 可能有用:

    仅分配给“枚举”类型 许多字节,因为它需要 声明的可能值范围。 具体来说,“枚举”类型将是 相当于 有足够空间的最小整数类型。

    其实here是一个有很多相关信息的页面。我希望你能遇到许多你不知道存在的 GCC 开关。 ;)

    【讨论】:

    • 哈,我今天意识到,如果我通过 AVR studio 4 IDE 编译,那么它默认是打开的
    • 我想补充一点,在收到命令时,您可能需要确保传入的 8 位值实际上是来自您的枚举的有效值,然后再键入 convert 并将其存储为您的枚举。跨度>
    【解决方案2】:

    您正在尝试解决一个不存在的问题。

    您的问题已标记为 C。在 C 语言中,值上下文中的枚举类型与整数类型完全兼容,并且其行为与其他整数类型一样。当在表达式中使用时,它们受到与其他整数类型完全相同的整数提升。考虑到这一点后,您应该意识到,如果要将枚举常量描述的值存储在 8 位整数类型中,您所要做的就是选择合适的通用 8 位整数类型(比如int8_t ) 并使用它代替枚举类型。通过将枚举常量值存储在 int8_t 类型的对象中(与使用枚举类型显式声明的对象相反),您绝对不会失去任何东西。

    您描述的问题将存在于 C++ 中,其中枚举类型与其他整数类型分离得更远。在 C++ 中,为了节省内存而使用整数类型代替枚举类型更加困难(尽管可能)。但不是在 C 中,它不需要任何额外的努力。

    【讨论】:

      【解决方案3】:

      我不明白为什么枚举不起作用。与枚举的比较和分配都应该在默认扩展的情况下正常工作。请注意您的 8 位值已正确签名(我认为您需要无符号扩展名)。

      您将通过这种方式获得 16 位比较,我希望这不会是性能问题(它不应该是,特别是如果您的处理器是 16 位,因为它听起来是这样)。

      【讨论】:

      • 事情是,我的串行输入是最初始的 8 位。我不确定 ALU 是在 16 位还是 8 位上工作。大多数汇编 cannands 仅适用于 8 位字节,少于 5 个适用于 2 字节字(ADDW,MOVW 是我能想到的全部)。只有
      • @oxinabox - 我仍然不确定这与枚举类型的大小有关。将 8 位值存储在 uint8_t 变量(或其他对应于字节的变量)中。您仍然可以比较枚举值并将其分配给它们(只要枚举小于 256)。如果确切的大小对应用程序很重要,请不要将枚举类型用作变量类型
      【解决方案4】:

      微软的 C 编译器允许你做这样的事情,但它是一个扩展(它是 C++0x 中的标准):

      enum Foo : unsigned char {
          blah = 0,
          blargh = 1
      };
      

      由于您标记了 GCC,我不完全确定相同的事情是否可能,但 GCC 可能在 gnu99 模式或其他方式下具有扩展名。试一试。

      【讨论】:

      • 嗯,我标记了 AVR-GCC。我将不得不查找它支持哪些扩展
      • 我对你的发现很感兴趣。这是一个直觉。
      • 而且似乎 MS 是唯一支持这种语法的。
      • 也许它后来被添加到 gcc 中,因为现在它可以工作并且该枚举的 sizeof 为 1,而常规枚举为 2。
      【解决方案5】:

      出于以下原因,我建议在任何情况下都使用枚举:

      • 此解决方案允许您将命令值直接映射到串行协议的预期值。
      • 如果您真的使用 16 位架构,那么迁移到 8 位类型并没有那么多优势。考虑节省 1 个内存字节以外的其他方面。
      • 在某些编译器中,我使用的实际枚举大小使用了最少的位数(可能适合字节的枚举仅使用字节,然后是 16 位,然后是 32)。

      首先你不应该关心真正的类型宽度。只有当你真的需要有效的存储方式时,你才应该在 GNU 编译器上使用 -fshort-enums 等编译器标志,但除非你真的需要它们,否则我不推荐它们。

      作为最后一个选项,您可以将“枚举”定义为命令的表示数据,并使用转换为字节的 2 个简单操作将命令值存储到内存/从内存恢复(并将其封装在一个地方)。那这个呢?这些是非常简单的操作,因此您甚至可以内联它们(但这允许您真正使用 1 个字节进行存储,并从另一端使用您喜欢的最可用枚举执行操作。

      【讨论】:

      • 8 位架构。我检查了硬件dos,它是8bit
      【解决方案6】:

      ARC编译器相关的答案 (引自 DesignWare MetaWare C/C++ Programmer's Guide for ARC;第 11.2.9.2 节)

      枚举大小 枚举类型的大小取决于切换 *Long_enums* 的状态。

      ■ 如果toggle *Long_enums* 关闭,则枚举类型映射到1、2 或4 个字节中的最小值,以便可以表示所有值。

      ■ 如果切换 *Long_enums* 处于打开状态,则枚举映射到 四个字节(符合 AT&T 便携式 C 编译器约定)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        • 1970-01-01
        • 1970-01-01
        • 2014-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多