8 位枚举,C 语言

发布于 2024-08-10 22:43:35 字数 432 浏览 14 评论 0原文

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

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

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

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

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

I have to store instructions, commands that I will be receiving via serial.
The commands will be 8 bits long.

I need to preserve transparency between command name, and its value.
So as to avoid having to translate an 8-bit number received in serial into any type.

I'd like to use Enumerations to deal with them in my code.
Only a enumeration corresponds to a on this platform a 16 bit integer.

The platform is AVR ATmega169V microcontroller, on the Butterfly demo board.
It is a 8bit system with some limited support for 16bit operations.
It is not a fast system and has about 1KB of RAM.
It doesn't have any luxuries like file I/O, or an operating systems.

So any suggestions as to what type I should be using to store 8-bit commands?
There has got to be something better than a massive header of #defines.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

≈。彩虹 2024-08-17 22:43:35

gcc-fshort-enums 可能有用:

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

事实上,这里的页面包含很多相关信息。我希望您遇到许多您以前不知道存在的 GCC 开关。 ;)

gcc's -fshort-enums might be useful:

Allocate to an "enum" type only as
many bytes as it needs for the
declared range of possible values.
Specifically, the "enum" type will be
equivalent to
the smallest integer type which has enough room.

In fact, here's a page with a lot of relevant information. I hope you come across many GCC switches you never knew existed. ;)

岁月苍老的讽刺 2024-08-17 22:43:35

你正试图解决一个不存在的问题。

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

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

You are trying to solve a problem that does not exist.

Your question is tagged C. In C language enum types in value context are fully compatible with integral types and behave just like other integral types. When used in expressions, they are subjected to exactly the same integral promotions as other integral types. Once you take that into account, you should realize that if you want to store values described by enumeration constants in a 8-bit integral type, all you have to do is to choose a suitable generic 8-bit integral type (say int8_t) and use it instead of enum type. You'll lose absolutely nothing by storing your enum constant values in an object of type int8_t (as opposed to an object explicitly declared with enum type).

The issue you describe would exist in C++, where enum types are separated much farther from other integral types. In C++ using an integral type in place of enum type for the purpose of saving memory is more difficult (although possible). But not in C, where it requires no additional effort whatsoever.

落叶缤纷 2024-08-17 22:43:35

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

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

I don't see why an enum wouldn't work. Comparisons to, and assignments from, an enum should all work fine with the default widening. Just be careful that your 8 bit values are signed correctly (I would think you would want unsigned extension).

You will get 16-bit comparisons this way, I hope that won't be a performance problem (it shouldn't be, especially if your processor is 16-bit as it sounds like it is).

遮云壑 2024-08-17 22:43:35

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

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

既然你标记了 GCC,我不完全确定同样的事情是否可能,但 GCC 可能有一个扩展gnu99 模式或其他模式。试一试。

Microsoft's C compiler allows you to do something like this, but it's an extension (it's standard in C++0x):

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

Since you tagged GCC, I'm not entirely sure if the same thing is possible, but GCC might have an extension in gnu99 mode or something for it. Give it a whirl.

止于盛夏 2024-08-17 22:43:35

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

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

首先,您不应该关心实际类型的宽度。仅当您确实需要有效的存储方式时,您才应该在 GNU 编译器上使用编译器标志,例如 -fshort-enums,但我不推荐它们,除非您确实需要它们。

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

I'd recommend to stay on enum in any case for the following reasons:

  • This solution allows you to map command values directly to what your serial protocol expects.
  • If you really use 16-bit architecture there is not so big number of advantages to move to 8 bits type. Think about aspects other then 1 memory byte saved.
  • At some compilers I used actual enum size used minimal number of bits (enums that could be fit in byte used only byte, then 16 bit then 32).

First you should not care about real type width. Only if you really need effective way of storage you should use compiler flags such as -fshort-enums on GNU compiler but I don't recommend them unless you really need them.

As last option you can define 'enum' as presentation data for the commands and use conversion to byte with 2 simple operations to store / restore command value to/from memory (and encapsulate this in one place). What about this? These are very simple operations so you can even inline them (but this allows you to really use only 1 byte for storage and from other side to perform operations using most usable enum defined as you like.

何必那么矫情 2024-08-17 22:43:35

ARC 编译器相关的答案
(引自 DesignWare MetaWare C/C++ ARC 程序员指南;第 11.2.9.2 节)

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

■ 如果切换*Long_enums* 关闭,枚举类型将映射到一、二或四个字节中的最小值,以便可以表示所有值。

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

Answer which is relevant for ARC compiler
(Quoted from DesignWare MetaWare C/C++ Programmer’s Guide for ARC; section 11.2.9.2)

Size of Enumerations The size of an enum type depends on the status of toggle *Long_enums*.

■ If toggle *Long_enums* is off, the enum type maps to the smallest of one, two, or four bytes, such that all values can be represented.

■ If toggle *Long_enums* is on, an enum maps to
four bytes (matching the AT&T Portable C Compiler convention).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文