请参阅此代码片段

int main()
{ 
 unsigned int a = 1000;
 int b = -1;
 if (a>b) printf("A is BIG! %d\n", a-b);
 else printf("a is SMALL! %d\n", a-b); 
 return 0;
}   

这给出了输出:a 很小:1001

我不明白这里发生了什么事。> 运算符在这里如何工作?为什么“a”比“b”小?如果它确实更小,为什么我会得到一个正数(1001)作为差异?

有帮助吗?

解决方案

不同的积分类型之间

二进制操作由所谓的通常的算术转换定义的“公共”型内执行(参见语言规范,6.3.1.8)。在你的情况下,“普通”的类型是unsigned int。这意味着,int操作数(您的b)将被转换到unsigned int比较之前,以及用于执行减法的目的。

-1转换为unsigned int结果是最大可能unsigned int值(同UINT_MAX)。不用说,这将是比你的无符号1000值时,这意味着a > b的确是假的,a确实的的比较(unsigned) b。在你的代码的if应该下定决心else分支,这是你在实验中观察到的东西。

在相同的转换规则适用于减法。你a-b真的解释为a - (unsigned) b和结果类型unsigned int。这样的值不能被打印与%d格式说明中,由于仅%d签名值的工作原理。你尝试与未定义的行为%d结果打印出来,这样就看到印刷(即使它具有在实践中的逻辑确定性解释)的值是从图的C语言的点完全没有意义的。

编辑:其实,我可能是错关于未定义行为的一部分。据C语言规范的范围内的公共部分相应的有符号和无符号整数类型应具有相同的表示(这意味着,根据本脚注31,“互换性作为函数的参数”)。所以,a - b表达式的结果是如上文所述的无符号1001,除非我失去了一些东西,它是合法的打印与%d符这个特定的无符号的价值,因为它属于int的正面范围内。与(unsigned) INT_MAX + 1印刷%d将是不确定的,但1001u是细

其他提示

在一个典型的实现方式,其中int是32位,-1时转换为unsigned int是4294967295这的确是≥1000

即使你把在unsigned世界减法,1000 - (4,294,967,295) = -4,294,966,295 = 1,001这是你会得到什么。

这就是为什么当你与gcc比较unsigned signed会吐出警告。 (如果您没有看到一个警告,通过-Wsign-compare标志。)

您正在做无符号比较,即比较1000〜2 ^ 32 - 1

的输出,因为在printf的%d的签名。

N.B。有时当你混合签署的行为和无符号操作数是编译器特定的。我认为这是最好的,以避免他们做蒙上有疑问时。

找到一个简单的方法来比较,也许有用,当你无法摆脱无符号的声明,(例如,[NSArray的计数]),只是迫使“无符号整型”到“INT”。

如果我错了,请大家指正。

if (((int)a)>b) {
    ....
}

硬件设计来比较签名到符号和无符号无符号。

如果你想要的运算结果,第一个无符号值转换为一个更大符号的类型。否则编译器港岛线假定比较确实是无符号的值之间。

和-1表示为1111..1111,所以这是一个非常大的数量...最大的...当解释为无符号。

 #include<stdio.h>
 int main()
 {
   int a = 1000;
   signed int b = -1, c = -2;
   printf("%d",(unsigned int)b);
   printf("%d\n",(unsigned int)c);
   printf("%d\n",(unsigned int)a);

   if(1000>-1){
      printf("\ntrue");
   }
   else 
     printf("\nfalse");
     return 0;
 }

为此,您需要了解运算符的优先级

  1. 关系运算符从左到右工作...所以当它到来时

    如果(1000>-1)

那么首先它会将 -1 更改为无符号整数,因为 int 默认情况下被视为无符号数,并且它的范围大于有符号数

-1会变成无符号数,变成很大的数

当比较A> B,其中a是无符号整型类型和b是整数类型,的 b的键入浇铸无符号整型所以,符号int值-1转换成无符号的MAX值** (范围:0到(2 ^ 32)-1)** 因此,A> B,即(1000> 4294967296)变为假。因此其他环的的printf( “a是SMALL%D \ N!”,A-B); 执行

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top