Логически оператори в C
Логически оператори
Булевите оператори са оператори, които приемат булеви стойности (false или true) като аргументи и връщат булева стойност. Подобно на обикновените оператори, те могат да бъдат едноместни (унарни, т.е. приемат един аргумент), двуместни (двоични, приемат два аргумента), тройни и т.н.
Характеристика на езика C е, че той няма тип, който съхранява булева стойност (false или true). В C цяло число 0 се счита за невярно (логическа нула) и всяко ненулево цяло число ще бъде логическа истина. Например
Булевите стойности обикновено се генерират от операторите за сравнение (==, !=, >, =. Операторът NOT (NOT) се използва за обръщане на стойността на аргумента. Тоест, ако е предадено true, ще върне false, ако е получило false като аргумент, ще върне true.
0 | 1 |
1 | 0 |
В C отрицанието се представя от оператора !. Например
Както в обикновената логика, тук действа законът за двойното отрицание - отрицанието на отрицанието може да бъде пропуснато.
логично И
Операторът И (И, логическо умножение) връща истина, ако и само ако и двата аргумента са верни.
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
В C логическото умножение е представено от оператора &&. Например, задачата е само пълнолетни мъже да бъдат допускани в кръга на военните космически кораби. Тоест кандидат може да стане само този, за когото са валидни и двете условия едновременно.
И операторможе да се прилага последователно към множество аргументи. За него важат асоциативни и комутативни закони. Ще подобрим програмата, ще въведем и растеж:
Освен това условието може да бъде написано
Логическо ИЛИ
Логическият оператор ИЛИ (логическо събиране, ИЛИ) е верен, когато поне един от аргументите му е верен.
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
В C ИЛИ е представено от оператора . Например, нека подобрим програмата: сега полът може да се въвежда както с главни, така и с малки букви
Както при оператора И, ИЛИ е комутативен и асоциативен.
Операторите могат да се смесват един с друг, за да се създадат сложни оператори
Трябва само да запомните, че операторът за отрицание има по-висок приоритет от И или ИЛИ, така че той ще бъде изпълнен първи. Ако може да има ситуация, при която редът за изпълнение не е ясен, дефинирайте го със скоби.
Пример: Законът на Де Морган. За да промените И на ИЛИ (или обратно), трябва да обърнете стойностите на всички операнди, да замените И с ИЛИ (или ИЛИ с И) и да обърнете крайния резултат. В случая с нашето състояние
Помислете първо за парчето
Обърнете всички стойности
замени оператор && На
и обърнете отговора
Както виждате, резултатът е същият. Очевидно е, че
Така променяме условието
Променете втората скоба по същия начин
Сега можем да приложим същото правило за целия израз
Ред на изпълнение на логически оператори
Помислете за израза
където a, b, c, d са булеви стойности. всичкоизразът е верен тогава и само ако всички операнди са верни. Ако поне един от операндите е фалшив, тогава останалите вече не са важни. Следователно, за да се оптимизира производителността, изчислението продължава отляво надясно и спира веднага щом бъде открит първият нулев операнд.
В C операторът за присвояване може да върне стойност. Понякога се използва директно в състояние:
В този случай операторът malloc няма да бъде изпълнен, тъй като първият операнд a е 0 (съответно целият израз е нула). По този начин операторът free ще се опита да изчисти паметта, която не може да изчисти (защото p ще продължи да препраща към a). Ако променим a = 1, тогава всичко ще работи без проблеми.
Същото се случва при изпълнение. Изразяване
върви отляво надясно, докато срещне първата ненулева стойност. След това изпълнението спира, тъй като е известно, че целият израз е равен на true.
Очевидно това се отнася не само за оператора за присвояване, но и за всяко друго извикване на функция. Например, в този случай функцията foo ще бъде извикана, а bar не.
Заключение - не използвайте присвоявания и извиквания на функции (особено ако променят състоянието на програмата) вътре в условия.