Условный (компьютерное программирование)

редактировать
Блок-схема «Если-То-Иначе» Вложенная блок-схема «Если – То – Иначе»

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

В языках императивного программирования обычно используется термин «условный оператор », тогда как в функциональном программировании термин «условный выражение "или" условная конструкция "предпочтительнее, потому что все эти термины имеют разные значения.

Хотя динамическая отправка обычно не классифицируется как условная конструкция, это еще один способ выбора между альтернативами во время выполнения .

Содержание

  • 1 If – then (- else)
    • 1.1 Else if
    • 1.2 If – then – else выражения
      • 1.2.1 Семейство Algol
      • 1.2.2 Диалекты Lisp
      • 1.2.3 Haskell
      • 1.2.4 C-подобный языки
      • 1.2.5 Small Basic
      • 1.2.6 Visual Basic
      • 1.2.7 Tcl
      • 1.2.8 Rust
    • 1.3 Арифметика if
    • 1.4 Объектно-ориентированная реализация в Smalltalk
    • 1.5 JavaScript
    • 1.6 Лямбда-исчисление
  • 2 Операторы case и switch
  • 3 Сопоставление с образцом
  • 4 Условные выражения на основе хеша
  • 5 Предсказание
  • 6 Перекрестная ссылка системы выбора
  • 7 См. Также
  • 8 Ссылки
  • 9 Внешние ссылки

If – then (–else)

Конструкция if – then(иногда называемая if – then – else) распространен во многих языках программирования. Хотя синтаксис варьируется от языка к языку, основная структура (в форме псевдокода ) выглядит следующим образом:

If (логическое условие) Then (консеквент) Else (альтернатива) End If

Например :

Если запас = 0 Then message = заказ нового запаса Else message = есть запас End If

В приведенном выше примере кода часть, представленная (логическое условие), составляет условное выражение, имеющее внутреннее значение (например, он может быть заменен любым из значений Истинаили Ложь), но не имеет внутреннего значения. Напротив, комбинация этого выражения, окружающих его Ifи Then, и последующего следствия, составляют условное утверждение, имеющее внутреннее значение (например, выражающее связное логическое правило), но без внутренней стоимости.

Когда интерпретатор находит If, он ожидает логического условия - например, x>0, что означает «переменная x содержит число больше нуля» - и оценивает это условие. Если условие истина, выполняются операторы, следующие за , затем. В противном случае выполнение продолжается в следующей ветви - либо в блоке else (который обычно является необязательным), либо, если нет ветви else, то после the end If.

После выполнения любой из ветвей control возвращается к точке после end If.

В ранних языках программирования, особенно в некоторых диалектах BASIC в 1980-х годах домашние компьютеры, if – thenинструкция могла содержать только инструкции GOTO (эквивалент ветка инструкция). Это привело к созданию трудночитаемого стиля программирования, известного как программирование спагетти, с программами в этом стиле, называемыми кодом спагетти. В результате структурированное программирование, которое позволяет (фактически) помещать произвольные операторы в блоки операторов внутри оператора if, набирало популярность, пока оно не стало нормой даже в большинстве BASIC. кружки программирования. Такие механизмы и принципы были основаны на более старом, но более продвинутом семействе языков АЛГОЛ, а такие АЛГОЛ-подобные языки, как Паскаль и Модула-2, оказали влияние на современный БЕЙСИК. варианты на долгие годы. Хотя при использовании только операторов GOTOв операторах if – thenможно писать программы, которые не являются спагетти-кодом и так же хорошо структурированы и удобочитаемы, как и программы, написанные на языке структурированного программирования., структурированное программирование упрощает эту задачу и усиливает ее. Структурированные операторы if – then – else, подобные приведенному выше примеру, являются одним из ключевых элементов структурного программирования, и они присутствуют в большинстве популярных языков программирования высокого уровня, таких как C, Java, JavaScript и Visual Basic.

