[英]C/C++: Conversion of char[] to int fails, unsigned char[] to int works, why?
我还没有找到回答这个确切行为的问题,而且我只是不知道发生了什么:
我将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
将字节顺序更改为big endian可以得到0x190
,即十进制的400
。
如果我将以上代码更改为:
unsigned char biHeader[40];
// ...
source.read((char*)biHeader,40);
// ...
int biHeight = ... (same as before)
...然后我得到了期望值。 这里发生了什么?
并且:您将如何读取这些数据?
作为有符号的8位二进制补码整数, 0x90
是-112
。 当|
转换为int
。 ,其值被保留。 由于如果表示形式是二进制补码,则从第七位起的所有位都将置位,因此按位或左移至少八位的值不再更改该值。
作为一个无符号的8位整数, 0x90
值为144,是一个正数,没有超出2^7
位设置的位。 然后,按位或biHeader[9] << 8
将值更改为所需的144 + 256 = 400
。
当使用按位运算符时,(几乎)总是使用无符号类型,有符号类型经常导致不愉快的意外(如果移位结果超出范围或向左移负整数,则会导致不确定的行为)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.