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