?: поведение троичного условного оператора, когда одно выражение оставлено пустым - PullRequest
34 голосов
/ 23 июля 2010

Я писал консольное приложение, которое пыталось бы «угадать» число методом проб и ошибок, оно работало нормально и все, но это заставило меня задуматься об определенной части, которую я написал рассеянно,

Код:

#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 (или ложь), все выражение будет иметь значение 1 ((100/(i<<=1))?:***1***), и я оставил часть условия, которая будет работать, если бы она была действительно пустой ((100/(i<<=1))? _this space_ :1), похоже, работает правильно, но есть ли риск оставить эту часть условного пустым?

Ответы [ 2 ]

56 голосов
/ 23 июля 2010

Это расширение GNU C (см. ?: запись в википедии ), поэтому для переносимости вы должны явно указать второй операнд.

В «истинном» случае оно возвращаетрезультат условного выражения.

Следующие операторы почти эквивалентны:

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

Разница только в первом утверждении, x всегда вычисляется один раз, тогда как во втором,x будет оцениваться дважды, если это правда.Таким образом, единственная разница заключается в том, что при оценке x есть побочные эффекты.

В любом случае, я бы счел это тонким использованием синтаксиса ... и если у вас есть сочувствие тем, кто поддерживает ваш код,должен явно указать операнд.:)

С другой стороны, это хороший маленький трюк для общего случая использования.

18 голосов
/ 23 июля 2010

Это расширение GCC для языка Си.Если между ?: ничего не появляется, тогда значение сравнения используется в истинном случае.

Средний операнд в условном выражении может быть опущен.Тогда, если первый операнд отличен от нуля, его значением является значение условного выражения.

Следовательно, выражение

x ? : y

имеет значение x, если этоненулевой;в противном случае значение y.

Этот пример полностью эквивалентен

x ? x : y

. В этом простом случае возможность опустить средний операнд не особенно полезна.,Когда это становится полезным, это когда первый операнд имеет, или может (если это макропараметр) содержать побочный эффект.Затем повторение операнда в середине будет выполнять побочный эффект дважды.Пропуск среднего операнда использует уже вычисленное значение без нежелательных последствий его повторного вычисления.

...