Тонкость заключается в том, что необязательное предложение else, имеющееся во многих языках, означает, что контекстно-свободная грамматика является неоднозначной, поскольку вложенные условные выражения можно анализировать несколькими способами. В частности,

ifa, затем ifb, затем s else s2

могут быть проанализированы как

ifa затем (ifb затем s) else s2

или

ifa, затем (ifb, затем s else s2)

в зависимости от того, связан ли elseс первым , если, или вторым , если. Это известно как проблема dangling else и решается различными способами в зависимости от языка.

Else if

Используя else if, можно комбинировать несколько условий. Будут выполнены только операторы, следующие за первым условием, которое окажется истинным. Все остальные заявления будут пропущены.

if condition then --statements elseif condition then - больше операторов elseif condition then - больше операторов;... else - другие утверждения; конец, если;

Например, для магазина, предлагающего 30% скидку на товар:

если скидка < 11% then print (you have to pay $30) elseif discount<21% then print (you have to pay $20) elseif discount<31% then print (you have to pay $10) end if;

Утверждения elseifв Аде просто синтаксический сахар для else, за которым следует , если. В Ada разница в том, что только один конец , если требуется, если используется elseifвместо else, за которым следует if. PHP использует elseifключевое слово как для фигурных скобок, так и для синтаксиса двоеточия. Perl предоставляет ключевое слово elsif, чтобы избежать использования большого количества фигурных скобок, которые требовались бы для нескольких операторов ifи else. Python использует специальное ключевое слово elif, потому что структура обозначается отступом, а не фигурными скобками, поэтому повторное использование elseи , еслипотребует увеличенный отступ после каждого условия. Некоторые реализации BASIC, такие как Visual Basic, также используют ElseIf. Точно так же более ранние оболочки UNIX (позже собранные в синтаксис оболочки POSIX) также используют elif, но с возможностью выбора разделителей пробелами, переносами строк или и тем, и другим.

Однако во многих языках более прямое происхождение от Algol, например Algol68, Simula, Pascal и C, этот специальный синтаксис для конструкции else ifотсутствует и не присутствует во многих синтаксических производных языка C, таких как Java, ECMAScript, и так далее. Это работает, потому что в этих языках любой отдельный оператор (в данном случае if cond...) может следовать за условным оператором, не заключаясь в блок.

Этот выбор дизайна имеет небольшую «стоимость» в этом коде иначе, если ветвь, по сути, добавляет дополнительный уровень вложенности, усложняя работу для некоторых компиляторов (или его разработчиков), что должен анализировать и реализовывать произвольно длинные иначе, еслицепочки рекурсивно.

Если все термины в последовательности условных операторов проверяют значение одного выражения (например, , если x = 0,... , иначе, если x = 1... else if x = 2...), то альтернативой является оператор переключения, также называемый оператором case или оператором select. И наоборот, в языках, в которых нет оператора switch, они могут быть созданы последовательностью операторов else if.

Выражения If – then – else

Многие языки поддерживают выражения if, которые аналогичны операторам if, но возвращают значение в качестве результата. Таким образом, они являются истинными выражениями (которые оценивают значение), а не операторами (которые могут быть недопустимыми в контексте значения).

Семейство Алголов

АЛГОЛ 60 и некоторые другие члены семейства АЛГОЛ допускают if – then – elseкак выражение:

myvariable: = if x>20 then 1 else 2

Диалекты Лиспа

В диалектах Лиспа - Схема, Racket и Common Lisp - первый из которых был в значительной степени вдохновлен ALGOL:

;; Схема (определить мою переменную (если (>x 12) 1 2)); Присваивает myvariable значение 1 или 2, в зависимости от значения x
;; Common Lisp (let ((x 10)) (setq myvariable (if (>x 12) 2 4))); Присваивает myvariable 2

Haskell

. В Haskell 98 есть только выражение if, нет оператора if, а часть elseявляется обязательной, поскольку каждое выражение должно иметь какое-то значение. Логика, которая могла бы быть выражена с помощью условных выражений на других языках, обычно выражается с помощью сопоставления с образцом в рекурсивных функциях.

