C在计算比较值时的处理

C在计算比较值时的处理,c,casting,comparison,implicit-conversion,C,Casting,Comparison,Implicit Conversion,有人在和我谈论C语言中的wrapparound(0xffff+0x0001=0x0000),这导致了以下情况: int main() { unsigned int a; for (a = 0; a > -1; a++) printf("%d\n", a); return 0; } 使用GCC编译时,该程序退出而不运行循环,我认为这是因为-1被隐式转换为0xffff。将int切换到long时也会发生同样的情况。但是,当切换到char时,程序将无限期运行。我希望由于int

有人在和我谈论C语言中的wrapparound(0xffff+0x0001=0x0000),这导致了以下情况:

int main() {
  unsigned int a;
  for (a = 0; a > -1; a++)
    printf("%d\n", a);
  return 0;
}
使用GCC编译时,该程序退出而不运行循环,我认为这是因为
-1
被隐式转换为
0xffff
。将
int
切换到
long
时也会发生同样的情况。但是,当切换到
char
时,程序将无限期运行。我希望由于
int
没有运行循环,
char
也不会运行循环。有人能解释一下编译器在这种情况下执行的是哪种隐式转换,它是在C标准的某个版本中定义的还是依赖于编译器的?

摘自:

如果两个操作数都具有算术类型,则通常的算术转换为 表演

几个运算符自动将操作数值从一种类型转换为另一种类型

许多期望算术类型的操作数的运算符会导致转换并产生结果 以类似的方式输入。目的是确定操作数的通用实数类型 结果呢。对于指定的操作数,将转换每个操作数,而不更改类型 域,指向其对应实类型为公共实类型的类型。除非 否则,公共实数类型也是 结果,其类型域是操作数的类型域(如果操作数相同), 否则会很复杂。这种模式称为通常的算术转换:

首先,如果任一操作数的对应实数类型为长双精度(…)

否则,如果任一操作数的对应实数类型为double(…)

否则,如果任一操作数的对应实数类型为float(…)

否则,将对两个操作数执行整数提升。然后 以下规则应用于提升的操作数:

如果两个操作数的类型相同,则无需进一步转换

否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型 整数类型(…)

否则,如果具有无符号整数类型的操作数的秩大于或等于 等于另一个操作数类型的秩,然后为 有符号整数类型转换为无符号的操作数类型 整数类型。

否则,如果带符号整数类型的操作数的类型可以表示 具有无符号整数类型的操作数类型的所有值,然后 无符号整数类型的操作数转换为 带符号整数类型的操作数

否则,两个操作数都转换为无符号整数类型
与带符号整数类型的操作数的类型相对应。

基本上,在C中执行操作时,必须在至少与较大运算符相同的基中执行该操作

因此,假设您的int是int32,则操作:

uint32_t > int32_t
操作必须在基础“uint32_t”或格栅中执行。在这种情况下,它将在“uint32\u t”中执行

当您这样做时:

uint8_t > int32_t
正在基“int32_t”或更高版本中执行该操作

通常,如果可能,操作将在“int”基中执行,因为它应该比任何其他基都快

因此,如果你这样做:

(int)unsigned char > int(-1)

,条件将始终为真。

在C中,无符号是粘性的:

  unsigned int a;

  /* ... */

  a > -1
在上面的
表达式中,左操作数的类型为
无符号int
,右操作数的类型为
int
。C常用算术转换将两个操作数转换为一个公共类型:
无符号int
,因此上面的
表达式等价于:

 a > (unsigned int) -1
-1
转换为
无符号int
会使结果值成为一个巨大的
无符号int
值,当
a
初始值为
0
时,表达式的计算结果为false(
0


现在,如果
a
的类型为
char
int
-1
则不会转换为
无符号int
,因此
0>-1
如预期的那样为真(
1
)。

那么,在应用之前是否将文本转换为
有符号int
。@Tanaki是的,ouah先生告诉您如何做一个示例。