我认为((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
。
答案 0 :(得分:20)
a ? b : c
的类型不依赖于a
。它是由b
和c
的类型无条件确定的。完整规则很复杂,但是对于算术操作数,类型由常规的算术转换确定。实际上,两个操作数将转换为通用类型。对于int
和unsigned 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
。int
或更窄(表示位数较少)或位数相同但有符号而不是无符号),则结果为int
。否则,如果两者均为unsigned int
或更小,则结果为unsigned int
。否则,结果将是更广泛的类型。结构,联合和无效规则很明确:两个操作数必须具有相同的类型,这就是结果。
第6段描述了指针的结果:
如果第二个操作数和第三个操作数都是指针,或者一个是空指针常量,而另一个是指针,则结果类型是指向一个类型的指针,该类型具有两个操作数都引用的所有类型限定符。此外,如果两个操作数都是指向兼容类型或兼容类型的不同限定版本的指针,则结果类型是指向复合类型的适当限定版本的指针。如果一个操作数是空指针常量,则结果具有另一操作数的类型;否则,一个操作数是指向 void 或 void 的限定版本的指针,在这种情况下,结果类型是指向 void < / strong>。
总而言之:
const
,volatile
,restrict
或_Atomic
),则将其包括在结果类型中。答案 1 :(得分:3)
除非您完全知道正在展开的事情(并且您想要这种行为)[checkout here why],否则不要混合使用带符号和无符号值。在幕后,由于表达式中有一个unsigned
数字,因此C被计算为大于unsigned integer >
的大于运算符。因此,您的比较不会评估true
,因为“ unsigned -1
”大于您的unsigned 1
。
答案 2 :(得分:2)
您的?:
运算符的结果为unsigned类型,因为它是int
和unsigned
的常见类型(您的第二和第三操作数)。结果的“期望”值为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)
(将其作为评论输入,但我没有声誉。)