Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > выход из if


Автор: _hunter 30.5.2004, 15:57
произойдет ли выход из if' a в такой конструкции:
if ( ( a ) || ( b ) || ( c ) )
при первом true (т.е. проверка b и c выполнятся не будет )
, а из такой:
if ( ( a ) && ( b ) && ( c ) )
при первом false?

Заранее благодарю за ответ.



Автор: Elfet 30.5.2004, 16:08
Из первой нет,
а из второго да, выдет тобишь.

Автор: p0s0l 30.5.2004, 16:31
В Delphi есть такая опция "Complete boolean eval", возможно она есть и в BC... Если её включить, то выражение будет всегда досчитываться до конка, даже если уже результат известен...
В обоих случаях || или && один раз всё равно сделается, а потом уже будет происходить проверка (это более эффективно с точки зрения оптимизации)...

Автор: Дрон 30.5.2004, 17:50
Цитата
В Delphi есть такая опция "Complete boolean eval", возможно она есть и в BC...

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

Автор: p0s0l 30.5.2004, 20:09
Дрон, ну может и так, я в этом не особого сведущ...
Только странный стандарт получается...
Пример:
if ( ( a ) || ( b ) || ( c ) || ( somefunc1() ) )
somefunc1 - какая-то функция.
Если a==true, то somefunc1 не вызовется, а если она делает что-то критично важное (бывают такие случаи), то будет облом.
По-крайней мере в Delphi по-умолчанию complete boolean eval отключено, и была прога, где я долго голову ломал, из-за чего она не работает (тогда я не знал об этой фиче). Оказалось, что этот somefunc1 не вызывался...
Конечно, можешь сказать: "ставь somefunc1" в начало if'а", но что если таких somefunc'ов несколько ?...

Автор: Дрон 30.5.2004, 21:18
Цитирую из книги Кернигана и Ричи "Язык С":

Цитата
... Выражения,  связанные операциями && или || , Рассматриваются слева на право, и при этом гарантируется, что оценивание выражений будет прекращено, как только станет ясно, является ли все выражение истинным или ложным...
... В данном случае это не имеет принципиального значения, но, как мы скоро увидим, в более сложных ситуациях эта особенность языка весьма существенна.


Автор: Anklav 30.5.2004, 21:22
Цитата
но что если таких somefunc'ов несколько

А что если эти функции будут очень большими, на вычисление которых уходит много времени.
Тут уже прямо сказать нельзя, что лучше. Поэтому, наверно, в стандарте чётко и ясно сказано, что лишнее не будет выполняться.
А вот возможность переключение "режима", по моему мнения, - плохо, т.к. может быть такое, что в одной части кода для нормальной работы должна быть включена эта опция, а для другой выключена, а это потеря времени и всё такое.

Автор: Дрон 30.5.2004, 21:23
Я, кстати, в своих прогах иногда пишу так:
Код
if (n<ArraySize && Array[n] == Something) { ... }

Если n выходит за границы массива, то и заглядывать в массив мы не будем.
Так что для меня эта особенность полезна.

Автор: p0s0l 30.5.2004, 21:36
Согласен, что в подавляющем большинстве случаев это и лучше и полезнее и удобнее... Поэтому видимо это "зашили" в стандарт в Си...
Цитата
А вот возможность переключение "режима", по моему мнения, - плохо, т.к. может быть такое, что в одной части кода для нормальной работы должна быть включена эта опция, а для другой выключена, а это потеря времени и всё такое.

Ну там (в delphi/pascal) это решалось бы с помощью директив {$B+} и {$B-}, так что это не является неудобством... Но тут речь не о Delphi...
Цитата
Я, кстати, в своих прогах иногда пишу так:

Код 
if (n<ArraySize && Array[n] == Something) { ... }

Если n выходит за границы массива, то и заглядывать в массив мы не будем.
Так что для меня эта особенность полезна.

Согласен. Тоже так же делаю...

Всё, вопросов больше не имею smile.gif

Автор: gray_k 31.5.2004, 08:23
С++ делает так:
if( (a) || (b) || © ) -
если a = true, то b и c не проверяется, все выражение есть истина,
иначе, если b=true, то с не проверяется, все выражение - истина,
иначе, если c=true, то выражение - истина,
иначе - выражение- фальш.


if( (a) | (b) | (с) )
проверить a, b, c, затем истинность выражения.

Автор: gepard 31.5.2004, 09:02
p0s0l
Цитата
Если a==true, то somefunc1 не вызовется, а если она делает что-то критично важное (бывают такие случаи), то будет облом.

А ты сделай так:
Код

if ( somefunc1() || a || b || c)

В таком случае твоя жизненно-необходимая функция выполнится в любом случае.

gray_k
Цитата
if( (a) | (b) | (с) )
проверить a, b, c, затем истинность выражения.

Поясни, plz.

Автор: DENNN 31.5.2004, 09:43
Цитата
но что если таких somefunc'ов несколько

Если вычисление их значений необъодимо, то такие функции ставят на первое место.
А в целом, если возникла такая проблема, то это говорит о плохом стиле написания кода.
Никто ведь не мешает присвоить это значение локальной переменной и потом ее проверить?

Автор: gray_k 31.5.2004, 10:37
Цитата
Поясни, plz.

Ну, например, если у тебя в условии несколько выражений, которые все надо выполнить, то надо использовать не логические операторы && и ||, а поразрядные логические операторы & и |. Их применение гарантирует, что все выражения, входящие в условие будут выполнены.
Пример:
Код

//глобальные перпеменные
int a = 1, b=2;
bool f1()
{
  if( a == 1 ) {
    b = 0;
     return true;
  }
   else
     return false;
}

bool f2()
{
 if( b == 2 )
   return true;
 else {  
   b = 2;
   return false;
 }
}

//теперь в после выполенения такого условия
if( f1() || f2() )
//b будет равно 0

//а после такого
if( f1() | f2() )
// b будет равно 2

Добавлено @ 10:38
Цитата
А в целом, если возникла такая проблема, то это говорит о плохом стиле написания кода.

Очень категоричное суждение.

Автор: Дрон 31.5.2004, 12:44
Только следует заметить, что || и | ведут себя немного по-разному:
2 && 1 даст true.
2 & 1 даст 0 (что эквивалентно false).

Добавлено @ 12:46
DENNN
Цитата
А в целом, если возникла такая проблема, то это говорит о плохом стиле написания кода.
Согласен. Всегда можно сделать по-другому.

Автор: gepard 31.5.2004, 15:08
gray_k и Дрон
Мерси. Теперь, вроде, понял.

Автор: p0s0l 31.5.2004, 15:22
Цитата
А в целом, если возникла такая проблема, то это говорит о плохом стиле написания кода.

Совершенно верно. smile.gif
Цитата
2 && 1 даст true.
2 & 1 даст 0 (что эквивалентно false).

Может тогда арифметическое умножение (*) использовать, а не логическое (&) ? Правда, это медленнее...

Цитата
Согласен. Всегда можно сделать по-другому.

Нет ничего такого, чего нельзя было бы сделать более чем одним способом...
Добавлено @ 15:24
gepard
Цитата
p0s0l

Цитата 
Если a==true, то somefunc1 не вызовется, а если она делает что-то критично важное (бывают такие случаи), то будет облом.

А ты сделай так:

Код 

if ( somefunc1() || a || b || c)


В таком случае твоя жизненно-необходимая функция выполнится в любом случае.

Я на это уже ответил на первой странице...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)