?:将一个表达式留空时的三元条件运算符行为

Too*_*red 37 c ternary-operator conditional-operator ternary

我正在编写一个控制台应用程序,试图通过反复试验来"猜测"一个数字,它工作得很好,除了它让我想知道某个部分是我心不在焉地写的,

代码是:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

我曾经((100/(i<<=1))?:1)确保如果100/(i<<=1)返回0(或错误),整个表达式将计算为1 ((100/(i<<=1))?:***1***),并且我离开条件的部分,如果它是真的空的((100/(i<<=1))? _this space_ :1),它会工作,它似乎工作正常但是有离开的风险条件空的那部分?

Ste*_*hen 58

这是GNU C扩展(参见?:wikipedia条目),因此为了便于移植,您应该明确说明第二个操作数.

在'true'的情况下,它返回条件的结果.

以下陈述几乎相同:

a = x ?: y;
a = x ? x : y;
Run Code Online (Sandbox Code Playgroud)

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

无论哪种方式,我都认为这是对语法的一种微妙使用......如果你对维护代码的人有任何同情心,你应该明确说明操作数.:)

另一方面,对于常见用例来说,这是一个不错的小技巧.

  • 几乎等效的......除了`x`在`x?:y`中只评估一次. (5认同)

Mat*_* B. 19

这是C语言的GCC扩展.当两者之间没有出现时?:,则在真实情况下使用比较的值.

可以省略条件表达式中的中间操作数.然后,如果第一个操作数非零,则其值为条件表达式的值.

因此,表达

    x ? : y

如果非零,则其值为x; 否则,y的值.

这个例子完全等同于

    x ? x : y

在这个简单的例子中,省略中间操作数的能力并不是特别有用.当它变得有用时是第一个操作数,或者可能(如果它是一个宏参数),包含副作用.然后在中间重复操作数将执行两次副作用.省略中间操作数使用已经计算的值而没有重新计算它的不良影响.