为什么1字节变量的按位补码返回4字节值?

问题描述 投票:3回答:2

我们以下面两个1字节变量为例:

uint8_t x1 = 0x00;
uint8_t x2 = 0xFF;

打印按位补码时,结果是一个4字节的变量:

printf("%02X -> %02X; %02X -> %02X\n", x1, ~x1, x2, ~x2);
00 -> FFFFFFFF; FF -> FFFFFF00

我知道这可以通过使用强制转换或屏蔽来“解决”:

printf("%02X -> %02X; %02X -> %02X\n", x1, (uint8_t) ~x1, x2, (uint8_t) ~x2);
00 -> FF; FF -> 00
printf("%02X -> %02X; %02X -> %02X\n", x1, ~x1&0xFF, x2, ~x2&0xFF);
00 -> FF; FF -> 00

但为什么非直觉行为首先出现?

c bitwise-operators
2个回答
2
投票

许多计算机处理器的大多数操作都具有“字”大小。例如,在32位机器上,可能存在加载32位的指令,存储32位的指令,将一个32位数加到另一位的指令,等等。

在这些处理器上,使用其他尺寸可能会令人讨厌。可能没有将16位数乘以另一个16位数的指令。 C在这些机器上长大。它被设计成int(或unsigned int)是“无论大小对你运行的机器有什么好处”而且charshort适合存储在内存中,但是,一旦它们从内存加载到处理器寄存器中,C就可以了和他们一样,他们是int

这简化了早期C编译器的开发。编译器不必通过执行32位补码指令,然后执行AND指令来删除不需要的高位来实现补码。它只做了一个简单的32位补码。

我们今天可以以不同的方式开发语言,但C承担着这种遗产。


1
投票

当您将~运算符应用于x1x2时,值首先受整数提升,因为uint8_t小于int。然后将运算符应用于提升的值。

所以~x1真的是~0x00000000(即0xFFFFFFFF)和~x2真的是~0x000000FF(即FFFFFF00)。这就是为什么你得到你正在获得的价值。

此外,%x格式说明符期望它打印的unsigned int

您需要使用%hhx作为格式说明符。这表示unsigned char论点。

printf("%02hhX -> %02hhX; %02hhX -> %02hhX\n", x1, ~x1, x2, ~x2);
© www.soinside.com 2019 - 2024. All rights reserved.