同样,我对C相当新,所以请原谅这个问题的简单/愚蠢。无论如何,在这里。在C中定义一个2字节宏(即#define MSGID 0xABCD)的最佳方法是什么,它很容易放入字节数组,但也比较if语句的内容?
为了澄清这一点,再次采用0xABCD示例。说我想做一个:
unsigned char test_msg[] = { 0x00, 0x01, 0x02, MSGID, 0x03, 0x04, 0x05 };
根据我在上面的定义,它不起作用,因为它被定义为一个大的int,gcc将它截断为无符号类型。当我将它定义为#define MSGID 0xAB,0xCD它似乎工作正常,但我不明白逗号在那里做什么,看起来不是很干净。我找到的另一个选项是工作,但也不干净,就像#define MSGIDCLASS 0xAB那样拆分,然后#define MSGID 0xCD。
我还想比较这些MSGID字节,目前我不得不经常做一个if(data [n] == MSGIDCLASS&& data [n + 1] == MSGID)...对于我需要解析和响应的每条消息。我想知道是否有更简单的方法来做到这一点,就是这样。如果没有,我会保持原样。再次感谢您的帮助。很抱歉没有使用代码示例代码,认为没有必要使用一个衬垫。
答案 0 :(得分:3)
#define
只是被他们的内容所取代。因此,当您使用逗号时,最终代码将变为:
unsigned char test_msg[] = { 0x00, 0x01, 0x02, 0xAB, 0xCD, 0x03, 0x04, 0x05 };
这就是为什么它似乎有效。
相反,分别定义MSGIDHI
和MSGIDLO
组件可让您轻松使用和比较。您可以将MSGID定义为:
#define MSGIDLO 0xCD
#define MSGIDHI 0xAB
#define MSGID (MSGIDLO | (MSGIDHI << 8))
这样您就可以以任何形式使用它们。
答案 1 :(得分:1)
有时您可能更喜欢没有预处理器的解决方案,例如:
enum {MSGID = 0xABCD};
// in C++ you can use const int MSGID = 0xABCD instead, not sure about C
unsigned char test_msg[] = { 0x00, 0x01, 0x02, MSGID>>8, MSGID&0xff, 0x03, 0x04, 0x05 };
答案 2 :(得分:1)
如果你的消息ID实际上是由一个类和一个ID组成的,并且这种分离不只是将它们分成两个字节,那么你可以做到以下几点:
使用以下宏进行比较:
#define MSGID(msgClass, ID) (((msgClass) << 8) | (ID))
#define GET_MSGID(data, n) (((data)[n] << 8) | (data)[(n)+1])
你像这样使用它们:
#define MSGCLASS_A 0xAB
#define MSGID_B 0xCD
unsigned char test_msg[] = { 0x00, 0x01, 0x02, MSGCLASS_A, MSGID_B, 0x03, 0x04, 0x05 };
if (GET_MSGID(test_msg, 0) == MSG_ID(MSGCLASS_A, MSGID_B))
{
// matched message
}
如果您的消息ID实际上只是一个16位数字,您可以执行以下操作:
使用以下宏从邮件中插入/提取它们:
#define MSGID(ID) (((ID) >> 8) & 0xFF), ((ID) & 0xFF) /* For static message definitions */
#define ADD_MSGID(data, n, ID) do { (data)[n] = (((ID) >> 8) & 0xFF; (data)[(n)+1] = ((ID) & 0xFF; } while (0)
#define GET_MSGID(data, n) (((data)[n] << 8) | (data)[(n)+1])
你像这样使用它们:
#define MSGID_A 0xABCD
unsigned char test_msg[] = { 0x00, 0x01, 0x02, MSGID(MSGID_A), 0x03, 0x04, 0x05 };
// or: ADD_MSGID(test_msg, 0, MSGID_A)
if (GET_MSGID(test_msg, 0) == MSGID_A)
{
// matched message
}
MSGID
宏中的逗号处理就像任何分隔数组初始化程序的逗号一样,因为宏只是在编译器解析代码之前执行文本替换。