Хотя с несколькими условиями - PullRequest
3 голосов
/ 02 мая 2010

Может кто-нибудь объяснить, почему выражение (я изучаю C), как

while(a!=1 || b!=1 || c!=1)

вызывает проблемы.

В частности, у меня есть этот конкретный код:

while (ch != '\n' || ch != '\t' || ch != ' ') { ... } 

Ответы [ 4 ]

7 голосов
/ 02 мая 2010

ОБНОВЛЕНИЕ : Согласно вашему другому комментарию, ваше выражение неверно - оно не имеет ничего общего с "while", имеющим несколько условий.

ch != '\n' || ch != ' ' ВСЕГДА верно, независимо от того, какие символы.

Если символ НЕ является пробелом, второе условие истинно, поэтому ИЛИ истинно.

Если символ является пробелом, первое условие истинно (так как пробел не является новой строкой) и ИЛИ истинно.

Правильный путь ch != '\n' && ch != ' ' ...

СТАРЫЙ ответ:

При нормальных обстоятельствах нет никаких проблем с приведенным выше выражением (при условии, что вы хотели именно это).

Единственная проблема, связанная с вашим, заключается в том, что иногда она может быть меньше оптимальной (например, если b и c никогда не меняются в цикле, в этом случае вам необходимо кэшировать значение b!=1 в переменной).

while с несколькими условиями может иметь проблему в одном случае - , если эти несколько условий действительно имеют предполагаемые побочные эффекты .

Это связано с ленивой оценкой || и && в C, так что если первое выражение истинно, остальные НЕ будут оцениваться и, следовательно, их побочные эффекты не произойдут.

4 голосов
/ 02 мая 2010

Это совершенно правильно. Но это зависит от того, что вы хотите, возможно, вы имеете в виду && вместо ||

3 голосов
/ 02 мая 2010

Вы должны быть осторожны при использовании не в логических выражениях, чтобы не перепутать AND и OR. Читайте о законах де Моргана . Часто легче читать только с одним негативом. Применение закона де Моргана к вашему выражению дает следующее:

while (!(ch=='\r' && ch=='\n' && ch==' '))

Если вы написали это в этой форме, вы, надеюсь, немедленно заметите, что (ch == '\ r' && ch == '\ n') никогда не может быть правдой.

Решение состоит в том, чтобы изменить это:

while (ch != '\n' || ch != '\t' || ch != ' ')

в это:

while (!(ch == '\n' || ch == '\t' || ch == ' '))

Вы можете прочитать это как "Пока у нас нет \ n или \ t или пробела, сделайте это ...". Обратите внимание, что «while not» похоже на «then» в английском (и некоторых языках программирования), поэтому вы также можете прочитать его как «Пока у нас нет \ n или \ t или пробела, делайте это».

0 голосов
/ 02 мая 2010

К какой проблеме вы обращаетесь? Это обычно имеет смысл как:

while(a == 1 || b == 1 || c == 1)  

Или

while(a != 1 && b != 1 && c != 1)

Но нет проблем с выражением, которое у вас есть, если вы этого хотите.

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