C/C++:将 char[] 转换为 int 失败,无符号 char[] 到 int 有效,为什么
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
将字节顺序更改为大端序会得到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
。
使用按位运算符时,(几乎)总是使用无符号类型,有符号类型通常会导致令人不快的意外(如果移位结果超出范围或负整数向左移动,则会导致未定义的行为)。
相关文章:
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 如何在不强制转换每个参数的情况下删除初始值设定项列表中从 int 到 char 的缩小转换?
- C ++如何在使用"tolower"时将char转换为int
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- 类型为 'std::map< char,int > 的 <Swig 对象的代理
- 声明具有两种类型的变量:"int char"
- 定义.cpp中常数int/char*
- Qt5 对'QApplication::QApplication(int&, char**, int)'的未定义引用
- 将int/char插入数据库
- 从 std::vector 转换为<int> char[] C++
- 为什么INT(char)的比较不起作用
- 使用int+char组合uint8_t
- 为什么这个返回值?C++int/char混淆
- 向量到 int<char> 与向量<wchar_t>到 int
- Evaluate an int, char and int
- 接收错误"no matching function for call to 'getline(std::ifstream&, int&, char)'"
- reinterpret_cast<int*>(char*) vs. static_cast<int*>(static_cast<void*>(char*)) --
- 将类型int(C::*)(int, char)转换为类型int(int, char)
- 如何添加多位数的int和char,其中输出为int+char
- 是int, char也是抽象数据类型