C / C ++:char []到int的转换失败,unsigned char []到int工作,为什么?

时间:2012-12-09 11:19:00

标签: c++ c serialization file-io type-conversion

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

我将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

将字节顺序更改为big endian会得到0x190,其中十进制为400,如预期的那样。

如果我将上述代码更改为:

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

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

并且:你会如何阅读这些数据?

1 个答案:

答案 0 :(得分:5)

作为带符号的8位二进制补码整数,0x90-112。如果int转换为|,则会保留其值。由于如果表示是二进制补码,则设置第七个开启的所有位,按位或向左移动至少八位的值不再改变该值。

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

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