Условный оператор в Си - PullRequest
4 голосов
/ 03 апреля 2010

может ли каждый оператор if ... then ... else быть преобразован в эквивалентный оператор, используя только?:

Ответы [ 3 ]

7 голосов
/ 03 апреля 2010

код:

if ( flag ) {
   exit(1);
}
else {
   return 0;
}

не может быть преобразовано в:

flag ? exit(1) : return 0;

Лучший пример - это будет внутри цикла:

if ( flag ) {
   continue;
}
else {
   break;
}

не может быть преобразовано в:

flag ? continue : break;
3 голосов
/ 03 апреля 2010

Хотя любое использование тернарного оператора, которое я могу себе представить, может быть реализовано как if / else, обратное утверждение неверно; по крайней мере, не прибегая к извращенным и бессмысленным «уловкам», которые не приносят никакой выгоды с точки зрения производительности, читабельности или удобства обслуживания.

Синтаксис if / else:

if( <boolean expression> )
    <statment>|<statment block>
else
    <statment>|<statment block>

, тогда как синтаксис троичного оператора?:: 1006 *

<boolean expression> ? <expression> : <expression> ;

Здесь важно то, что <expression> и <statement> - это разные синтаксические элементы.

Очень ограниченное использование формы:

if( b ) x = y else x = z ;

может быть реализовано как:

x = b ? y : x ;

но здесь ограничение заключается в том, что одна и та же переменная присваивается как в выражениях true, так и в ложных (и, следовательно, y и z оба, по крайней мере, могут быть преобразованы в тип x). Таким образом, можно сказать, что любое условное присвоение может быть реализовано с помощью троичного оператора (после всего, что является его основной целью).

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

if( b )
    true_stuff() ;
else
    false_stuff() ;

эквивалентно:

b ? true_stuff() : false_stuff() ;

и эти функции могут содержать любой код вообще.

Таким образом, чтобы преобразовать более общий случай if / else в операцию?: Сначала блоки операторов true / false должны быть заключены в отдельные функции. Однако даже в этом случае примеры Нила Баттерворта победят этот подход, поскольку поведение break, continue и return влияет на поток управления за пределами конструкции if / else (хотя, возможно, это также примеры кода, который вам нужен избежать!). Наличие goto в if / else также нарушит этот подход. .

Думаю, в конце концов, даже если бы вы могли, зачем вам это нужно?

1 голос
/ 03 апреля 2010

номер

Обе "ветви" условного выражения должны иметь одинаковый тип, и этот тип не должен быть void.

Например, вы можете сделать это:

x > 0 ? printf("Positive!\n") : 0;

потому что printf возврат int. (Я бы использовал это только в раунде гольф-кода, хотя, на самом деле, я только что сделал .)

Но вы не можете сделать это:

x > 0 ? exit() : 0;

потому что exit возвращает void (или вообще не возвращает).

...