c++ - C/C++ : Conversion of char[] to int fails, unsigned char[] to int 有效,为什么?

标签 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)

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

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

最佳答案

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

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

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

关于c++ - C/C++ : Conversion of char[] to int fails, unsigned char[] to int 有效,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13786921/

相关文章:

c++ - C++ 中堆对象 getter/setter 的更好实践

c - 添加到列表中的奇怪值

c# - 克隆整个对象图

scala - 如何在 Scala 中单独存储 HashMap 值?

c# - mono_field_set_value 不起作用

java - Spring MVC : How to create single instance of object while deserialization JSON string containing duplicate object definitions

c++ - 我可以在函数定义中使用函数 typedef 吗?

c++ - 如何区分PCL数据和通常的Text?

c# - 将托管 unsigned char* 转换为 jbyte*

c - 指向 char 数组的指针数组