C语言中的条件运算符

C语言中的条件运算符,c,ternary-operator,C,Ternary Operator,每个if…then…else语句是否可以仅使用以下代码转换为等效语句?:代码: if ( flag ) { exit(1); } else { return 0; } 无法转换为: flag ? exit(1) : return 0; 一个更好的例子-这将在一个循环中: if ( flag ) { continue; } else { break; } 无法转换为: flag ? continue : break; 没有 条件表达式的两个“分支”的计算结果必须是相

每个if…then…else语句是否可以仅使用以下代码转换为等效语句?:

代码:

if ( flag ) {
   exit(1);
}
else {
   return 0;
}
无法转换为:

flag ? exit(1) : return 0;
一个更好的例子-这将在一个循环中:

if ( flag ) {
   continue;
}
else {
   break;
}
无法转换为:

flag ? continue : break;
没有

条件表达式的两个“分支”的计算结果必须是相同的类型,并且该类型不能是
void

例如,您可以这样做:

x > 0 ? printf("Positive!\n") : 0;
因为
printf
返回
int
。(不过,我只会在一轮代码高尔夫比赛中使用它;事实上,)

但你不能这样做:

x > 0 ? exit() : 0;

因为
exit
返回
void
(或者实际上根本不返回)。

虽然我能想到的三元运算符的任何用法都可以实现为if/else,但反之则不成立;至少在不使用在性能、可读性或可维护性方面没有任何好处的反常和毫无意义的“技巧”的情况下是如此

if/else的语法为:

if( <boolean expression> )
    <statment>|<statment block>
else
    <statment>|<statment block>
可实施为:

x = b ? y : x ;
但这里的限制是,同一个变量在true和false子句中都被赋值(因此y和z至少都可以转换为x的类型)。所以可以说,任何条件赋值都可以用三元运算符实现(毕竟这是它的主要目的)

既然函数调用是一个有效的表达式,您可以将true和false子句包装在单独的函数中,但这样做只是为了证明某一点有点反常:

if( b )
    true_stuff() ;
else
    false_stuff() ;
相当于:

b ? true_stuff() : false_stuff() ;
这些函数可以包含任何代码

因此,要将更一般的if/else情况转换为?:操作,必须首先将true/false语句块包装在单独的函数中。然而,即使这样,Neil Butterworth的示例也会破坏这种方法,因为
中断
继续
、和
返回
的行为会影响超出if/else构造范围的控制流(尽管这些可能也是您想要避免的代码示例!)。如果在if/else中出现
goto
,也会破坏这种方法


我想最后,即使你可以,你为什么要这样做?

你可以做
返回(flag?exit(1),1:0)
,但那太难看了。@Pavel Radzivilovsky看看这里:只有当我们给某个变量赋值为void时,它才起作用,除非它工作得很好。我想我想出了一个方法,让答案是肯定的;然后看看你的例子!最后,我的建议是适当地使用构造,而不是不正确地使用构造,这使得问题变得无关紧要。例如,您不能编写一个返回
int
并调用
exit(0)
然后返回0的函数吗?然后做
x>0?myExit():0。这是可行的,所以我认为答案实际上是“是的,如果你没有更好的事情做的话”。你可以,但这是毫无意义的。此外,如果if/else语句包含大量代码,而不是一两条语句,则此操作不起作用。只有在尝试分配?:的结果或将其用作参数时,您关于type和void的第一点才是正确的。您的第二个示例至少在MSVC++2008中编译和运行。@Clifford:嗯,您说得对。有趣。在这种情况下,
0
是否转换为
void
。例如,
intmain(){0;}
编译但不生成0的代码;语句(或实际上任何其他未赋值常量表达式)。
if( b )
    true_stuff() ;
else
    false_stuff() ;
b ? true_stuff() : false_stuff() ;