2010-05-01 6 views
3

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

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

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

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

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

Есть ли более подробная информация по этому вопросу? – Eric

+0

Приоритет оператора? – Eilon

+1

Я отредактировал вопрос, чтобы включить важную информацию из комментариев. –

ответ

7

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

ch != '\n' || ch != ' ' ВСЕГДА ИСТИНА, независимо от характера.

Если символ НЕ является пробелом, второе условие истинно, так что OR является истинным.

Если символ является пространством, первое условие истинно (поскольку пространство не является символом новой строки), а OR - true.

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

OLD Ответ:

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

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

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

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

4

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

+0

У меня есть выражение вот так: while (ch! = '\ N' || ch! = '\ T' || ch! = '') ... Мне нужно прекратить чтение символов, если я встречаю вкладку или белый цвет пробел или введите – lego69

+0

, но я не могу выйти из цикла, так что может быть проблемой? – lego69

+2

@ lego69: Тогда @ComputerGuru является правильным, и вы смешиваете '&&' и '||'. 'ch! = '\ n' || ch! = '\ t' || ch! = '' 'всегда' истина'. – sepp2k

3

Вы должны быть осторожны при использовании не в булевых выражениях, которые вы не получите И и ИЛИ смешаны. Читайте о De Morgan's Laws. Часто его легче читать только с одним отрицательным. Применяя закон Де Моргана к вашему выражению дает это:

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

Если бы вы написали его в таком виде вы будете надеяться, что немедленное уведомление (ч == «\ г» & & ч == «\ п») может никогда не будет правдой.

Решение изменить это:

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

в этом:

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

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

+0

@Mark - +1 (частично потому, что вы редактировали вопрос, чтобы его создать :)) – DVK

0

В чем проблема? Это, как правило, имеет смысл, как:

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

Или

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

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

Смежные вопросы