有人可以解释这个按位的 C 代码吗?
Can someone explain this bitwise C code?
我不知道这是怎么回事:
#define _PACK32(str, x) \
{ \
*(x) = ((int) *((str) + 3) ) \
| ((int) *((str) + 2) << 8) \
| ((int) *((str) + 1) << 16) \
| ((int) *((str) + 0) << 24); \
}
str是整数,x是整数指针
看起来 str
是指向 4 字节数组的指针,而 x
是指向 32 位值的指针。 str
实际上指向一个 little endian 32 位数字的第一个字节 (LSB),这个宏将读取它并存储在 x
.
指向的变量中
嗯,如前所述,str
不是整数。它是一个指针,因为它被 *
运算符取消引用。
*((str) + 3)
等同于 *(str + sizeof(str[0])*3)
,因此这取决于 str 的类型,如 here 所示。其他取消引用运算符也是如此。
所以这是怎么回事?好吧,它将 str[0]、str1、str[2] 和 assemble 的最低有效 8 位取为一个 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's 可以是任何东西。
正确地写成一个 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
.
的不同位中
我不知道这是怎么回事:
#define _PACK32(str, x) \
{ \
*(x) = ((int) *((str) + 3) ) \
| ((int) *((str) + 2) << 8) \
| ((int) *((str) + 1) << 16) \
| ((int) *((str) + 0) << 24); \
}
str是整数,x是整数指针
看起来 str
是指向 4 字节数组的指针,而 x
是指向 32 位值的指针。 str
实际上指向一个 little endian 32 位数字的第一个字节 (LSB),这个宏将读取它并存储在 x
.
嗯,如前所述,str
不是整数。它是一个指针,因为它被 *
运算符取消引用。
*((str) + 3)
等同于 *(str + sizeof(str[0])*3)
,因此这取决于 str 的类型,如 here 所示。其他取消引用运算符也是如此。
所以这是怎么回事?好吧,它将 str[0]、str1、str[2] 和 assemble 的最低有效 8 位取为一个 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's 可以是任何东西。
正确地写成一个 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
.