Поскольку Haskell ленив, можно писать управляющие структуры, такие как if, в виде обычных выражений; ленивое вычисление означает, что функция if может оценивать только условие и правильную ветвь (где строгий язык оценил бы все три). Его можно записать так:

if ':: Bool ->a ->a ->a if' True x _ = x if 'False _ y = y

C-подобные языки

C и C -подобные языки имеют специальный тернарный оператор (?: ) для условных выражений с функцией, которая может быть описана шаблоном следующим образом:

условие? оценено-когда-истина: оценено-когда-ложно

Это означает, что он может быть встроен в выражения, в отличие от операторов if, в языках типа C:

my_variable = x>10? «фу»: «бар»; // В C-подобных языках

, которые можно сравнить с выражениями if – then – else семейства Algol (в отличие от оператора) (и аналогичными в Ruby и Scala, среди прочих).

Чтобы добиться того же с помощью оператора if, потребуется более одной строки кода (в соответствии с типичными соглашениями о компоновке) и потребуется дважды упомянуть «my_variable»:

if (x>10) my_variable = "фу"; еще my_variable = "бар";

Некоторые утверждают, что явный оператор if / then легче читать и что он может компилироваться в более эффективный код, чем тернарный оператор, в то время как другие утверждают, что краткие выражения легче читать, чем операторы, расположенные на нескольких строках, содержащих повторение.

Small Basic

