不同的数据类型 - 有符号和无符号

时间:2017-09-12 19:29:53

标签: c operators equality integer-promotion

我刚刚执行了以下代码

main()
{
   char a = 0xfb;
   unsigned char b = 0xfb;
   printf("a=%c,b=%c",a,b);
   if(a==b) {
     printf("\nSame");
   }
   else {
     printf("\nNot Same");
   }
}

对于这段代码,我得到了答案

A =? B =?

不同

为什么我不能得到它,a和b的值是什么?

4 个答案:

答案 0 :(得分:6)

if (a == b) ...在比较之前将字符提升为整数,因此字符的签名会影响其发生的方式。无符号字符0xFB变为整数251;有符号字符0xFB变为整数-5。因此,他们是不平等的。

答案 1 :(得分:4)

有两种情况需要考虑:

  • 如果默认情况下char类型未签名,则ab都会分配值251,程序将打印Same
  • 如果char类型默认签名,这是最常见的情况,则定义char a = 0xfb;的实现定义行为为0xfb(十进制为251)可能超出char类型的范围(通常为-128127)。最有可能将值-5存储到a中,a == b计算结果为0,因为两个参数在比较之前都会提升为int,因此{{1将是假的。

-5 == 251的行为也取决于系统,因为非ASCII字符printf("a=%c,b=%c", a, b);-5可能会以意想不到的方式打印。但请注意,两者都将打印相同的251格式,指定在打印前将参数转换为%c。尝试unsigned char

会更安全,更明确

使用gcc或clang,您可以尝试使用printf("a=%d, b=%d\n", a, b);重新编译您的程序,看看行为会有何不同。

答案 2 :(得分:2)

根据C标准(6.5.9平等运营商)

  

4如果两个操作数都有算术类型,通常算术   转换已执行 ....

通常的算术转换包括整数提升。

来自C标准(6.3.1.1布尔,字符和整数)

  

2无论是int还是int,都可以在表达式中使用以下内容   可以使用unsigned int:       ...

     

如果int可以表示原始类型的所有值(限制为   通过宽度,对于位字段),该值被转换为int;   否则,它将转换为unsigned int。 这些被称为   整数提升 .58)所有其他类型的整数不变   促销。

所以在这个等式表达式中

a == b

两个操作数都转换为int类型。带符号的操作数(假设类型char的行为类型为signed char)通过传播符号位转换为类型int

结果,由于二进制表示的不同,操作数具有不同的值。

如果类型char的行为类型为unsigned char(例如通过设置编译器的相应选项),那么操作数显然是相等的。

答案 3 :(得分:0)

char存储-128到127和unsigned char存储从0到255。 0xfb代表小数点数251超出char a的限制。