Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Про and, or в логических конструкций, Небольшая заметка 
:(
    Опции темы
EvilsInterrupt
Дата 7.10.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Введение:
Многие из нас при разработке программ, наверное не могут обойтись без составление множества логических конструкций. Здесь я бы хотел не много обратить внимание читателя на некоторые особенности и нюансы.

Немного Теории:
Логическое "И"
Рассмотрим простое утверждение: 1) "Мама и папа дома", однако по факту Мама пошла в магазин за хлебом. Это выражение правдиво?
Чуточку усложним: 2) "Мама, которая сейчас пошла в магазин за хлебом и папа находятся дома", Это выражение правдиво?
Переформулируем предложение: 3) "Папа дома и Мама, которая сейчас стоит в очереди в магазине, тоже дома". Это выражение тоже правдиво?

Конечно оба предложения ложны. Но почему то большинство программистов забывают об этих очевидных вещах!!! Ведь явно же видно что мама сейчас в магазине и смысла нет проверять, а дома ли папа? Вот и компилятор точно также, проверяет сначала одно под_условие, входящее в одно сложное условие и если оно ложно,то сколько бы не было под_условий после потом, он их рассматривать не будет! Т.к. уже известен результат!

Логическое "ИЛИ"
Берем опять 3) из Логическое "и". Если папа дома, то нет смысла проверять дальше, т.к. результат уже известен! Компилятор
видя конструкцию:

if (cond1) or (cond2) or (cond3) then

расссудит так: "Ха, раз cond1 истина, значит можно выполнять все что в then begin ... end; и наоборот. то что cond1 ложно, это еще значит, что cond2 тоже ложно!

Вывод:
Составляя большие условия, надо рассматривать а какое под условие наибольшую вероятность имеет быть в ложном или истинном состоянии? А какое чуточку меньше имеет вероятность быть в ложном или истинном? Зная эти особенности вы построете более эффективный код при выполнении. Почему?
Потому что:
1) Во первых быстрта проверки условия
2) Процессор имеет механизм предсказывания о том, какой код будет в дальнейшем. Следовательно правильно построенное условие, экономит процессору на его промахах!.

Нюансы:
Сам только сегодня открыл, хотелось бы предостеречь других от ошибки. Итак у меня код:
private:
Код

 FPluginList : TList;
// много кода
  procedure TPluginManager.SetPlugin(Index: Integer; const aPlugin: TPlugin);
  var
    Plugin : TPlugin;
  begin
    if (FPluginList.Count > 0) and (FPluginList <> Nil) and
       (Index >= 0) and (Index < FPluginList.Count) then
    begin
      Plugin := TPlugin(FPluginList.Items[Index]);
      if Plugin <> Nil then
         Plugin.Handle := aPlugin.Handle;
    end;
  end;


Казалось бы корректный код,но! Я специально привел код именно в таком виде, т.к. код содержит не очевидную на первый взгляд особенность и в конечном итоге выливается в возможную багу при некоторых условиях.
Задаем вопрос: "А что если FPluginList не создан, что тогда?", ответ прост: "Будет бага!" и вот почему, в первом же под_условии смысл которого это проверка на кол-во элементов выполняется так, как будто бы FPluginList уже создан! А вдруг до применения этого метода FPluginList еще не создали? Логичней и правильней было бы вынести на первое место под_условие №2, в котором проверка на Nil.

Это код, можно чуточку с оптимизировать, поставив (Index >= 0) самым, первым, т.к. если мы передадим отрицательный индекс, то сразу же выйдем из метода тем самым сэкономим время на проверке трех других под_условиях. Хотя есть некоторые, зверюшки, которые сомневаются в целесообразности этого трюка smile))

Это сообщение отредактировал(а) EvilsInterrupt - 8.10.2007, 06:10
PM MAIL WWW ICQ Jabber   Вверх
volvo877
Дата 7.10.2007, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 9
Всего: 116



Цитата(EvilsInterrupt @  7.10.2007,  13:44 Найти цитируемый пост)
хотелось бы предостеречь других от ошибки

Только учти, что если в Project -> Option -> Compiler будет отмечена галка "Complete Boolean Eval", то то что ты написал - не поможет... Выражение будет выполняться полностью, следовательно по прежнему будет бага... Избежать этого можно с помощью использования ключа компиляции {$B-} (поскольку ключ компиляции имеет более высокий приоритет, чем настройки проекта)
PM MAIL   Вверх
MetalFan
Дата 7.10.2007, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(EvilsInterrupt @  7.10.2007,  14:44 Найти цитируемый пост)
(FPluginList.Count > 0) and (FPluginList <> Nil)

