?:当一个expression式为空时的三元条件运算符行为

我正在编写一个控制台应用程序,试图通过反复试验来“猜测”一个数字,它运行良好,但是所有这些都让我不知道我写了些什么,

代码是:

#include <stdio.h> #include <stdlib.h> int main() { int x,i,a,cc; for(;;){ scanf("%d",&x); a=50; i=100/a; for(cc=0;;cc++) { if(x<a) { printf("%d was too big\n",a); a=a-((100/(i<<=1))?:1); } else if (x>a) { printf("%d was too small\n",a); a=a+((100/(i<<=1))?:1); } else { printf("%d was the right number\n-----------------%d---------------------\n",a,cc); break; } } } return 0; } 

更具体地说,困惑我的部分是

 a=a+((100/(i<<=1))?:1); //Code, code a=a-((100/(i<<=1))?:1); 

我使用((100/(i<<=1))?:1)确保如果100/(i<<=1)返回0(或false),整个expression式将评估为1 ((100/(i<<=1))?:***1***)如果它真的是空的((100/(i<<=1))? _this space_ :1) ,那么我就离开了这个有效的条件的一部分((100/(i<<=1))? _this space_ :1) ,它似乎工作正常,但有没有任何风险留下条件空的那部分?

这是一个GNU C扩展(请参阅?:wikipedia条目 ),因此为了便于携带,您应该明确声明第二个操作数。

在“真”情况下,它返回条件的结果。

以下声明几乎等同于:

 a = x ?: y; a = x ? x : y; 

唯一的区别是在第一个语句中, x总是被评估一次,而在第二个语句中,如果x是真的,它将被评估两次。 所以唯一的区别是评估x有副作用。

无论哪种方式,我都认为这是对语法的巧妙使用……如果您对维护您的代码的人有任何同情心,您应该明确声明操作数。 🙂

另一方面,这是一个常见用例的一个很好的小窍门。

这是C语言的GCC扩展 。 当?:之间没有任何出现时,比较的值将用于真实情况。

条件expression式中的中间操作数可以省略。 那么如果第一个操作数是非零的,那它的值就是条件expression式的值。

因此,expression

x ? : y

如果非零,则有x的值; 否则,y的值。

这个例子完全等同于

x ? x : y

在这种简单的情况下,省略中间操作数的能力并不是特别有用。 当第一个操作数有用时,或者可能(如果它是macros参数)包含副作用。 然后在中间重复操作数会执行两次副作用。 省略中间操作数使用已计算的值,而没有重新计算它的不良影响。