定义2个字节的最佳方法是使用C中的数组初始化/比较来轻松使用?

时间:2011-01-08 17:30:16

标签: c arrays byte c-preprocessor

同样,我对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 MSGIDCLA​​SS 0xAB那样拆分,然后#define MSGID 0xCD。

我还想比较这些MSGID字节,目前我不得不经常做一个if(data [n] == MSGIDCLA​​SS&& data [n + 1] == MSGID)...对于我需要解析和响应的每条消息。我想知道是否有更简单的方法来做到这一点,就是这样。如果没有,我会保持原样。再次感谢您的帮助。很抱歉没有使用代码示例代码,认为没有必要使用一个衬垫。

3 个答案:

答案 0 :(得分:3)

#define只是被他们的内容所取代。因此,当您使用逗号时,最终代码将变为:

unsigned char test_msg[] = { 0x00, 0x01, 0x02, 0xAB, 0xCD, 0x03, 0x04, 0x05 };

这就是为什么它似乎有效。

相反,分别定义MSGIDHIMSGIDLO组件可让您轻松使用和比较。您可以将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组成的,并且这种分离不只是将它们分成两个字节,那么你可以做到以下几点:

  • 保留单独的类和ID值
  • 使用这些单独的val; ues填写消息
  • 使用以下宏进行比较:

    #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位数字,您可以执行以下操作:

  • 为您的留言ID
  • 使用单个定义
  • 使用以下宏从邮件中插入/提取它们:

    #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宏中的逗号处理就像任何分隔数组初始化程序的逗号一样,因为宏只是在编译器解析代码之前执行文本替换。