x = TextWindow.ReadNumber () If (x>10) Then TextWindow.WriteLine («Моя переменная названа 'foo'.») Else TextWindow.WriteLine («Моя переменная названа 'bar'. ") EndIf

Сначала, когда пользователь запускает программу, появляется курсор, ожидающий, пока читатель наберет число. Если это число больше 10, появится текст «Моя переменная называется 'foo'». отображается на экране. Если число меньше 10, появится сообщение «Моя переменная названа 'bar'». печатается на экране.

Visual Basic

В Visual Basic и некоторых других языках предоставляется функция IIf , которая может быть используется как условное выражение. Однако оно не ведет себя как истинное условное выражение, поскольку всегда оцениваются как истинная, так и ложная ветви; просто результат одного из них отбрасывается, а результат другого возвращается функцией IIf.

Tcl

В Tcl if- это не ключевое слово, а функция (в Tcl известная как команда или proc). Например,

if {$ x>10} {помещает "Фу!" }

вызывает функцию с именем , еслипередает 2 аргумента: первый является условием, а второй - истинной ветвью. Оба аргумента передаются как строки (в Tcl все в фигурных скобках является строкой).

В приведенном выше примере условие не оценивается перед вызовом функции. Вместо этого реализация функции ifполучает условие в виде строкового значения и отвечает за оценку этой строки как выражения в области вызывающих объектов.

Такое поведение возможно при использовании uplevelи exprкоманды:

Uplevel позволяет реализовать новые управляющие конструкции как процедуры Tcl (например, uplevel может использоваться для реализации конструкции while как процедуры Tcl).

Поскольку , еслина самом деле является функцией, он также возвращает значение:

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

Rust

В Rust, ifвсегда является выражением. Он оценивает значение того, какая ветвь выполняется, или тип модуля (), если ветвь не выполняется. Если ветвь не предоставляет возвращаемого значения, по умолчанию она оценивается как (). Чтобы гарантировать, что тип выражения ifизвестен во время компиляции, каждая ветвь должна оценивать значение того же типа. По этой причине ветвь elseявляется фактически обязательной, если другие ветви не оценивают как (), потому что ifбез elseможет по умолчанию всегда оценивается как ().

// Присваивать my_variable некоторое значение в зависимости от значения x let my_variable = if x>20 {1} else {2}; // Этот вариант не будет компилироваться, потому что 1 и () имеют разные типы let my_variable = if x>20 {1}; // Значения можно опустить, если они не нужны, если x>20 {println! ("X больше 20"); }

Арифметика if

До Fortran 77 язык Fortran имеет оператор «арифметическое if», который находится на полпути между вычисляемым оператором IF и оператором case на основе трихотомия x < 0, x = 0, x>0. Это был самый ранний условный оператор в Фортране:

IF (e) label1, label2, label3

Где e - любое числовое выражение (не обязательно целое); это эквивалентно

IF (e.LT. 0) GOTO label1 IF (e.EQ. 0) GOTO label2 GOTO label3

Поскольку это арифметическое IF эквивалентно множественному GOTO Операторы, которые могут перейти в любое место, считаются неструктурированными операторами управления и не должны использоваться, если можно использовать более структурированные операторы. На практике было замечено, что большинство арифметических операторов IFссылаются на следующий оператор с одной или двумя метками.

Это был единственный оператор условного управления в исходной реализации Fortran на компьютере IBM 704. На этом компьютере код операции test-and-branch имел три адреса для этих трех состояний. Другие компьютеры будут иметь регистры «флагов», такие как положительный, нулевой, отрицательный, четный, переполнение, перенос, связанные с последними арифметическими операциями, и будут использовать такие инструкции, как «Переход, если аккумулятор отрицательный», затем «Переход при нулевом аккумуляторе» или аналогичные. Обратите внимание, что выражение оценивается только один раз, и в таких случаях, как целочисленная арифметика, когда может произойти переполнение, также будут учитываться флаги переполнения или переноса.

Объектно-ориентированная реализация в Smalltalk

В отличие от других языков, в Smalltalk условный оператор не является языковой конструкцией , а определен в class Booleanкак абстрактный метод, который принимает два параметра, оба закрывают. Booleanимеет два подкласса, Trueи False, которые определяют метод, Trueвыполняет только первое замыкание, Falseвыполнение только второго закрытия.

var = condition ifTrue: ['foo'] ifFalse: ['bar']

JavaScript

Два примера в JavaScript :

if (Math.random () < 0.5) { console.log("You got Heads!"); } else { console.log("You got Tails!"); }
var x = Math.random (); if (x < 1/3) { console.log("One person won!"); } else if (x < 2/3) { console.log("Two people won!"); } else { console.log("It's a three-way tie!"); }

Лямбда-исчисление

В Лямбда-исчислении концепция if-then- иначе условное выражение можно выразить с помощью выражений:

true = λx. λy. x false = λx. λy. y ifThenElse = (λc. λx. λy. (cxy))
  1. true принимает до двух аргументы, и как только оба предоставлены (см. каррирование ), он возвращает первый заданный аргумент.
  2. false принимает до двух аргументов, и когда оба предоставлены (см. каррирование ), он возвращает второй заданный аргумент.
  3. ifThenElse принимает до трех аргументов, и как только все они предоставлены, он передает второй и третий аргумент первому аргументу (который является функцией ion, который дает два аргумента и дает результат). Мы ожидаем, что ifThenElse будет принимать только true или false в качестве аргумента, оба из которых проецируют данные два аргумента на их предпочтительный единственный аргумент, который затем возвращается.

примечание : если ifThenElse передается две функции как левая и правильные условные предложения; необходимо также передать пустой tuple () результат ifThenElse, чтобы фактически вызвать выбранную функцию, иначе ifThenElse просто вернет объект функции, не вызывая его.

В системе, где числа могут использоваться без определения (например, Lisp, традиционная бумажная математика и т. Д.), Приведенное выше может быть выражено одним закрытием ниже:

((λtrue. Λfalse. ΛifThenElse. (ifThenElse true 2 3)) (λx. λy. x) (λx. λy. y) (λc. λl. λr. clr))

Здесь true, false и ifThenElse связаны с их соответствующими определениями, которые являются передаются в их область видимости в конце своего блока.

Рабочая аналогия JavaScript (с использованием только функций одной переменной для строгости):

var computationResult = ((_true =>_ false =>_ ifThenElse =>_ ifThenElse (_true) (2) (3))) (x =>y =>x) (x =>y =>y) (c =>x =>y =>c (x) (y)));

