1

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

我将 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。因此,我查看了文件的 hexdump。读取的内容是:

90 01 00 00

正如预期的那样,将字节顺序更改为大端会给出0x190十进制400

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

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

...然后我得到预期值。这里发生了什么?

并且:您将如何读取这些数据?

4

1 回答 1

5

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

作为一个无符号的 8 位整数, 的值为0x90144,一个正数,没有超出2^7位集的位。然后,按位或 withbiHeader[9] << 8将值更改为所需的144 + 256 = 400.

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

于 2012-12-09T11:22:49.187 回答