我需要根据条件将双数转换为整数,但是当我使用三元运算符时,我会得到一些奇怪的结果。我写了这个简单的程序来测试我的逻辑,但是我无法理解它是怎么回事。
#include <stdio.h>
int main()
{
double n = 50.0;
printf("%i\n", (int)n);
printf("%i\n", ((1) ? (int)n : n));
printf("%i\n", ((1) ? n : (int)n));
printf("%i\n", ((0) ? (int)n : n));
printf("%i\n", ((0) ? n : (int)n));
return 0;
}
我希望得到以下输出:
50
50
0
0
50
但我得到的输出是:
50
0
0
0
0
答案 0 :(得分:2)
当三元运算符的第2和第3个操作数具有不同的类型时,它们将使用usual arithmetic conversions自动转换为相同的类型。因此,对其中一个操作数进行强制转换并不会产生预期效果 - (int) n
将被强制转换为double
,这将是三元表达式的类型。
这将传递给printf
,您将获得未定义的行为,因为您尝试使用double
格式打印%i
,该格式需要int
}。
如果您希望参数的类型取决于条件,则需要使用普通的if
。例如,这是你在第一个三元例子中显然要完成的事情:
if (1) {
printf("%i\n", (int) n); // valid
} else {
printf("%i\n", n); // invalid
}
答案 1 :(得分:1)
你同时绊倒了C语言的两个黑暗角落。
鉴于double n
,“usual arithmetic conversions”原因(ANYTHING ? (int)n : n)
和(ANYTHING ? n : (int)n)
都有double
类型。也就是说,如果采用(int)n
分支,则值n
将转换为int
,然后再转回double
。
printf("%i\n", (double)whatever)
引发未定义的行为。这是因为printf
依赖于其格式字符串来了解其可变参数的类型。如果您告诉它打印int
但是您传递了double
,则会在错误的位置查找要打印的值。
由于(1),(2)影响包含三元表达式的所有四个printf
语句,而不仅仅是那些未执行转换为int
分支的语句。
我不明白你试图用(condition ? (int)n : n)
完成什么,所以我不能告诉你应该做些什么。
答案 2 :(得分:1)
在&#39;条件运算符&#39;的标准中,它说:
如果第二个和第三个操作数都有算术类型,那么通常的算术转换确定的结果类型是应用于这两个操作数的结果类型,是结果的类型。
由于您有int
和double
作为类型,因此条件的结果始终为double
,因此当您使用错误的格式打印时,您将获得任何垃圾 - 这是调用未定义的行为和一个坏主意