Умовний перехід
Умовний перехід — конструкція мови програмування, яка дозволяє виконувати різні дії залежно від булевого значення умови вказаної програмістом.
Найбільш часто умовний перехід має дві стадії: на першій відбувається порівняння між собою деяких величин, що визначають умову переходу, а на другій виконується сам перехід.
Необхідність коректної обробки умовних переходів накладає серйозний відбиток на логіку роботи сучасних конвеєрних процесорів[1]. Умовні переходи можуть виконуватися двома способами. Виконувані переходи часто змінюють значення лічильника команд процесора на обчислене значення адреси переходу. Невиконувані — додають до значення лічильника команд число, рівне довжині поточної команди в байтах, для переходу до виконання наступної команди. Неправильне визначення типу умовного переходу може призводити до виникнення суттєвих затримок в роботі конвеєра і відповідно до великої втрати продуктивності комп'ютера.
Конструкція if—then(—else)
С-подібні мови
В мовах з C-подібним синтаксисом (C, C++, JavaScript) умовний перехід виглядає так:
if (умова) {
// Дії виконуються, якщо умова виконана
} else {
// Дії виконуються, якщо умова не виконана
}
Pascal
В мові програмування Pascal оператор умовного переходу виглядає так[2]:
if умова then оператор 1 else оператор 2;
Вирази if—then—else
У багатьох мовах програмування підтримуються так звані if—вирази, що подібні до операторів умовного переходу, але повертають деяке значення.
Алголоподібні мови
ALGOL 60 і деякі інші мови сімейства ALGOL дозволяють трактувати конструкцію if–then–else
як вираз:
myvariable := if x > 10 then 1 else 2
У наведеному прикладі змінній myvariable
буде надано значення в залежності від поточного значення змінної x
.
Lisp і діалекти
У діалектах мови Lisp — Scheme, Racket і Common Lisp — умовні вирази також присутні:
;; Scheme
(define myvariable (if (> x 12) 1 2)) ; Надає змінній 'myvariable' значення 1 чи 2, залежно від значення 'x'
;; Common Lisp
(let ((x 10))
(setq myvariable (if (> x 12) 2 4))) ; Надає 'myvariable' значення 2
Haskell
У мові Haskell (Haskell-98 і пізніші стандарти) існують лише if-вирази (умовних операторів немає), і частина else
є обов'язковою, через те, що кожен вираз повинен мати значення.[3] Логіка програми, яка у інших мовах зазвичай виражається умовними операторами, у Haskell як правило реалізується за допомогою співставлення зі шаблоном у рекурсивних функціях.
Мова Haskell реалізує ліниві обчислення, через це є можливим формулювати керуючі структури (такі як if) у вигляді звичайних виразів. Ліниві обчислення у цьому випадку означають, що if—функція обчислює лише вираз умови і відповідну гілку (if чи else), в той час як у мовах з обов'язковим обчисленням («не-лінивих») обчислюються всі три вирази. Приклад програми:[4]
if' :: Bool -> a -> a -> a
if' True x _ = x
if' False _ y = y
C-подібні мови
Мова C і подібні їй мають спеціальну тернарну умовну операцію (?:
) для умовних виразів. Її сутність можна описати таким чином:
умова ? обчислюється_коли_умова_дійсна : обчислюється_коли_умова_недійсна
Таким чином, тернарна операція може бути вбудована у будь-який вираз, на відміну від умовного оператора. У C-подібних мовах вираз
my_variable = (x > 10) ? "foo" : "bar"; // In C-like languages
може бути порівняний з алголоподібними мовами, а також з тернарними операціями у мовах Ruby, Scala і подібних.
Умовний вираз, наведений вище, можна описати і за допомогою умовного оператора:
if (x > 10)
my_variable = 'foo';
else
my_variable = 'bar';
Думки програмістів різняться щодо того, яка форма умовної операції (вираз чи оператор) є простішою для читання і сприймання людиною, і чи генерує оператор більш ефективний код.[5]
Арифметичний оператор if
if
У ранніх версіях мови програмування Фортран (до стандарту Фортран 77) був присутній так званий «арифметичний умовний оператор». Його можна розглядати як проміжну конструкцію між власне умовним оператором і оператором вибору. Ідея базується на математичній трихотомії: x < 0, x = 0, x > 0. Цей оператор був найпершим умовним оператором у Фортрані:[6]
IF (e) label1, label2, label3
де e
— будь-який числовий вираз (не обов'язково цілий). Даний оператор еквівалентний наступному:
IF (e .LT. 0) GOTO label1
IF (e .EQ. 0) GOTO label2
GOTO label3
Через те, що «арифметичний IF» еквівалентний трьом операторам GOTO
(які можуть переходити будь-куди у програмі), він вважається шкідливим у структурному програмуванні і не повинен використовуватися у нових програмах.
Див. також
Примітки
- The Inhibition of Potential Parallelism by Conditional Jumps. doi:10.1109/T-C.1972.223514.
- Розгалуження: оператори умовного та безумовного переходів, оператор вибору в Turbo Pascal. Архів оригіналу за 19 січня 2018. Процитовано 19 січня 2018.
- Haskell 98 Language and Libraries: The Revised Report
- "If-then-else Proposal on HaskellWiki"
- Efficient C Tips #6 – Don’t use the ternary operator « Stack Overflow. Embeddedgurus.com. 18 лютого 2009. Процитовано 7 вересня 2012.
- American National Standard Programming Language FORTRAN. 3 квітня 1978. Архів оригіналу за 11 жовтня 2007. Процитовано 9 вересня 2007.