unsigned int - shift和oring产生负值

bas*_*h.d 1 c c++ bit-manipulation bit-shift

当我从文件中读取原始字节时,我正在读取wav文件的标题并使用<<(左移)和|(或)填充我的类成员.现在,凑巧我有以下的情况
,其中uBytesPerSecond的类型是unsigneddata是的char*,所以我可以使用std::fstream::read.

现在,当我按照uBytesPerSecond调试器中的创建进行操作时

this->uBytesPerSecond |= data[0x1F]; //0x00 ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond |= data[0x1E]; //0x02 ->uBytesPerSecond = 0x00000002
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0x00000200
this->uBytesPerSecond |= data[0x1D]; //0xb1 ->uBytesPerSecond = 0xffffffb1 !!!
this->uBytesPerSecond <<= 8;         //     ->uBytesPerSecond = 0xffffb100
this->uBytesPerSecond |= data[0x1C]; //0x10 ->uBytesPerSecond = 0xffffb110
Run Code Online (Sandbox Code Playgroud)

在这种情况下的预期输出是uBytesPerSecond = 0x00002b110.请告诉我这里发生了什么以及如何解决这个问题.

我正在使用MSVC2012Windows 8,这是一个应用程序VC++-Console.

Gri*_*zly 6

问题是您的平台char是签名类型.因此,对于or-operation,包含的值将被标记扩展到32位,为您0xffffffb1提供data[0x1D].

要解决该问题,只需更改类型data即可unsigned char*.

编辑:如评论中所述,问题的另一个解决方案是使用以下方式显式屏蔽操作数0xFF:this->uBytesPerSecond |= data[0x1F] & 0xFF依此类推.