Логічні оператори в Сі
Логічні оператори
Логічні оператори - це оператори, які приймають як аргументи логічні значень (брехня або істину) і повертають логічне значення. Як і звичайні оператори, вони можуть бути одномісними (унарними, тобто приймати один аргумент), двомісними (бінарні, приймають два аргументи), тримісними тощо.
Особливістю мови си є те, що в ньому немає типу, що зберігає булеве значення (брехня або істину). У брехнею (логічним нулем) вважається цілий 0, а будь-яке ненульове ціле буде логічною істиною. Наприклад
Логічні значення зазвичай породжуються операторами порівняння (==, !=, >, =). брехня як аргумент, то поверне істину.
| 0 | 1 |
| 1 | 0 |
Всі заперечення представлено оператором!. Наприклад
Як і у звичайній логіці, тут діє закон подвійного заперечення – заперечення заперечення можна опустити.
Логічне І
О перетор І (AND, логічне множення) повертає істину тоді і лише тоді, коли обидва аргументи є істиною.
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
У логічне множення представлено оператором &&. Наприклад, завдання – у гурток військових спейсмаринів допускаються лише повнолітні громадяни чоловічої статі. Тобто претендентом може стати лише той, для якого одночасно дві умови є істиною.
Оператор Іможе застосовуватися послідовно до кількох аргументів. Для нього діє асоціативний та комутативний закони. Удосконалимо програму, будемо також запроваджувати зростання:
Також умова могла бути записана
Логічне АБО
Про перетор логічне АБО (логічне додавання, OR) істинне тоді, коли істиною є хоча б один його аргумент.
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
АБО представлений оператором. Наприклад, удосконалимо програму: тепер підлогу можна вводити як великою, так і маленькою буквою
Як і у випадку оператора І, АБО комутативний та асоціативний.
Оператори можна перемішувати один з одним, створюючи складні оператори
Варто тільки пам'ятати про те, що оператор заперечення має більший пріоритет, ніж І або АБО, тому виконуватиметься насамперед. Якщо може статися ситуація, коли порядок виконання не зрозумілий, визначте його за допомогою дужок.
приклад: закон де-Моргана. Щоб змінити І на АБО (або навпаки), необхідно інвертувати значення всіх операндів, замінити І на АБО (або АБО) і інвертувати кінцевий результат. У випадку з нашою умовою
Розглянемо спочатку шматок
Змінюємо всі значення на зворотні
замінюємо оператор && на
та інвертуємо відповідь
Як бачимо, результат той самий. Очевидно, що
Таким чином, змінимо умову
Поміняємо так само другу дужку
Тепер можна застосувати це правило і для всього висловлювання
Порядок виконання логічних операторів
Розглянемо вираз
де a, b, c, d – логічні значення. Всівираз дорівнює істині тоді й лише тоді, коли всі операнди істинні. Якщо хоча б один із операндів брехня, то решта вже не важлива. Тому, для оптимізації роботи, обчислення відбувається зліва направо і зупиняється, як тільки було знайдено перший операнд, що дорівнює нулю.
У сі оператор присвоєння може повертати значення. Іноді він використовується безпосередньо за умови:
В даному випадку оператор malloc не буде виконаний, так як перший операнд a дорівнює 0 (відповідно, весь вираз дорівнює нулю). Таким чином, оператор free спробує очистити пам'ять, яку не може очистити (бо p продовжить посилатися на a). Якщо ми поміняємо a = 1, то все відпрацює без проблем.
Те саме відбувається і при виконанні. Вираз
виконується зліва направо доти, доки зустріне перше ненульове значення. Після цього виконання зупиняється, оскільки відомо, що весь вираз дорівнює істині.
Очевидно, що це стосується не тільки оператора присвоєння, але й іншого виклику функції. Наприклад, у цьому випадку функції foo буде викликано, bar немає.
Висновок – не використовуйте привласнення та виклики функцій (особливо якщо вони змінюють стан програми) всередині умов.