C/C++:将 char[] 转换为 int 失败,无符号 char[] 到 int 有效,为什么



我还没有找到回答这种确切行为的问题,不知何故,我只是不明白发生了什么:

我将 Windows 位图文件 (bmp) 的内容读入数组,稍后使用此数组提取所需信息:

char biHeader[40];
// ...
source.read(biHeader,40);
// ...
int biHeight = biHeader[8] | (biHeader[9] << 8) | (biHeader[10] << 16) | (biHeader[11] << 24);

在此之后,biHeight显示为-112这是完全错误的,因为它应该是400的。所以,我看了一下该文件的十六进制转储。阅读的内容是:

90 01 00 00

字节顺序更改为大端序会得到0x190,该400以十进制表示,正如预期的那样。

如果我将上面的代码更改为:

unsigned char biHeader[40];
// ...
source.read((char*)biHeader,40);
// ...
int biHeight = ... (same as before)

。然后我得到预期值。这是怎么回事?

以及:您将如何读取这些数据?

作为有符号 8 位二进制补码整数,0x90-112 。当它被转换为|int时,它的值被保留。由于如果表示形式是 2 的补码,则设置从第七位开始的所有位,因此按位或值向左移动至少 8 位不会再更改该值。

作为无符号 8 位整数,0x90 的值为 144,这是一个正数,没有超出 2^7 位设置的位。然后,按位或带biHeader[9] << 8将值更改为所需的144 + 256 = 400

使用按位运算符时,(几乎)总是使用无符号类型,有符号类型通常会导致令人不快的意外(如果移位结果超出范围或负整数向左移动,则会导致未定义的行为)。

最新更新