а я бы еще как минимум местами эти проверки поменял.
ибо если у тебя FPluginList=nil, то словишь AV при проверке первого условия


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 7.10.2007, 20:13 (ссылка)  | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



MetalFan, Уважаемый, читаем вниматильней, что я писал: 
Цитата

Сам только сегодня открыл, хотелось бы предостеречь других от ошибки. Итак у меня код:
,
 из этого следует что дальше идет пример кода! Подчеркну, пример кода! ;) Потом читаем: 
Цитата

Что если FPluginList не создан? Будет бага, в прорвом же под_условии на проверку
.

Из этих слов следует, что я знал о баге!!! Раз знал значит специально привел именно такой код! А почему? Да потому что: 
Цитата

Что если FPluginList не создан? 


Я конечно сумбурно выражаюсь, но если внимательно читать. То понять можно )))
PM MAIL WWW ICQ Jabber   Вверх
MetalFan
Дата 7.10.2007, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



EvilsInterrupt, у тебя итоговая мысль, что надо вперед поверку на Index >= 0 вынести. что имхо логически некрасиво будет)

Цитата(EvilsInterrupt @  7.10.2007,  20:13 Найти цитируемый пост)
сумбурно выражаюсь

верно подметил)



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 8.10.2007, 06:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



MetalFan, я немного подправил, думаю сейчас поменьше сумбурности ;)
PM MAIL WWW ICQ Jabber   Вверх
bems
Дата 8.10.2007, 17:23 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



а вот я однажды наткнулся
Код

function GetWordCount(const s:string):byte;
 begin
 result:=5//представим что в строке больше одного слова и мы это правильно пощитали
 end;

 function MoreThanOneWord(const s:string):boolean;
 begin
 result:=boolean(GetWordCount(s)-1);//если значение в скобках не равно нулю, то в  result получим истину
 end;

 function INeedMoreThanOneWord:boolean;
 begin
 result:=true//тут я типа прочитал настройки и присвоил истину
 end;

var a,b:boolean;
begin
a:=INeedMoreThanOneWord;
b:=MoreThanOneWord('Превед, медвед!');
if a then writeln('a=true');
if b then writeln('b=true');
if a=b then writeln('then')
       else writeln('else');
readln
end;

а выведется тут
Код

a=true
b=true
else

потому что если даже две переменные истина, то их равенство зависит от сравнения их как чисел.
т. е. 
Код

a=b
и
Код

(a and b) or ((not a) and (not b))
это не одно и тоже


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Esperito
Дата 8.10.2007, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 2.9.2007

Репутация: нет
Всего: 3



bems, раз уж ты делаешь прямое преобразование вместо того, чтобы написать
Код

Result := GetWordCount(s) > 1;

тогда уж объявляй переменные a и b как LongBool вместо Boolean.
PM MAIL   Вверх
bems
Дата 9.10.2007, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(Esperito @  8.10.2007,  21:19 Найти цитируемый пост)
bems, раз уж ты делаешь прямое преобразование 
я уже давно так не делаю. Как раз после того, как натолкнулся на такую тонкость

Цитата(Esperito @  8.10.2007,  21:19 Найти цитируемый пост)
тогда уж объявляй переменные a и b как LongBool вместо Boolean. 

смотрим сюда
Цитата(bems @  8.10.2007,  17:23 Найти цитируемый пост)
function GetWordCount(const s:string):byte;




--------------------
Обижено школьников: 8
PM MAIL   Вверх
Esperito
Дата 10.10.2007, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 2.9.2007

Репутация: нет
Всего: 3



И что? Я же про переменные a и b.
PM MAIL   Вверх
bems
Дата 10.10.2007, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(Esperito @  8.10.2007,  21:19 Найти цитируемый пост)
объявляй переменные a и b как LongBool вместо Boolean
почему?



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Esperito
Дата 11.10.2007, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 147
Регистрация: 2.9.2007

Репутация: нет
Всего: 3



Тогда то самое сравнение
Код

if a=b then writeln('then')

будет давать корректный результат.
PM MAIL   Вверх
bems
Дата 11.10.2007, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



да. так и есть. туплю


--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1249 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.