Цепочка нескольких больше чем / меньше чем операторы - PullRequest
5 голосов
/ 05 августа 2011

В оператор if я хочу включить диапазон, например:

if(10 < a < 0)

, но при этом я получаю предупреждение «Бессмысленное сравнение».Тем не менее, это прекрасно работает без каких-либо предупреждений:

if(a>10 && a<0)

Возможно ли реализовать первый случай в C?

Ответы [ 6 ]

28 голосов
/ 05 августа 2011

Обратите внимание, что оригинальная версия совершенно легальна; он просто не делает то, что вы (разумно) думаете, что делает. Вам повезло, что компилятор признал это вероятной ошибкой и предупредил вас об этом.

Оператор < ассоциируется слева направо, как и оператор +. Так как a + b + c действительно означает (a + b) + c, a < b < c действительно означает (a < b) < c. Оператор < возвращает значение int 0, если условие ложно, и 1, если оно истинно. Таким образом, вы либо проверяете, меньше ли 0, чем c, либо 1 меньше, чем c.

В маловероятном случае, если это действительно то, что вы хотите сделать, добавление скобок, вероятно, отключит предупреждение. Любой, кто читает ваш код позже, также заверит вас в том, что вы знаете, что делаете, поэтому они не «исправят» это. (Опять же, это применимо только в том маловероятном случае, когда вы действительно захотите (a < b) < c).)

Способ проверки, является ли a меньше b и b меньше c:

a < b && b < c
6 голосов
/ 05 августа 2011

Это невозможно, вы должны разделить чек, как вы это делали в случае 2.

5 голосов
/ 05 августа 2011

Нет, это невозможно.
Вы должны использовать второй способ, разделив две условные проверки.

2 голосов
/ 05 августа 2011

Первый выполняет одно сравнение, затем сравнивает результат первого со вторым значением. В этом случае группа операторов слева направо, поэтому она эквивалентна (10<a) < 0. Предупреждение, которое он вам дает, действительно потому, что < всегда будет давать 0 или 1. Предупреждение говорит вам, что результат первого сравнения никогда не может быть меньше 0, поэтому второе сравнение всегда будет давать false.

Несмотря на то, что компилятор не будет жаловаться на это, второе не очень хорошее улучшение. Как число может быть одновременно меньше 0, но больше 10? В идеале компилятор должен предупреждать вас, что условие всегда ложно. Предположительно, вы хотите 0<a<10 и a>0 && a<10.

Вы можете получить эффект секунды, используя только одно сравнение: if ((unsigned)a < 10) будет истинным, только если число находится в диапазоне 0..10. Сравнение диапазона обычно сводится к одному сравнению с кодом, подобным:

if ((unsigned)(x-range_start)<(range_end-range_start))
    // in range
else
    // out of range.

Когда-то это был главный продукт приличного программирования на ассемблере. Я сомневаюсь, что многие люди делают это больше (я, конечно, не как правило).

0 голосов
/ 05 августа 2011

Как указано выше, вы должны разделить чек. Подумайте об этом с точки зрения компилятора, который рассматривает один оператор за раз. 10

0 голосов
/ 05 августа 2011

нет, это недопустимый синтаксис оператора if, он должен иметь действительное константное выражение или может содержать логические операторы и выполняться только, когда выражение в скобках принимает значение true или ненулевое значение

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