Приведенный выше код с функциями с несколькими переменными выглядит так:

var computationResult = ((_true, _false, _ifThenElse) =>_ ifThenElse (_true, 2, 3)) ((x, y) =>x, (x, y) =>y, (c, x, y) =>c (x, y));

другая версия предыдущего примера без системы, в которой предполагаются числа, приведена ниже.

В первом примере показано выполнение первой ветви, а во втором примере показано выполнение второй ветви.

((λtrue. Λfalse. ΛifThenElse. (IfThenElse true (λFirstBranch. FirstBranch) (λSecondBranch. SecondBranch))) (λx. Λy. X) (λx. Λy. Y) (λc. Λl. Λr. Clr)) ((λtrue. λfalse. λifThenElse. (ifThenElse false (λFirstBranch. FirstBranch) (λSecondBranch. SecondBranch))) (λx. λy. x) (λx. λy. y) (λc. λl. λr. clr))

Smalltalk использует аналогичную идею для своих истинных и ложных представлений, причем True и False являются одноэлементными объектами, которые по-разному реагируют на сообщения ifTrue / ifFalse.

Haskell использовал эту точную модель для своего логического типа, но на момент написания большинство программ Haskell использовали синтаксический сахар «if a then b else c» конструкцию, которая, в отличие от ifThenElse, не составляется, если она не обернута другая функция или повторно реализована, как показано в разделе Haskell на этой странице.

Операторы case и switch

операторы Switch (в некоторых языках, операторы case или многосторонние ветки) сравнивают заданное значение с указанными константами и предпринимают действия в соответствии с первой совпадающей константой. Обычно существует положение о том, что действие по умолчанию («иначе», «иначе») должно выполняться, если совпадение не было успешным. Операторы switch могут разрешать оптимизацию компилятора, например, таблицы поиска. В динамических языках случаи могут не ограничиваться константными выражениями и могут расширяться до сопоставления с образцом, как в примере сценария оболочки справа, где '*)' реализует регистр по умолчанию - регулярное выражение , соответствующее любой строке.

Паскаль :C :сценарий оболочки :
case someChar of 'a': actionOnA; 'x': действиеOnX; 'y', 'z': actionOnYandZ; еще действиеOnNoMatch; конец;
переключатель (someChar) {case 'a': actionOnA; перемена; case 'x': actionOnX; перемена; case 'y': case 'z': actionOnYandZ; перемена; по умолчанию: actionOnNoMatch; }
case $ someChar в a) actionOnA; ;; х) действиеOnX; ;; [yz]) actionOnYandZ; ;; *) actionOnNoMatch ;; esac

Сопоставление с образцом

Сопоставление с образцом можно рассматривать как альтернативу операторам if – then – else и case. Он доступен на многих языках программирования с функциями функционального программирования, таких как Wolfram Language, ML и многих других. Вот простой пример, написанный на языке OCaml :

сопоставьте фрукты с | "яблоко" ->приготовить пирог | "кокос" ->приготовить данго_моти | «банан» ->микс ;;

Сила сопоставления с образцом заключается в способности кратко сопоставлять не только действия, но и значения с образцами данных. Вот пример, написанный на Haskell, который иллюстрирует обе эти функции:

map _ = map f (h: t) = fh: map ft

Этот код определяет карту функций, которая применяется первый аргумент (функция) для каждого из элементов второго аргумента (список) и возвращает результирующий список. Две строки - это два определения функции для двух типов аргументов, возможных в этом случае: одна, когда список пуст (просто возвращает пустой список), а другая - случай, когда список не пуст.

Сопоставление с образцом, строго говоря, не всегда является конструкцией выбора, потому что в Haskell можно написать только одну альтернативу, которая гарантированно всегда будет соответствовать - в этой ситуации она не используется в качестве конструкции выбора, но просто как способ привязать имена к значениям. Однако он часто используется в качестве конструкции выбора на языках, на которых он доступен.

Условные выражения на основе хэша

