有人可以解释这个按位C代码吗?

时间:2015-04-26 18:41:19

标签: c bit-manipulation

我不知道发生了什么:

#define _PACK32(str, x)                   \
    {                                             \
        *(x) =   ((int) *((str) + 3)      )    \
               | ((int) *((str) + 2) <<  8)    \
               | ((int) *((str) + 1) << 16)    \
               | ((int) *((str) + 0) << 24);   \
    }

str它是一个整数而x是一个整数指针

3 个答案:

答案 0 :(得分:3)

嗯,如上所述,str不是整数。它是一个指针,因为它是*运算符的解除引用。

*((str) + 3)相当于*(str + sizeof(str[0])*3),因此这取决于str的类型,如here所示。其他解除引用运算符也是如此。

那是怎么回事?好吧,它需要最低8位的str [0],str 1,str [2],并将它们组合成一个32位大小的整数。

例如,让W, X, Y, Z, A为任意位。然后,

  • *(str + 3) = WWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXX
  • *(str + 2) = WWWWWWWWWWWWWWWWWWWWWWWWYYYYYYYY
  • *(str + 1) = WWWWWWWWWWWWWWWWWWWWWWWWZZZZZZZZ
  • *(str + 0) = WWWWWWWWWWWWWWWWWWWWWWWWAAAAAAAA

最后3个分别被移位,8,16和24,因此,

  • *(str + 3) = WWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXX
  • *(str + 2) = WWWWWWWWWWWWWWWWYYYYYYYY00000000
  • *(str + 1) = WWWWWWWWZZZZZZZZ0000000000000000
  • *(str + 0) = AAAAAAAA000000000000000000000000

请注意,在班次期间,最后3位的最低有效数字将替换为0。

最后,它们是OR'ED,然后分配给X,

X = AAAAAAAAZZZZZZZZYYYYYYYYXXXXXXXX

编辑:O'Ring并不像W看起来那么简单。

答案 1 :(得分:1)

看起来str是指向4个字节数组的指针,而x是指向32位值的指针。 str实际上指向一个小端32位数的第一个字节(LSB),该宏将读取它并存储在x指向的变量中。

答案 2 :(得分:1)

正确地写为inline函数,它应该类似于:

void pack32(void const*p, unsigned* x) {
    unsigned char const* str = p;
     *x = str[0];
     *X = *x<<8 | str[1];
     *X = *x<<8 | str[2];
     *X = *x<<8 | str[3];
}

当你进行位移时你应该使用无符号类型,否则你的结果会溢出。也许它也使这个想法更清晰。每个字节的8位被置于目标x的不同位中。