Кондиционал (рачунарско програмирање)
У информатици, условне изјаве, условни изрази и условне конструкције су функције програмског језика, које извршавају различита израчунавања или различите акције у зависности од тога да ли је програмерски одређен булов услов оценио на тачно или нетачно. Осим у случају предвиђања огранка, ово се увек постиже тако што се селективно мења управљање током засновано на неком услову.
У језицима императивног програмирања, термин "условна изјава" се обично користи, док у функционалном програмирању, термини "условни изрази" или "условна конструкција" су пожељни, зато што ови појмови имају различита значења.
Иако динамична депеша обично није класифицирана као условна конструкција, она представља још један начин бирања између алтернатива за време рантајма.
If–then(–else)
уредиif–then
конструкција (понекад звана if–then–else
) је заједничка за многе порграмске језике. Иако синтакса поприлично варира од језика до језика, основна структура (у облику псеудокода) изгледа овако:
If (boolean condition) Then
(consequent)
Else
(alternative)
End If
Када интерпретарор пронађе реч If
, он очекује булов услов – на пример, x > 0
, што значи "променљива x садржи број који је већи од нуле" – и процењује тај услов. Ако је услов true
, изјава која следи после then
се извршава. Иначе, извршавање се наставља у следећој грани – било у else
блоку (која је обично опционална), или ако не постоји else
грана, онда после end If
.
После извршавања било које гране, управљање током се враће на тренутак после end If
.
У првим програмским језицима, посебно неки дијалекти Бејсика у кућним рачунарима 1980-их година, if–then
изјава је могла само да садржи GOTO
изјаве. Ово је довело до стила програмирања тешког за читање који је познат као шпагети програмирање, са програмима у стилу који се називао шпагети код. Као резултат, структурирано програмирање, које дозвољава (готово) произвољним изјавама да буду стављене у изјавне блокове унутар if
изјаве, је добило на популарности, док није постало норма чак и у већини Бејсик програмских кругова. Такви механизми и принципи су базирани на старијој али много напреднијој породици језика Алгол, и језици налик на Алгол као што су Паскал и Модула-2 су утицали на модерне Бејсик варијанте дуги низ година. Док је могуће при употреби само GOTO
изјава у if-then
изјавама, написати програме који нису шпагети код и који су структуирани и читљиви колико и програми написни у структуираном програмском језику, структуирано програмирање ово чини лакшим и оно га спроводи. Структуиране if-then-else
изјаве као на примеру изнад су један од кључних елемената структуираног програмирања, и оне су присутне у најпопуларнијим програмским језицима високог нивоа као што су C, Јава, Јаваскрипт и Вижуал бејсик .
Субтилност је у томе да опционална else клаузула која се може њаћи у многим језицима значи да је контекстно слободна граматика двосмислена, пошто се груписани кондиционали могу анализирати на различите начине. Конкретно,
if a then if b then s else s2
се може анализирати као
if a then (if b then s) else s2
или
if a then (if b then s else s2)
у зависности да ли је else
повезано са првим if
или другим if
. Ово је познато као климаво else проблем, и тај проблем се решава на различите начине, у зависности од језика.
Else if
уредиКоришћењем else if
, могуће је комбиновати веше услова. САмо изјаве после првог услова за које се утврди да су истините ће бити извршене. Све остале изјаве ће бити прескочене. Изјаве
if услов then
--изјаве
elseif услов then
-- још изјава
elseif услов then
-- још изајва;
...
else
-- друге изјаве;
end if;
elsif
, у Ади, је просто шећер синтаксе за else
после кога иде if
. У Ади, разлика је у томе да је само једно end if
потребно, ако неко користи elsif
уместо else
после кога иде if
. Ово је слично у Перл, који обезбеђује кључну реч elsif
да би избегао велики број протеза које би биле потребне од стране више if
и else
изјава и такође у Пајтону, који користи специјалну кључну реч elif
зато што је структура означена са увлачењем а не са протезама, тако да би репетитивна употреба else
и if
захтевала повећано увлачење после сваког услова. Слично, раније јуникс љуске (касније сакупљене у Посикс синтаксу љуске [1]) користе elif такође, али дајући избор разграничавања са празним простором, линијама, или оба.
Међутим, у многим језицима који воде директно порекло од Алгола, као што су Алгол68, Симула, Паскал, BCPL и C, ова специјална синтакса за else if
није присутна, није присутна ни у многим синтаксним дериватима C-а, као што су Јава, ECMA-скрипт, PHP, и тако даље. Ово ради зато што у овим језицима, било који један израз (у овом случају if конд
...) може да прати кондиционал а да не буде уклопљен у блок.
Овај дизајнерски избор има малу "цену" у томе да код else if
гране, ефективно, додаје један више ниво груписања, компликујући посао за неке компајлере (или за њихове реализаторе), који морају да нализирају и имплементирају поризвољно дугачке else if
ланце рекурзивно.
Ако сви термини у секвенци кондиционала тестирају вредност једног израза (нпр, if x=0
... else if x=1
... else if x=2
...), онда се та алтернатива назива изјава замене, ил изјава случаја или изјава одабира. С друге стране, у језицима који немају изјаву замене, ове изваје могу бити произведене од стране секвенце else if
изјава.
If-then-else изрази
уредимноги језици подржавају if изразе, који су слични if изјавама, али враћају вредност као резултат. Стога, они су истински изрази (који процењују на вредност), не изјаве (које мењају стање програма или врше неку врсту акције).
Алгол породица
уредиАлгол 60 и неки други чланови Алгол породице дозвољавају if-then-else
као израз:
мојапроменљива := if x > 10 then 1 else 2
Lisp дијалекти
уредиУ дијалектима Lisp-а -- Ским, Ракет и Common Lisp -- од којих је прва била инспирисана у великој мери од стране Алгола:
;; Scheme
(define myvariable (if (> x 10) 1 2)) ; Додељује ‘myvariable’ на 1 или 2, у зависности од вредности ‘x’
;; Common Lisp
(let ((x 5))
(setq myvariable (if (> x 10) 1 2))) ; Додељује ‘myvariable’ на 2
Хаскл
уредиУ Хаскл 98, постоји само if израз, а не if изјава, и else
део је обавезан, како сваки израз мора да има неку вредност.[2] Логика која би била изражена са кондиционалима у другим језицима је обично изражена са подударањем шаблона у рекурзивним функцијама.
Зато што је Хаскл лењ, могуће је писати контролне структуре, као што су if, као обичне изразе; лења евалуација значи да if функција може да процени само услов и одговарајућу грану (где би строги језик процењивао сва три). Може се написати овако:[3]
if' :: Bool -> a -> a -> a
if' True x _ = x
if' False _ y = y
Језици налик на C
уредиC и језици налик на C имају специјалан тернарни оператер (?:) за кондиционалне изразе са функцијом која може бити описана од стране шаблона на овај начин:
услов ? процењен-када-true : процењен-када-false
Ово значи да може бити убачен у изразе, за разлику од if-изјава, у језицима налик на C:
моја_променљива = (x > 10) ? "foo" : "bar"; // У језицима налик на C
који могу бити поређени са if-then-else изразима Алгол породице (и слично у Руби и Скали, међу осталима).
Да би постигли исту ствар користећи if-изјаву, за ово би било потребно више од једне линије кода (под типочним конвенцијама израза):
if (x > 10)
моја_променљива = 'foo';
else
моја_променљива = 'bar';
Неки тврде да је изричита if/then изјава лакша за читање и да се може саставити на ефикаснији код од тернарног оператера,[4] док други тврде да су концизни изрази лакши за читање него изјаве прострањене на неколико линија.
Унутар Вижуал бејсика
уредиУ Вижуал бејсику и неким другим језицима, функција која се назива IIf
је обезбеђена, која се може користити као кондиционални израз. Међутим, она се не понаша као прави кондиционални израз, зато што су и true и false гране увек процењене; то само значи да је резултат једне од њих одбачен, док је резултат друге враћен од стране IIf функције.
Аритметичко if
уредиДо Фортрана 77, језик Фортаран има "аритметичку if" изјаву која је на пола пута између обрачунатог IF и изјаве случаја, базирану на трихотомији , , . Ово је најранија условна изјава у фортрану:[5]
IF (e) ознака1, ознака2, ознака3
Где је e било који нумерички израз (не мора бити цео број); ово је еквивалентно са
IF (e .LT. 0) GOTO ознака1
IF (e .EQ. 0) GOTO ознака2
GOTO ознака3
Зато што је ово аритметичко IF еквивалентоно вишеструким GOTO
изјавама које се могу преместити било где, оно се сматра да је неструктуирана контролна изјава, и не треба се користити ако се могу користити више структуиране изјаве. У пракси је уочено да је већина аритметичких IF
изјава референцирала следећу изјаву са једном или две ознаке.
Ово је била једина условна контролна изјава у оригиналној имплементацији Фортрана на IBM 704 рачунару. На том рачунару је тест-и-грана op-код имао три адресе за за та три стања. Други рачунари би имали "застава" регистре као што су позитива, нула, негатива, једнакост, преливање, ношење, повезане са последњом аритметичком операцијом и они би користили инструкција као што су 'Разгранај ако је акумулатор негативан' затим 'Разгранај ако је аумулатор нула' или слично. Имајте на уму да се израз процењује само једном, и у случајевима као што је цео аритметички број где може доћи до преливања, такође би се разматрало преливање или ношење застава .
Објектно-оријентисана имплементација у Smalltalkу
уредиЗа разлику од других језика, у Smalltalkу условна изјава није језичка конструкција али је дефинисана у класи Boolean
као апстрактна метода која узима два параметара, оба затварача. Boolean
има две подкласе, True
и False
, где обе дефинишу методу, True
извршава само прво затварање, False
извршава само друго затварање.[6]
var = condition
ifTrue: [ 'foo' ]
ifFalse: [ 'bar' ]
Изјаве случаја и замене
уредиИзјаве замене (у неким језицима, изјаве случаја или гране на више начина) упоређују дату вредност са специфизираном константом и предузимају мере према првој константи која одговара. Обично постоји одредба за подразумевану акцију ('else','otherwise') коју треба предузети ако ниједно спаривање не успе. Изјаве замене могу дозволити компајлер оптимизације, као што су лукап табеле. у динамичким језицима, случајеви можда неће бити ограничени на сталне изразе, и можда се прошире на подударање шаблона, као у шел скрипт примеру са десне стране, где '*)' имплементира уобичајен случај за регуларни израз који се подудара са сваким стрингом.
Паскал: | C: | Шел скрипте |
---|---|---|
case someChar of
'a': actionOnA;
'x': actionOnX;
'y','z':actionOnYandZ;
else actionOnNoMatch;
end;
|
switch (someChar) {
case 'a': actionOnA; break;
case 'x': actionOnX; break;
case 'y':
case 'z': actionOnYandZ; break;
default: actionOnNoMatch;
}
|
case $someChar in
a) actionOnA; ;;
x) actionOnX; ;;
[yz]) actionOnYandZ; ;;
*) actionOnNoMatch ;;
esac
|
Уклапање шаблона
уредиУклапање шаблона се можда види као софистициранија алтернатива и за if-then-else изјаве и изјаве случаја. Она је доступна у многим програмским језицима са функционалним програмским карактеристикама, као што су Волфрам језик, ML и многи други. Ево простог примера написаног у OCaml језику:
match fruit with
| "apple" -> cook pie
| "coconut" -> cook dango_mochi
| "banana" -> mix;;
Моћ укапања шаблона је способност да концизно слаже не само акције али и вредности у обрасце података. Ево примера написаног у Хаскл који илуструје обе ове карактеристике:
map _ [] = []
map f (h : t) = f h : map f t
Овај код дефинише мапу, функције која примењује први аргумент (функцију) сваком од елемената другог аргумента (листе), и враће резултујућу листу. Две линије су две дефиниције функције за две врсте аргумената могућих у овом случају – онај у коме је листа празна (само врати празну листу) и други случај када листа ниеј празна.
Уклапање шаблона стриктно говорећи није увек изборна конструкција, зато што је могуће у Хасклу написати само једну алтернативу, која је загарантована да увек пуде упарена – у овој ситуацији, се не користи као изборна конструкција, већ само као начина везивања имена са вредностима. Међутим, често се користи као изборна конструкција у језицима у којима је доступна.
Кондиционали базирани на хешу
уредиУ пограмским језицима који имају асоцијативне низове или упоредиве структуре, као што су Пајтон, Перл, PHP или Objective-C, идиоматски је да их користите за имплементацију условног задатка.[7]
љубимац = raw_input("Унесите тип љубимца којег желите да именујете: ")
познати_љубимци = {"Пас": "Fido",
"Мачка": "Meowsles",
"Птица": "Tweety"}
моје_име = познати_љубимци[љубимац]
У динамичким језицима који имају анонимне функције или које дозвољавају програмеру да додели именовану функцију варијаблној референци, условни ток се може имплементирати коришћењем хеша као прескок стола.
Предвиђање огранака
уредиУ асемблерским језицима, предвиђање огранака је функција одређених процесорских (централних процесорских јединица) (CPU) комплета инструкција која дозвољава суловно извршавање инструкција, без потребе да се извршавају скупи условни скокови.
Упућивање изброног система
уредиОва табела се односи на велики број недавних језичких спецификација за сваки језик. За језике који немају спецификацију, последња званично пуштена имплементација је она на коју се односи.
Програмски језик | Структурно if | замена-одабир-случај | Аритметичко if | Укалпање шаблона[A] | ||
---|---|---|---|---|---|---|
then | else | else-if | ||||
Ада | Да | Да | Да | Да | Не | Не |
C, C++ | Да | Да | Непотребан[B] | Пропао | Не | Не |
C# | Да | Да | Непотребан[B] | Да | Не | Не |
Кобол | Да | Да | Непотребан[B] | Да | Не | Не |
Ајфел | Да | Да | Да | Yes | Не | Не |
F# | Да | Да | Да | Непотребан[C] | Не | Да |
Фротран 90 | Да | Да | Да | Да | Да | Не |
Гоу | Да | Да | Непотребан[B] | Да | Не | Не |
Хаскл | Да | Needed | Непотребан[B] | Непотребан[C] | Не | Да |
Јава | Да | Да | Непотребан[B] | Пропао[8] | Не | Не |
Екмаскрипт | Да | Да | Непотребан[B] | Пропао[9] | Не | Не |
Матхематика | Да | Да | Да | Да | Не | Да |
Оберон | Да | Да | Да | Да | Не | Не |
Перл | Да | Да | Да | Да | Не | Не |
PHP | Да | Да | Да | Пропао | Не | Не |
Паскал, Објектни
паскал
(Делфи) |
Да | Да | Непотребан | Да | Не | Не |
Пајтон | Да | Да | Да | Не | Не | Не |
КуикБејсик | Да | Да | Да | Да | Не | Не |
Руби | Да | Да | Да | Да | Не | Не |
Скала | Да | Да | Непотребан[B] | Пропао | Не | Да |
SQL | Да[S] | Да | Да | Да[S] | Не | Не |
Вижуал Бејсик, класик | Да | Да | Да | Да | Не | Не |
Вижуал Бејсик.NET | Да | Да | Да | Да | Не | Не |
Виндоус
Пауршел |
Да | Да | Да | Пропао | Не | Не |
- ^ Ово се односи на уклапање шаблона као посебну условну конструкцију у програмском језику – насупрот само подршци уклапања шаблона стингова, као што је подршка регуалрни израз support.
- 1 2 3 4 5 Често сусретано
else if
у C породици језика, а такође и у Коболу и Хасклу, није функција језика већ је скуп угнежђених и независних if then else изјава комбинованим са одређеним изгледао изворног кода. Међутим, ово такође значи да јасна else-if конструкција није заиста потребна у овим језицима. - 1 2 У Хасклу и F#, посебна константа изборне конструкције је непотребна, јер исти задатак може бити урађен с уклапањем шаблона.
- 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
ради као изјава замене. За детаље и примере погледајте Case (SQL).
Види још
уредиРеференце
уреди- ^ POSIX стандардна синтакса љуске
- ^ Хаскл 98 језик и библиотеке: Измењени извештај
- ^ "If-then-else Proposal on HaskellWiki"
- ^ „Efficient C Tips #6 – Don’t use the ternary operator « Stack Overflow”. Embeddedgurus.com. 18. 02. 2009. Приступљено 07. 09. 2012.
- ^ „American National Standard Programming Language FORTRAN”. 03. 04. 1978. Архивирано из оригинала 11. 10. 2007. г. Приступљено 09. 09. 2007.
- ^ „VisualWorks: Conditional Processing”. 16. 12. 2006. Архивирано из оригинала 22. 10. 2007. г. Приступљено 09. 09. 2007.
- ^ „Pythonic way to implement switch/case statements”. Архивирано из оригинала 20. 01. 2015. г. Приступљено 19. 01. 2016.
- ^ Java.sun.com, Јава језичка спецификација, треће издање.
- ^ Ecma-international.org Архивирано на сајту Wayback Machine (12. април 2015) Екма скрипт језичка спецификација, пето издање.
Спољашње везе
уреди- IF NOT (АкшнСкрипт 3.0) Архивирано на сајту Wayback Machine (1. новембар 2011) видео