В языках программирования, которые имеют ассоциативные массивы или сопоставимые структуры данных, такие как Python, Perl, PHP или Objective-C, идиоматично использовать их для реализации условного присвоения.

pet = raw_input ("Введите тип питомца, которого вы хотите назвать:") known_pets = {"Dog": "Fido", "Cat": "Meowsles", "Bird": "Tweety",} my_name = known_pets [pet]

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

Предикация

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

Перекрестная ссылка системы выбора

Эта таблица относится к самой последней спецификации языка каждый язык. Для языков, не имеющих спецификации, используется последняя официально выпущенная реализация.

Язык программирования Структурированный, еслипереключатель –select – caseАрифметика, еслиСопоставление с образцом
, тоelseelse – if
Ada ДаДаДаДаНетНет
APL ДаДаДаДаНетНет
Оболочка Bash ДаДаДаДаНетДа
C, C ++ ДаДаДаПадениеНетНет
C# ДаДаНе требуетсяДаНетНет
COBOL ДаДаНе требуетсяДаНетНет
Эйфель ДаДаДаДа НетНет
F# ДаДаДаНе требуетсяНетДа
Fortran 90 ДаДаДаДаДаНет
Go ДаДаНенужноДаНетНет
Haskell ДаНеобходимоНе нужноДа, но не нужноНетДа
Java ДаДаНе требуетсяПадениеНетНет
ECMAScript (JavaScript )ДаДаНе требуетсяПадениеНетНет
Mathematica ДаДаДаДаНетДа
Оберон ДаДаДаДаНетНет
Perl ДаДаДаДаНетНет
PHP ДаДаДаПадение черезНетНет
Паскаль, Object Pascal (Delphi )ДаДаНе требуетсяДаНетНет
Python ДаДаДаНетНетНет
QuickBASIC ДаДаДаДаНетНет
Руби ДаДаДаДаНетНет
Ржавчина ДаДаДаНе требуетсяНетДа
Scala ДаДаНе нужноПадениеНетДа
SQL ДаДаДаДаНетНет
Swift ДаДаДаДаНетДа
Tcl ДаДаДаДаНетДа
Visual Basic, классическийДаДаДаДаНетНет
Visual Basic.NET ДаДаДаДаНетНет
Windows PowerShell ДаДаДаПадениеНетНет
  1. Это относится к сопоставление с образцом как отдельная условная конструкция в языке программирования - в отличие от простой поддержки сопоставления с образцом строки, такой как регулярное выражение suppo rt.
  2. Часто встречающийся else ifв семействе языков C, а также в COBOL и Haskell, является не функцией языка, а набором вложенных и независимых операторов if then else в сочетании с конкретным макет исходного кода. Однако это также означает, что отдельная конструкция else – if на самом деле не нужна в этих языках.
  3. В Haskell и F # отдельная конструкция выбора константы не требуется, потому что ту же задачу можно выполнить с сопоставлением с образцом.
  4. В конструкции Ruby caseсоответствие регулярному выражению входит в число доступных альтернатив условного управления потоком. В качестве примера см. этот вопрос о переполнении стека.
  5. SQL имеет две похожие конструкции, которые выполняют обе роли, обе введены в SQL-92. Выражение «искомый CASE» CASE WHEN cond1 THEN expr1 WHEN cond2 THEN expr2 [...] ELSE exprDflt ENDработает как if... else if... else, тогда как выражение «простое CASE»: CASE expr WHEN val1 THEN expr1 [...] ELSE exprDflt ENDработает как оператор switch. Для получения подробной информации и примеров см. Case (SQL).
  6. Арифметика , еслиявляется устаревшим в Fortran 90.

См. Также

Ссылки

Внешние ссылки

Найдите , затем или или в Wiktionary, бесплатный словарь.
  • Носители, относящиеся к Conditional (компьютерное программирование) на Wikimedia Commons
  • IF NOT (ActionScript 3.0) video
Последняя правка сделана 2021-05-15 09:03:33
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте