今天,我从切换块中得到了一些奇怪的行为,特别是我正在从文件中读取一个字节,并将其与某些十六进制值进行比较(文本文件编码问题,没什么大不了的)。该代码看起来像:

char BOM[3] = {0};
b_error = ReadFile (iNCfile, BOM, 3, &lpNumberOfBytesRead, NULL);

switch ( BOM[0] ) {
case 0xef: {
    // Byte Order Marker Potentially Indicates UTF-8
    if ( ( BOM[1] == 0xBB ) && ( BOM[2] == 0xBF ) ) {
        iNCfileEncoding = UTF8;
    }
    break;
           }
}

尽管调试看起来还不错,但这没有用。我意识到该开关将值提升为整数,一旦单击到位,我就可以在case语句中使用0xffffffef进行匹配。当然,正确的解决方案是使BOM []未签名,现在一切都按预期进行了改进和比较。

有人可以简要解释一下char-> int促销中产生了0xffffffef而不是0x000000ef的情况吗?

最佳答案



到目前为止,与四个答案相反,没有。

相反,您具有一个负char值,作为switch条件,该条件已提升为与要求相同的负int



然后,对于您的32位C++编译器,0xffffffef被解释为unsigned int文字,因为对于32位int而言,它太大了,



现在,对于case标签,



在您的情况下,对于带符号的目标类型,转换的结果是正式实现定义的,方法是



但是实际上,几乎所有编译器都使用二进制补码表示形式而没有任何陷阱,因此在您的情况下,实现定义的转换是将bitpattern 0xffffffef解释为负值的二进制补码规范。您可以通过0xffffffef-232来计算哪个值,因为我们在这里谈论的是32位表示形式。或者,由于这只是一个8位的值,已被符号扩展为32位,因此您也可以将其计算为0xef-28,其中0xef是字符代码点。

干杯,……

10-05 18:15