1

我对 C 语言缺乏经验,并且在微控制器上工作,消息存储在数组中,每个字节都有不同的作用。如何给数组的每个元素一个人类可读的名称,而不是将它们引用为 msg[1]、msg[2] 等?

这是结构的用途吗?但是“你不能对结构的二进制布局做出假设,因为它可能在字段之间有填充。”

我应该只使用这样的宏吗?(我知道“宏很糟糕”,但代码已经充满了它们)

#define MSG_ID       msg[0]
#define MSG_COMMAND  msg[1]

哦!或者我想我可以做

MSG_ID = 0;
MSG_COMMAND = 1;
MSG[MSG_ID];

如果再丑一点,那可能会更好。

4

3 回答 3

3

如果您想走那条路,请使用宏,当然,但要使它们比您建议的更好:

#define MSG_ID(x)      (x)[0]
#define MSG_COMMAND(x) (x)[1]

这将允许代码以有意义的方式命名数组,而不是使用宏的方式。

否则,您可以为索引定义常量(对不起,我无法为它们想出更好的名称......):

#define IDX_MSG_ID      0
#define IDX_MSG_COMMAND 1

如果负责任地使用宏,它们也不错。这种“简单的别名”是宏有助于使代码更易于阅读和理解的情况之一,前提是宏的名称适当且有据可查。

编辑:根据@Lundin 的评论,提高代码可读性和安全性的最好方法是引入一个类型和一组函数,就像这样(假设你存储char并且消息很MESSAGE_SIZE长):

typedef char MESSAGE[MESSAGE_SIZE];
char get_message_id(MESSAGE msg) { return msg[0]; }
char get_message_command(MESSAGE msg) { return msg[1]; }

这种方法虽然带来了一定程度的类型安全性并允许您将存储从使用中抽象出来,但也引入了调用开销,这在微控制器世界中可能是有问题的。编译器可以通过内联函数来缓解其中的一些问题(您可以通过inline在定义中添加关键字来激励)。

于 2012-01-25T15:58:07.520 回答
2

在 C 中命名一组整数的最自然的概念是枚举:

enum msg_pos { msg_id, msg_command, };

By default they start counting at 0 and increment by one. You would then access a field by msg[msg_id] for example.

于 2012-01-25T19:33:22.433 回答
1

如果你花时间弄清楚你的编译器是如何布置它们的,那么使用结构是很好的,而且结构在嵌入式编程中非常有用。它总是按顺序排列成员,但如果您不在 8 位微控制器上,则可能会有填充。GCC 有一个“packed”属性,您可以将其应用于结构以禁止填充,其他一些编译器也有类似的功能。

于 2012-01-25T16:09:04.633 回答