【发布时间】:2023-04-03 12:44:01
【问题描述】:
是否可以将每个 if...then...else 语句转换为仅使用的等效语句?:
【问题讨论】:
标签: c ternary-operator
是否可以将每个 if...then...else 语句转换为仅使用的等效语句?:
【问题讨论】:
标签: c ternary-operator
虽然我能想到的三元运算符的任何用途都可以实现为 if/else,但反之则不成立;至少在不使用在性能、可读性或可维护性方面没有任何好处的不正当和毫无意义的“技巧”的情况下是这样。
if/else 的语法是:
if( <boolean expression> )
<statment>|<statment block>
else
<statment>|<statment block>
而 ?: 三元运算符的语法是:
<boolean expression> ? <expression> : <expression> ;
这里重要的是<expression> 和<statement> 是不同的句法元素。
表单的使用非常有限:
if( b ) x = y else x = z ;
可以实现为:
x = b ? y : x ;
但这里的限制是在 true 和 false 子句中都分配了相同的变量(因此 y 和 z 至少都可以转换为 x 的类型)。所以可以说,任何条件赋值都可以用三元运算符来实现(毕竟这是它的主要目的)。
既然函数调用是一个有效的表达式,你可以将真假子句包装在单独的函数中,但这样做只是为了证明一个观点有点不正当:
if( b )
true_stuff() ;
else
false_stuff() ;
相当于:
b ? true_stuff() : false_stuff() ;
这些函数可以包含任何代码。
因此,要将更一般的 if/else 情况转换为 ?: 操作,必须首先将 true/false 语句块包装在单独的函数中。然而即便如此,Neil Butterworth 的示例仍将击败这种方法,因为 break、continue 和 return 的行为会影响超出 if/else 构造范围的控制流(尽管这些可能也是您想要的代码示例避免!)。在 if/else 中出现goto 也会破坏这种方法。 .
我想最后,即使你可以,你为什么要这样做?
【讨论】:
没有。
条件表达式的两个“分支”必须计算为相同的类型,并且该类型不能是void。
例如,您可以这样做:
x > 0 ? printf("Positive!\n") : 0;
因为printf 返回int。 (不过,我只会在一轮代码高尔夫中使用它;事实上,I just did。)
但你不能这样做:
x > 0 ? exit() : 0;
因为exit 返回void(或者,实际上,根本不返回)。
【讨论】:
int,然后调用exit(0),然后返回0吗?然后做x > 0 ? myExit() : 0;。这会起作用,所以我认为答案实际上是“是的,如果你没有更好的事情可做”。
0 是否会转换为 void?
int main(){ 0;} 编译但不为 0 生成代码;语句(或实际上任何其他未分配的常量表达式)。
代码:
if ( flag ) {
exit(1);
}
else {
return 0;
}
无法转换成:
flag ? exit(1) : return 0;
一个更好的例子 - 这将在一个循环内:
if ( flag ) {
continue;
}
else {
break;
}
无法转换为:
flag ? continue : break;
【讨论】:
return (flag ? exit(1),1 : 0),但这太丑了。