“?:”中发生了什么?我不知道返回类型

时间:2019-01-06 14:15:10

标签: c ternary-operator unsigned signed conditional-operator

我认为((1 ? (int)1 : (unsigned int)2) > -1)的结果是1(真),但实际上在Visual Studio 2017中是0(假)。

我认为(1 ? (int)1 : (unsigned int)2)的值应为(int)1,因为1 ?为真,而1 > -1为真。

我不知道该表达式的最终结果为假的原因。

当我尝试像((int)(1 ? (int)1 : (unsigned int)2) > -1)一样进行投射时,它返回1(真)。

signed int test = -1;
signed int si = 1;
unsigned int ui = 2;

printf("%d\n", ((1 ? si : ui) > test));
return 0;

我希望输出为1,但实际输出为0

4 个答案:

答案 0 :(得分:20)

a ? b : c的类型不依赖于a。它是由bc的类型无条件确定的。完整规则很复杂,但是对于算术操作数,类型由常规的算术转换确定。实际上,两个操作数将转换为通用类型。对于intunsigned int,结果类型为unsigned int

C 2018标准的第6.5.15节描述了条件运算符? :。第4段说,结果“已转换为下述类型”。

第5段描述了算术类型,结构和联合的结果:

  

如果第二个和第三个操作数都具有算术类型,则将它们应用到这两个操作数时,将由通常的算术转换确定的结果类型。如果两个操作数都具有结构或联合类型,则结果具有该类型。如果两个操作数都为void类型,则结果为void类型。

根据6.2.5 18,算术类型为整数和浮点类型。(这些类型包括实数和复数类型。)6.3.1.8 1中描述了常用的算术转换,在我的摘要中未引用):

  • 如果其中一个是复杂类型,则结果是复杂的,其余规则描述了实部和虚部的类型。否则,结果是真实的,其余规则描述其类型。
  • 如果其中一个为long double,则结果为long double
  • 否则,如果其中一个为double,则结果为double
  • 否则,如果其中一个为float,则结果为float
  • 否则,将整数提升应用到每个操作数(这些在6.3.1.1 2中指定),然后将这两种类型转换为通用整数类型。完整的规则有些复杂,使用等级概念需要一些解释,并且涵盖了一些深奥的情况,因此,我将在正常情况下对它们进行总结:如果两种类型均为int或更窄(表示位数较少)或位数相同但有符号而不是无符号),则结果为int。否则,如果两者均为unsigned int或更小,则结果为unsigned int。否则,结果将是更广泛的类型。

结构,联合和无效规则很明确:两个操作数必须具有相同的类型,这就是结果。

第6段描述了指针的结果:

  

如果第二个操作数和第三个操作数都是指针,或者一个是空指针常量,而另一个是指针,则结果类型是指向一个类型的指针,该类型具有两个操作数都引用的所有类型限定符。此外,如果两个操作数都是指向兼容类型或兼容类型的不同限定版本的指针,则结果类型是指向复合类型的适当限定版本的指针。如果一个操作数是空指针常量,则结果具有另一操作数的类型;否则,一个操作数是指向 void void 的限定版本的指针,在这种情况下,结果类型是指向 void < / strong>。

总而言之:

  • 如果两个操作数都具有限定符(constvolatilerestrict_Atomic),则将其包括在结果类型中。
  • 如果两种类型不同但兼容(例如,未知大小的数组和已知大小的数组,都具有相同的元素类型),则将两种类型组合在一起。 (除了数组大小以外,其他合并的可能性还包括数组的元素是不同但兼容的类型,带有和不带有参数列表的函数以及函数的参数是不同但兼容的类型。)

答案 1 :(得分:3)

除非您完全知道正在展开的事情(并且您想要这种行为)[checkout here why],否则不要混合使用带符号和无符号值。在幕后,由于表达式中有一个unsigned数字,因此C被计算为大于unsigned integer >的大于运算符。因此,您的比较不会评估true,因为“ unsigned -1”大于您的unsigned 1

答案 2 :(得分:2)

您的?:运算符的结果为unsigned类型,因为它是intunsigned常见类型(您的第二和第三操作数)。结果的“期望”值为1,但其类型为unsigned

其余部分与?:无关。对于这个常见问题,它在众多答案中都有很好的描述:Comparison operation on unsigned and signed integers

答案 3 :(得分:1)

如果我放下这段代码,只需在上面加上一个数字:

unsigned x = (unsigned)-1;

进入我目前正在调试的程序中,X的值为4294967295(UINT_MAX),即您的程序“看到”比较是这样的:

((1 ? (int)1 : (unsigned int)2) > 4294967296)

(将其作为评论输入,但我没有声誉。)