在将无符号字符转换为整数类型的背景下发生了什么?

| 今天,我从切换块中得到了一些奇怪的行为,特别是我正在从文件中读取一个字节,并将其与某些十六进制值进行比较(文本文件编码问题,没什么大不了的)。该代码看起来像:
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-> int促销   产生0xffffffef而不是   0x000000ef?\“ 到目前为止,与这四个答案相反。 相反,您有一个
char
负值,作为
switch
条件,该值升为与required3 required值相同的负
int
值。   C ++ 98§6.4.2/ 2   进行整体促销。 然后,对于您的32位C ++编译器,ѭ4interpreted被解释为
unsigned int
文字,因为对于32位
int
而言,它太大了。   C ++ 98 2.13.1 / 2   如果是八进制或十六进制,并且没有后缀,则在   可以表示为:
int
unsigned int
long int
unsigned long int
。 现在,对于“ 11”标签,   C ++ 98§6.4.2/ 2   整数常量表达式(5.19)隐式转换为提升的   开关条件的类型。 在您的情况下,对于带符号的目标类型,转换的结果是正式实现定义的,方法是   C ++ 98§4.7/ 3   如果目标类型是带符号的,则该值可以表示,则保持不变   在目标类型(和位域宽度)中;否则,值为   实现定义的。 但是实际上,几乎所有编译器都使用二进制补码表示形式而没有任何陷阱,因此在您的情况下,实现定义的转换是将位模式
0xffffffef
解释为负值的二进制补码规范。您可以通过0xffffffef-232来计算哪个值,因为我们在这里谈论的是32位表示形式。或者,由于这只是一个8位的值,已被符号扩展为32位,因此您也可以将其计算为0xef-28,其中0xef是字符代码点。 干杯,……     
        您的(已签名)字符的符号扩展为一个已签名的int。这是因为有符号的值以二进制存储的方式。 例 1 in二进制字符= 00000001 1 int int整数= 00000000 00000000 00000000 00000001 -1 in二进制字符= 11111111 二进制int中的-1不是00000000 00000000 00000000 11111111而是11111111 11111111 11111111 11111111 如果您转换回十进制,则应该预先知道要处理带符号还是无符号值,因为11111111的带符号的可能是-1,无符号的是255。     
        platform1ѭ必须在您的平台上签名,并且您看到的是符号扩展名。     
        还没有说过(无论如何,我还是在键入),是否指定了char是未指定的。就您而言-如前所述-char是带符号的,因此任何大于127的ASCII值都将被解释为负数。     
        标志扩展     

要回复问题请先登录注册