Из Википедии, бесплатной энциклопедии
  (Перенаправлено из условного ветвления )
Перейти к навигации Перейти к поиску
Блок-схема If-Then-Else
Вложенная блок-схема "Если – То – Иначе"

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

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

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

Если – то (–else) [ править ]

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

Если ( логическое условие ) То ( следствие ) Иначе ( альтернатива ) Конец Если      

Например:

Если акции = 0 Тогда сообщение = заказать новый фондовый Else сообщение = есть есть запас End Если           

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

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

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

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

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

if a then  if b then s else s2

можно разобрать как

if a then ( if b then s) else s2

или же

если a, то ( если b, то s иначе s2)

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

Иначе, если [ редактировать ]

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

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

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

если  скидка  <  11 % ,  то  печать  ( вы  должны  к  заплатить  $ 30 ) ElseIf  скидка < 21 % ,  то  печать  ( вы  должны  к  заплатить  $ 20 ) ELSEIF  скидка < 31 % ,  то  печать  ( вы  должны  к  заплатить  $ 10 ) конец ,  если ;

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

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

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

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

Выражения if – then – else [ править ]

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

Семья Алголов [ править ]

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

 myvariable: = если x> 20, то 1 иначе 2

Диалекты Лиспа [ править ]

В диалектах Лиспа  - Scheme , 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часть является обязательной, так как каждое выражение должно иметь какое-то значение. [4] Логика, которая могла бы быть выражена с помощью условных выражений на других языках, обычно выражается с сопоставлением с образцом в рекурсивных функциях.

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

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

C-подобные языки [ править ]

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

condition ? evaluated-when-true : evaluated-when-false

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

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

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

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

если  ( x  >  10 )  my_variable  =  "foo" ; еще  my_variable  =  "бар" ;

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

Small Basic [ править ]

x  =  TextWindow . ReadNumber () Если  ( x  >  10 )  Тогда  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 }  {  помещает  "Фу!" }

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

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

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

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

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

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

Ржавчина [ править ]

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

// Присваиваем 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» );}

Арифметика, если [ править ]

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

IF  ( e )  label1 ,  label2 ,  label3

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

ЕСЛИ  ( е  . LT .  0 )  GOTO label1 ПЧ  ( е  . Эквалайзер .  0 )  GOTO label2 GOTO Метка3

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

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

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

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

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

JavaScript [ править ]

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

if  ( Math . random ()  <  0,5 )  {  console . log ( «У тебя есть головы!» ); }  else  {  console . log ( «У тебя решки!» ); }

[ требуется разъяснение ]

var  x  =  Math . случайный (); если  ( х  <  1 / 3 )  {  консоли . log ( «Выиграл один человек!» ); }  Иначе ,  если  ( х  <  2 / 3 )  {  консоли . log ( «Два человека выиграли!» ); }  else  {  console . журнал ( «Это трехсторонняя ничья!» ); }

[ требуется разъяснение ]

Лямбда-исчисление [ править ]

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

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

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

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

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

Здесь 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 )  =>  с ( х ,  у ));

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

В первом примере показана первая ветвь, а во втором примере - вторая.

 (( λtrue.  λfalse.  λifThenElse.  ( ifThenElse  true  ( λFirstBranch.  FirstBranch )  ( λSecondBranch.  SecondBranch ))  ) ( λx.  λy.  x ) ( λx.  λy.  y ) ( λc.  λl.  λr.  c  l  r )) (( λtrue.  λfalse.  λifThenElse.  ( ifThenElse  false  ( λFirstBranch.  FirstBranch )  ( λSecondBranch.  SecondBranch ))  ) ( λx.  λy.  x ) ( λx.  λy.  y ) ( λc.  λl.  λr.  c  l  r ))

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

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

Операторы case и switch [ править ]

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

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

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

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

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

map  _  []  =  [] map  f  ( h  :  t )  =  f  h  :  map  f  t

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

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

Условные выражения на основе хеша [ править ]

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

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

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

Предикация [ править ]

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

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

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

  1. ^ Это относится к сопоставлению с образцом как к отдельной условной конструкции в языке программирования - в отличие от простой поддержки сопоставления с образцом строки, такой какподдержкарегулярных выражений.
  2. 1 2 3 4 5 Часто встречающеесяelse ifв семействе языков C, а также в COBOL и Haskell, является не особенностью языка, а набором вложенных и независимыхоператоровif then else всочетании с определенным макетом исходного кода. Однако это также означает, что отдельная конструкция else – if на самом деле не нужна в этих языках.
  3. 1 2 В Haskell и F # отдельная конструкция выбора константы не требуется, потому что ту же задачу можно выполнить с сопоставлением с образцом.
  4. ^ ВcaseконструкцииRubyсопоставлениерегулярных выраженийвходит в число доступных альтернатив условного управления потоком. Например, см.Этотвопрос о переполнении стека.
  5. 1 2 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. ^if В Fortran 90 арифметикаустарела.

См. Также [ править ]

  • Отрасль (информатика)
  • Условная компиляция
  • Динамическая отправка для другого способа выбора выполнения
  • Маккарти Формализм для истории и исторических ссылок
  • Именованное условие
  • Оператор отношения
  • Тест (Unix)
  • Условия Йоды
  • Условный ход

Ссылки [ править ]

  1. ^ Синтаксис PHP elseif
  2. ^ Синтаксис Visual Basic ElseIf
  3. ^ Стандартный синтаксис оболочки POSIX
  4. ^ Haskell 98 Язык и библиотеки: пересмотренный отчет
  5. ^ " Предложение If-then-else на HaskellWiki "
  6. ^ «Эффективные советы C # 6 - Не используйте тернарный оператор« Stack Overflow » . Embeddedgurus.com. 2009-02-18 . Проверено 7 сентября 2012 .
  7. ^ «Новые структуры управления» . Вики Члера . Проверено 21 августа 2020 года .
  8. ^ "страница руководства верхнего уровня" . www.tcl.tk . Проверено 21 августа 2020 года .
  9. ^ "если справочная страница" . www.tcl.tk . Проверено 21 августа 2020 года .
  10. ^ "Если и если пусть выражения" . Проверено 1 ноября 2020 года .
  11. ^ "Американский национальный стандартный язык программирования FORTRAN" . 1978-04-03. Архивировано из оригинала на 2007-10-11 . Проверено 9 сентября 2007 .
  12. ^ «VisualWorks: условная обработка» . 2006-12-16. Архивировано из оригинала на 2007-10-22 . Проверено 9 сентября 2007 .
  13. ^ "Питонический способ реализации операторов switch / case" . Архивировано из оригинала на 2015-01-20 . Проверено 19 января 2015 .
  14. ^ Java.sun.com , Спецификация языка Java, 3-е издание.
  15. ^ Ecma-international.org Архивировано 12 апреля 2015 г. вспецификации языка ECMAScript Wayback Machine , 5-е издание.

Внешние ссылки [ править ]

  • СМИ, связанные с условным программированием (компьютерное программирование) на Викискладе?
  • ЕСЛИ НЕ (ActionScript 3.0) видео