【发布时间】:2013-01-27 15:22:52
【问题描述】:
我正在尝试更好地理解位运算符。我有许多类型 uint32_t 我正在尝试逐字节输出。执行此操作的代码是:
void printByteWise(uint32_t num) {
printf("byte 1 = %u\n", (num & 0xFF000000));
printf("byte 2 = %u\n", (num & 0x00FF0000));
printf("byte 3 = %u\n", (num & 0x0000FF00));
printf("byte 4 = %u\n", (num & 0x000000FF));
}
假设上面代码示例中的num 是9。那么字节数组应该像这样存储在内存中:09 00 00 00(按地址升序排列)。如果是这样,输出应该是:byte 1 = 09byte 2 = 00byte 3 = 00byte 4 = 00
但我得到的输出是:
byte 1 = 0
byte 2 = 0
byte 3 = 0
byte 4 = 9
我在一个小端的系统上,它是这样获得的:
int is_bigEndian() {
int i = 1;
char *low = (char *) (&i);
return *low ? 0 : 1;
}
这种行为正确吗?为什么我会看到这种行为?
【问题讨论】:
-
num & 0xFF000000的结果不是字节。它仍然是一个 32 位整数,低 24 位设置为 0。 -
%u 告诉 printf 期待一个无符号整数,而不是 uint32_t。因此,您的代码会调用未定义的行为。考虑将 PRIu32 宏用作格式字符串,用于 uint32_t 值。
-
另外,你不能使用 is_bigEndian 来测试小端,因为混合端系统的可能性。
-
@modifiablelvalue: 我如何检查混合字节序?
-
@Sriram 这不重要。一个更好的主意是编写不关心整数的底层表示的代码。例如,在通过 Internet 接收和发送整数值时,使用 sscanf 和 sprintf 将整数值解码和编码为十进制数字字符串。
标签: c bit-shift endianness