5.4. Podmíněný výraz Podmíněný výraz je v COBOLu přípustný v příkazech IF, PERFORM a SEARCH. Základními stavebními kameny pro podmíněné výrazy jsou tzv. jednoduché podmíněné výrazy (mající pro podmíněný výraz stejnou úlohu jako operandy pro aritmetický výraz), jichž existuje těchto šest typů: relační test znaménkový test (POSITIVE, ZERO, NEGATIVE) numerický třídní test (NUMERIC) alfabetický třídní test (ALPHABETIC) test podmínkového jména test UPSI-bytu Podmíněný výraz je pak buďto jediný jednoduchý podmíněný výraz anebo tzv. složený podmíněný výraz, který vznikne spojením několika jednoduchých podmíněných výrazů pomocí logických operátorů NOT, AND a OR a pomocí závorek (viz 5.4.7. a 5.4.8.). Každý jednoduchý podmíněný výraz má při vyhodnocování (pokud ovšem nedojde k chybě a k ukončení výpočtu) jednu ze dvou možných pravdivostních hodnot; je buďto pravdivý anebo nepravdivý. Uvedení rezervovaného slova NOT, které je v některých jednoduchých výrazech povoleno, mění pravdivostní hodnotu na opačnou. Nepovinná slova IS, TO a THAN se ignorují (viz 5.4.1. až 5.4.6.). 5.4.1. Relační test Relační test provádí srovnání dvou operandů. Je pravdivý tehdy, když skutečný vztah mezi oběma operandy odpovídá uvedenému relačnímu operátoru. Formát: - - | < | | = | - - | > | - - |položka | | <= | | položka | |literál | | =< | | literál | |aritm.výraz | | >= | | aritm.výraz | IS [NOT] < => > < fig.konstanta> |ALL-klauzule | | <> | | ALL-klauzule | |speciál.index | | >< | | speciál.index| |UI-položka | | LESS THAN | | UI-položka | - - | EQUAL TO | - - |GREATER THAN| - - Tento formát může být schématicky vyjádřen též takto: levý-operand IS [NOT] relační-operátor pravý-operand Poznámky: 1) Základní relační operátory jsou <, = a >. Slovní relační operátor LESS (resp. LESS THAN) je ekvivalentní s <, operátor EQUAL (resp. EQUAL TO) je ekvivalentní s = a operátor GREATER (resp. GREATER THAN) je ekvivalentní s >. 2) Ve zdvojených relačních operátorech <=, =<, >=, =>, <>, >< je možné, ne však nutné, mezi oběma znaky vynechat mezeru. Pro určení významu zdvojeného relačního operátoru je třeba představit si mezi oběma znaky slovo "nebo"; tak např. operátor "< =" znamená "menší nebo rovno". 3) Uvedení reservovaného slova NOT mění pravdivostní hodnotu relačního testu na opačnou, takže vlastně mění uvedený relační operátor na doplňkový (pozor, např. k relačnímu operátoru < není doplňkovým operátorem >, nýbrž >= ). 4) Každý z následujících řádků obsahuje vždy navzájem zcela ekvivalentní relační operátory: a) =, EQUAL, EQUAL TO, NOT < >, NOT > < b) NOT =, NOT EQUAL, NOT EQUAL TO, < >, > < c) <, LESS, LESS THAN, NOT > =, NOT = > d) NOT <, NOT LESS, NOT LESS THAN, > =, = > e) >, GREATER, GREATER THAN, NOT < =, NOT = < f) NOT >, NOT GREATER, NOT GREATER THAN, < =, = < Následující tabulka ukazuje, pro které dvojice operandů je srovnání přípustné a pro které nepřípustné, a podle jakého kritéria se jednotlivá přípustná srovnání vyhodnocují: Tabulka 7: Přípustná srovnání v relačním testu. ------------------------------------------------------------ | pravý operand| | | levý operand | 1 2 3 4 5 6 7| |------------------------|---------------------------------| | 1 skupinová-položka | | | 1 alfanumerická-položka| | | 1 alfan.edit.položka | AN AN AN AN -- AN AN| | 1 alfanumerický-literál| | |------------------------|---------------------------------| | 2 ALL alfanum.literál | | | 2 SPACE,-S | | | 2 QUOTE,-S | AN -- AN -- -- AN AN| | 2 LOW-VALUE,-S | | | 2 HIGH-VALUE,-S | | |------------------------|---------------------------------| | 3 numerická-položka | AN AN NU NU NU NU SP| | 3 numerický-literál | | |------------------------|---------------------------------| | 4 ZERO,-S,-ES | AN -- NU NU NU NU SP| |------------------------|---------------------------------| | 5 aritmetický-výraz | -- -- NU NU NU NU --| |------------------------|---------------------------------| | 6 položka-s-USAGE-INDEX| AN AN NU NU NU NU NU| |------------------------|---------------------------------| | 7 speciální-index | AN AN SP SP -- NU SP| ------------------------------------------------------------ AN znamená alfanumerické srovnaní NU znamená numerické srovnání SP znamená speciální srovnání -- znamená,že srovnání těchto dvou operandů není přípustné (V tabulce "aritmetický-výraz" znamená aritmetický výraz obsahující alespoň jeden operátor nebo závorku, nikoliv tedy jen samotnou numerickou položku, numerický literál nebo ZERO.) Alfanumerické srovnání (AN) Alfanumerické srovnání se provádí tehdy, jestliže alespoň jeden z obou operandů není numerický (ani UI-položka nebo speciální index; viz tabulka 7). Operandy, u nichž není způsob srovnání zřejmý, se alfanumericky srovnávají takto: a) Numerická položka, položka s USAGE INDEX a speciální index se při alfanumerickém srovnání zpracovávají znakově, jako kdyby se jednalo o alfanumerickou položku se stejnou délkou a se stejným obsahem. b) Numerický literál se pro účely alfanumerického srovnání upraví takto: znaménko, desetinná tečka a exponentová část se vynechají, literál se uloží znakově, přičemž znaménko + resp. - způsobí změnu levého půlbytu posledního bytu na hexadecimální 3 resp. 4. (Praktický význam má jedině použití celého čísla, které tedy při srovnání s nenumerickou položkou nemusí být uvedeno v apostrofech). c) Figurativní konstanta nebo ALL-klauzule se srovnávají tak, jako kdyby byl místo nich uveden alfanumerický literál o délce rovné délce druhého operandu, vytvořený cyklickým opakováním příslušné figurativní konstanty nebo alfanumerického literálu uvedeného za ALL zleva doprava (nezávisle na tom, zda druhý operand má nebo nemá klauzuli JUST). Příklady: 1) Má-li položka PIC S9(5)V9(3) COMP-3 VALUE -23, pak při alfanumerickém srovnání se s ní pracuje stejně jako kdyby se jednalo o alfanumerickou položku o délce 5 bytů a o obsahu hexadecimálně 0000230004. 2) Obsahuje-li položka s USAGE INDEX anebo speciální index hodnotu 162, pak při alfanumerickém srovnání se s nimi pracuje stejně, jako kdyby se jednalo o alfanumerickou položku o délce 4 bytů a o obsahu hexadecimálně 000000A2. 3) Numerický literál -123.45E-8 se pro účely alfanumerického srovnání upraví do tvaru '1234E' (hexadecimálně 3132333445). 4) Má-li položka A PIC X(5), pak při relačním testu A = ZERO se A srovnává s '00000', při relačním testu A = ALL '3' se A srovnává s '33333', při relačním testu A = ALL '123' se A srovnává s '12312' (i kdyby A měla klauzuli JUST). Pravidlo: Při alfanumerickém srovnání se srovnávají binární hodnoty jednotlivých bytů obou operandů v odpovídajících si pozicích zleva doprava. Nemají-li oba operandy stejné délky, provádí se srovnání tak, jako kdyby kratší z nich byl doplněn mezerami (hexadecimálně 20) do délky delšího operandu. Je-li při tomto postupu v obou operandech zleva doprava nalezena nerovnost mezi hodnotami bytů v odpovídajících si pozicích, je srovnání ukončeno a podle této nalezené nerovnosti se určí, že první operand je menší nebo větší než druhý. Jsou-li všechny odpovídající si byty obou operandů stejné, jsou oba prohlášeny za sobě rovné. Poznámka: Binární ekvivalenty všech znaků vnitřního kódu počítače lze nalézt v příslušné systémové dokumentaci. Nejmenší alfanumerickou hodnotu má LOW-VALUE (hex. 00, největší alfanumerickou hodnotu má HIGH-VALUE (hex. FF). Dále uvádíme některé tisknutelné znaky v pořadí shodném s pořadím jim odpovídajících binárních ekvivalentů: mezera ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D ... X Y Z a b c d ... x y z { | } Příklad: 04 JEDLE PIC X(3) VALUE 'BBC' 04 SLUNCE PIC X(3) VALUE 'BBB' 04 POLE PIC X(4) VALUE 'BBBA' 04 SELE PIC X(4) VALUE 'BBB ' 04 TELE PIC X(4) VALUE #42424200#. Pak jsou následující relační testy pravdivé: TELE < SLUNCE SLUNCE = SELE SELE < POLE TELE < SELE SLUNCE < POLE SELE < JEDLE TELE < POLE SLUNCE < JEDLE POLE < JEDLE TELE < JEDLE Numerické srovnání (NU) Numerické srovnání se provádí tehdy, jsou-li oba operandy numerické; dále se numericky srovnává UI-položka s numerickým operandem, s jinou UI-položkou nebo se speciálním indexem. UI-položka a speciální index se při numerickém srovnání chovají jako binární numerické položky o délce 4 bytů (tj. s PIC S9(9) COMP); srovnává se tedy binární hodnota obsažená v jim přiděleném slově a nikoliv pořadí odpovídající této hodnotě. Při numerickém srovnání se srovnávají numerické hodnoty obou operandů; přitom záleží pouze na numerických hodnotách operandů a nikoliv na jejich typech, USAGE a PICTURE. Speciální srovnání (SP) Při speciálním srovnání je alespoň jeden z obou operandů speciální index. Druhý operand je buďto též speciální index nebo numerická položka (pak je srovnání přípustné jen tehdy, je-li celočíselná) nebo numerický literál (pak je srovnání přípustné jen tehdy, je-li celočíselný a má nejvýše 9 cifer) anebo ZERO, ZEROS, ZEROES. Pro definici způsobu srovnání je třeba znát délku položky, v jejímž popisu je tento speciální index definován v klauzuli INDEXED (tj. délku úseku paměti opakujícího se vzhledem k té klauzuli OCCURS, v níž je speciální index definován): a) Máme-li srovnat dva speciální indexy, z nichž levému přísluší délka úseku d a pravému h, pak budeme ve skutečnosti numericky srovnávat h-násobek hodnoty levého speciálního indexu a d-násobek hodnoty pravého speciálního indexu. Takto se vlastně srovnávají pořadí odpovídající oběma speciálním indexům. b) Máme-li srovnat speciální index, jemuž přísluší délka úseku d, s numerickou položkou nebo s numerickým literálem nebo se ZERO (-S, -ES), pak budeme ve skutečnosti numericky srovnávat hodnotu speciálního indexu s d-násobkem hodnoty druhého operandu zmenšené o jednu. Takto se vlastně srovnává pořadí odpovídající speciálnímu indexu s hodnotou druhého operandu. Příklad: 03 A PIC S9(5). 03 B PIC X(8) OCCURS 10 INDEXED I. 03 C PIC X(12) OCCURS 30 INDEXED J. Speciálnímu indexu I odpovídá délka úseku d = 8 (tj. délka položky B) a tedy pořadí I/8+1. Speciálnímu indexu J odpovídá délka úseku h = 12 (tj. délka položky C) a tedy pořadí J/12+1. Při relačním testu I < J se ve skutečnosti numericky srovnává 12*I a 8*J, což je ekvivalentní se srovnáním obou pořadí I/8+1 a hodnoty J/12+1. Při relačním testu I > A se ve skutečnosti numericky srovnává I a (A - 1) * 8, což je ekvivalentní se srovnáním pořadí I/8+1 a hodnoty položky A. Při relačním testu I = 7 se ve skutečnosti numericky srovnává I s celým číslem 48, což je ekvivalentní se srovnáním pořadí I/8+1 s celým číslem 7. 5.4.2. Znaménkový test Znaménkový test zjišťuje znaménko hodnoty operandu. Je pravdivý tehdy, když skutečné znaménko hodnoty operandu odpovídá použitému formátu testu. Formát: - - | numerická položka | - - | aritmetický-výraz | | NEGATIVE | < UI-položka > IS [NOT] < ZERO > | speciální index | | POSITIVE | - - - - Funkce: Znaménkový test může být vždy nahrazen relačním testem, který je s ním rovnocenný jak významem (pravdivostní hodnotou), tak i instrukcemi přeloženého programu. A NEGATIVE ... A < 0 (záporné) A NOT NEGATIVE ... A NOT < 0 (nezáporné) A ZERO ... A = 0 (nulové) A NOT ZERO ... A NOT = 0 (nenulové) A POSITIVE ... A > 0 (kladné) A NOT POSITIVE ... A NOT > 0 (nekladné) Znaménkový test je vlastně jen jiným zápisem relačního testu a proto je vcelku bez praktického významu. Příklady: POCET POSITIVE MZDA OF CLOVEK IN CESKOSLOVENSKO (I) IS ZERO A + B * (C - D) NOT NEGATIVE 5.4.3. Test NUMERIC Test NUMERIC zjišťuje, zda uvedená položka má numerický obsah odpovídající popisu položky. Formát: položka IS [NOT] NUMERIC Položka musí mít USAGE DISPLAY nebo USAGE COMP-3, tj. musí to být skupinová, alfanumerická, alfanumerická editovaná, rozpakovaná, pakovaná, exponenciální znaková nebo numerická editovaná položka. Test není přípustný pro položku binární (USAGE COMP), exponenciální krátkou (USAGE COMP-1), exponenciální dlouhou (USAGE COMP-2) ani pro položku s USAGE INDEX. Význam: 1) U rozpakované numerické položky s předepsaným znaménkem (tj. se znakem S v PICTURE) se zkoumá: a) Zda první až předposlední byte položky obsahují cifry (hexadecimálně 30 až 39). b) Zda levý půlbyte posledního bytu položky obsahuje hexadecimální 3 nebo 4 (znaménkový půlbyte). c) Zda pravý půlbyte posledního bytu položky bez předepsaného znaménka obsahuje hexadecimální cifru 0 až 9. 2) U rozpakované numerické položky bez předepsaného znaménka (tj. bez S v PICTURE) a dále u skupinové, alfanumerické a alfanumerické editované položky se zkoumá, zda všechny byty položky obsahují cifry (hexadecimálně 30 až 39). 3) U pakované numerické položky se zkoumá: a) Zda první až předposlední byte položky obsahují na svém levém i na svém pravém půlbytu hexadecimální cifru 0 až 9. b) Zda levý půlbyte posledního bytu položky obsahuje hexadecimální cifru 0 až 9. c) Má-li vzor položky v klauzuli PICTURE sudý počet znaků 9, zkoumá se, zda levý půlbyte prvního bytu položky obsahuje hexadecimální nulu (neboť jinak obsah položky neodpovídá jejímu popisu). d) Má-li položka předepsáno znaménko (tj. má-li v PICTURE znak S), zkoumá se, zda pravý půlbyte posledního bytu položky obsahuje hexadecimální 3 nebo 4 (znaménkový půlbyte). e) Nemá-li položka předepsáno znaménko (tj. nemá-li v PICTURE znak S), zkoumá se, zda pravý půlbyte posledního bytu obsahuje hexadecimální 3. 4) U exponenciální znakové položky se zkoumá, zda obsah položky odpovídá jejímu popisu, tj. zda začíná znaménkem nebo mezerou, zda pak následuje patřičný počet cifer s případnou tečkou na správném místě, zda dále následuje písmeno E, opět znaménko nebo mezera a dvě cifry exponentu. Jsou-li mantisa resp. exponent nezáporné, smí na jejich znaménkovém bytu být znaménko plus nebo mezera nezávisle na tom, zda ve vzoru je použito znaménko plus nebo minus. Dále není požadována normalizace mantisy. 5) U numerické editované položky se zkoumá, zda obsah položky odpovídá jejímu popisu. Jako numerický je uznán výhradně přesně takový obsah, který by vznikl jako výsledek numerického přesunu příslušné hodnoty do této položky. Příklad: PICTURE USAGE hexadec.obsah test NUMERIC je ________________________________________________________ XXX DISPLAY 333835 pravdivý XXX DISPLAY 333845 nepravdivý XXX DISPLAY 203835 nepravdivý XB0 DISPLAY 332030 nepravdivý 999 DISPLAY 333835 pravdivý 999 DISPLAY 333845 nepravdivý S999 DISPLAY 333835 pravdivý S999 DISPLAY 333845 pravdivý S999 DISPLAY 203835 nepravdivý 9999 COMP-3 000000 nepravdivý 9999 COMP-3 023453 pravdivý 9999 COMP-3 023454 nepravdivý 9999 COMP-3 123453 nepravdivý S9999 COMP-3 023454 pravdivý 99999 COMP-3 123453 pravdivý Z99 DISPLAY 403035 pravdivý Z99 DISPLAY 303035 nepravdivý Z99 DISPLAY 202035 nepravdivý Příklad: Má-li položka PIC -9.99E+99, pak pro pravdivost testu NUMERIC musí obsahovat: + nebo - nebo mezeru, cifru, tečku, dvě cifry, písmeno E, + nebo - nebo mezeru a dvě cifry. Poznámka: Při rutinním zpracování by měla být kontrola numeričnosti vstupních údajů prováděna bezprostředně po jejich prvotním načtení do paměti. Protože bývají data pořizována většinou ve znakovém tvaru, neměl by být test NUMERIC pro pakované položky vlastně nikdy používán. 5.4.4. Test ALPHABETIC Formát: položka IS [NOT] ALPHABETIC Položka musí být skupinová, alfanumerická nebo alfanumerická editovaná. Test ALPHABETIC je pravdivý tehdy, když tato položka obsahuje pouze velká písmena (A až Z) a mezery. Příklad: Má-li položka A PIC X(5), pak test "A IS ALPHABETIC" je pravdivý při hexadecimálním obsahu např. 534D20524B; byl by však nepravdivý, kdyby třeba jen na jediném bytu položky bylo hexadecimální 00, pomlčka (2D), malé a (61) FF apod. 5.4.5. Test podmínkového jména Formát: test-podmínkového-jména (viz l.5.) Uvádí se tedy pouze podmínkové jméno, v případě potřeby opatřené ještě kvalifikací a indexy (viz 1.5. a 4.6.). Test podmínkového jména je pravdivý tehdy, když hodnota příslušné podmínkové proměnné patří do množiny hodnot určených popisem uvedeného podmínkového jména (viz 4.6.). Příklad: 04 A PIC 99. 88 B VALUE 23. 88 C VALUE 32 THRU 56 88 D VALUE 5, 54, 18, 42. 88 E VALUE 72 THRU 84, 23, 98 THRU 100,7,28. Pak následující dvojice podmíněných výrazů jsou ekvivalentní: B je ekvivalentní s A = 23 C je ekvivalentní s (A NOT < 32 AND A NOT > 56) D je ekvivalentní s (A = 5 OR A = 54 OR A = 18 OR A = 42) E je ekvivalentní s (A NOT < 72 AND A NOT > 84 OR A = 23 OR A NOT < 98 AND A NOT > 100 OR A = 7 OR A = 28) Píšeme např.: IF C MOVE 5 TO POCET. IF B OF A GO TO KONEC. IF D AND (IND = 3 OR E) PERFORM ZPRAC. 5.4.6. Test UPSI-bytu Test UPSI-bytu zjišťuje, zda jednotlivé bity UPSI-bytu mají hodnotu 0 nebo 1. Jak známo, UPSI-byte se v operačním systému DOS-3 nacházel na 24. bytu systémové komunikační oblasti COMREG. Používal se jednak pro předávání indikací uživatelovu programu monitorovským příkazem UPSI, dále pro potlačení provádění následujících monitorovských příkazů EXEC při vhodném nastavení v uživatelově programu, a konečně pro předávání indikací mezi dvěma uživatelovými programy - ať už se jednalo o hlavní program a podprogram anebo o dva programy pracující po sobě v rámci téhož jobstepu anebo i v různých jobstepech. Pro účely MX COBOLu byl zaveden soubor MXCOMREG.COB, který částečně nahrazuje chybějící oblast COMREG (viz 4.11.1). Formát 1: UPSI-n (n = 0,1,2,3,4,5,6,7) Význam: Číslo "n" označuje, o který bit UPSI-bytu se jedná; bity číslujeme zleva doprava od 0 do 7 (tedy UPSI-0 odpovídá bitu hex. 80, UPSI-1 odpovídá bitu hex. 40 atd., až UPSI-7 odpovídá bitu hex. 01). Jednoduchý podmíněný výraz UPSI-n je pravdivý, je-li na příslušném bitu 1 a nepravdivý při 0 (má tedy přesně stejný význam, jaký by mělo speciální jméno přidělené k tomuto UPSI-n ve SPECIAL-NAMES pomocí klauzule ON STATUS; viz dále). Formát 2: speciální-jméno Význam: Toto speciální jméno musí být přiřazeno v paragrafu SPECIAL-NAMES k nějakému UPSI-n pomocí klauzule ON STATUS (pak je pravdivé, je-li na příslušném bitu 1 a nepravdivé při 0) anebo pomocí klauzule OFF STATUS (pak je pravdivé je-li na příslušném bitu 0 a nepravdivé při 1); viz 3.1.3. Příklad: Je-li druhý bit UPSI-bytu zleva (hex. 40) roven 0 nebo je-li hodnota položky A větší než 5 anebo jsou-li současně pátý a sedmý bit UPSI-bytu zleva (hex. 08 a hex. 02) rovny 1, máme tedy odskočit na proceduru OSETRENI. a) Řešení dle Formátu 1 (lze provést bez jakýchkoliv přiřazení ve SPECIAL-NAMES, není však přípustné v některých implementacích jazyka COBOL): SPECIAL-NAMES. UPSI-1 OFF STATUS IS NENI-ZAPNUTO UPSI-4 ON STATUS IS CTVRTY UPSI-6 ON STATUS IS OPRAVNY-CHOD. . . . IF NENI-ZAPNUTO OR A > 5 OR CTVRTY AND OPRAVNY-CHOD GO TO OSETRENI. Poznámka: Jednotlivé bity UPSI-bytu lze v MX COBOLu nastavovat pomocí příkazu "SET UPSI TO řetězec" (viz 12.1.). 5.4.7. Složený podmíněný výraz Podmíněným výrazem nazýváme přípustnou posloupnost složenou z těchto prvků: a) jednoduché podmíněné výrazy b) logické operátory: NOT ... logické "ne" (negace) AND ... logické "a" (konjunkce) OR ... logické "nebo" (disjunkce) c) závorky: ( ... levá závorka ) ... pravá závorka Tabulka 8: Přípustné pořadí prvků v podmíněném výrazu. ----------------------------------------------------------- | . smí stát | jednoduchý podm.výraz | AND | | . prvek | NOT | OR | | za prvkem . | ( | ) | |----------------------|--------------------------|-------| | jednoduchý podm.výraz| ne | ano | | ) | | | |----------------------|--------------------------|-------| | NOT,AND,OR,( | ano | ne | ----------------------------------------------------------- Kromě toho platí tato pravidla: 1) Na začátku podmíněného výrazu smí stát jednoduchý podmíněný výraz, levá závorka a NOT. 2) Každé levé závorce musí odpovídat právě jedna pravá závorka a naopak; musí jich tedy být stejný počet. Vždy musí být levá závorka před sobě odpovídající pravou závorkou a mezi nimi musí být právě tolik levých závorek, kolik je tam pravých závorek. 3) Konec podmíněného výrazu nastává v situaci, kdy za jednoduchým podmíněným výrazem nebo za pravou závorkou je tečka nebo tam není ani AND ani OR ani pravá závorka, anebo je tam pravá závorka, které však v tomto podmíněném výrazu neodpovídá žádná levá závorka. Poznámka: Nejjednodušším (a také nejobvyklejším) případem podmíněného výrazu je tedy samotný jednoduchý podmíněný výraz. Pravidla: Při vyhodnocování (tj. zjišťování pravdivosti) složeného podmíněného výrazu platí tato pravidla o prioritách: a) Nejvyšší prioritu má vyhodnocení jednotlivých jednoduchých podmíněných výrazů. b) Závorky mají vyšší prioritu než logické operátory NOT, AND a OR; vnitřní závorky mají vyšší prioritu než vnější. (Závorky mají tedy stejnou úlohu a jejich použití se řídí stejnými pravidly jako v aritmetickém výrazu). c) NOT má vyšší prioritu než AND i než OR. d) AND má vyšší prioritu než OR. Příklady: a) Podmíněný výraz NOT A = 1 OR B = 1 AND C = 1 se vyhodnocuje tak, jako kdyby byl uzávorkován takto: (NOT (A = 1)) OR ((B = 1) AND (C = 1)) b) Podmíněný výraz NOT (A = 1 AND B = 1 OR C = 1) AND D = 1 OR E = 1 se vyhodnocuje tak, jako kdyby byl uzávorkován takto: ((NOT (((A = 1) AND (B = 1)) OR (C = 1))) AND (D = 1)) OR (E = 1) c) Podmíněný výraz A = 1 AND NOT B = 1 AND C = 1 OR NOT D = 1 AND E = 1 se vyhodnocuje tak, jako kdyby byl uzávorkován takto: (((A = 1) AND (NOT (B = 1))) AND (C = 1)) OR ((NOT (D = 1)) AND (E = 1)) Pravdivostní hodnota složeného podmíněného výrazu: Nechť A a B jsou buďto jednoduché podmíněné výrazy anebo takové části složeného podmíněného výrazu, které buďto jsou anebo by (vzhledem k výše definovaným prioritám) mohly být uzavřeny v závorkách. a) NOT se vztahuje pouze k jednomu výrazu (následujícímu); přitom výraz NOT A je pravdivý právě když výraz A je nepravdivý. b) AND se vztahuje ke dvěma výrazům (předcházejícímu a následujícímu); přitom výraz A AND B je pravdivý právě když oba výrazy A i B jsou pravdivé. c) OR se vztahuje ke dvěma výrazům (předcházejícímu a následujícímu); přitom výraz A OR B je pravdivý právě když alespoň jeden z obou výrazů A a B je pravdivý. Tabulka 9: Význam logických operátorů NOT, AND, OR. ------------------------------------------------------------ | A | B | NOT A | A AND B | A OR B | |----------|-----------|-----------|-----------|-----------| |pravdivý | pravdivý | nepravdivý| pravdivý | pravdivý | |----------|-----------|-----------|-----------|-----------| |pravdivý | nepravdivý| nepravdivý| nepravdivý| pravdivý | |----------|-----------|-----------|-----------|-----------| |nepravdivý| pravdivý | pravdivý | nepravdivý| pravdivý | |----------|-----------|-----------|-----------|-----------| |nepravdivý| nepravdivý| pravdivý | nepravdivý| nepravdivý| ------------------------------------------------------------ Každý složený podmíněný výraz může být sestaven ze svých jednoduchých podmíněných výrazů postupným aplikováním logických operátorů NOT, AND a OR podle pravidel o prioritách (jak je provedeno např. ve výše uvedených příkladech). Pokud pravidla o prioritách neurčují pořadí aplikování logických operátorů jednoznačně (jak je tomu jedině ve výrazech typu A = 1 AND B = 1 AND C = 1 anebo D = 1 OR E = 1 OR F = 1), postupuje se zleva doprava. Známe-li přitom pravdivostní hodnoty všech použitých jednoduchých podmíněných výrazů, můžeme postupnou aplikací vyhodnocovacích pravidel (viz Tabulka 9) určit pravdivostní hodnotu celého složeného podmíněného výrazu (to jest: můžeme určit, zda je pravdivý nebo nepravdivý). Poznámka: Bývá zvykem říkat, že při vyhodnocování složeného podmíněného výrazu nejprve vyhodnotíme výrazy v závorkách a to od vnitřních závorek k vnějším, pak vyhodnotíme výrazy opatřené operátorem NOT, pak výrazy spojené operátorem AND a nakonec výrazy spojené operátorem OR. Tato formule může pomáhat při vyhodnocování v jednoduchých konkrétních případech, nicméně není pravdivá, neboť ve skutečnosti se při vyhodnocování složeného podmíněného výrazu v tomto pořadí nepostupuje, i když pravdivostní hodnota vychází stejná. A přitom způsob a pořadí vyhodnocování nejsou jen vnitřní záležitostí překladače a mohou být pro programátora značně zajímavé. Obvyklé tvrzení, že totiž podmíněný výraz má jen dva možné stavy - je pravdivý nebo nepravdivý - platí bohužel jen ve zjednodušené teorii. Při praktickém výpočtu může podmíněný výraz nabývat jednoho z těchto tří navzájem se vylučujících stavů: l) při vyhodnocování bude shledán pravdivým; 2) při vyhodnocování bude shledán nepravdivým; 3) při vyhodnocování dojde k chybě a k ukončení výpočtu. Toto rozdělení platí jak pro jednoduché, tak i pro složené podmíněné výrazy. U jednoduchého podmíněného výrazu s výjimkou obou třídních testů a testu UPSI-bytu může dojít k chybě, pokud některá z použitých numerických položek má nepřípustný obsah, při nekladném, příliš velkém nebo nenumerickém indexu resp. položce za DEPENDING, při exponenciálním přetečení, při dělení nulou, při nepřípustném umocňování, při nepřidělené paměti atd. Při vyhodnocování složeného podmíněného výrazu může dojít k situaci, že některý z jeho jednoduchých podmíněných výrazů už nemůže ovlivnit výsledek vyhodnocování celkového složeného podmíněného výrazu a proto vůbec vyhodnocován nebude. V takovém případě bude složený podmíněný výraz vyhodnocen bez chyby, i kdyby snad ten přeskočený jednoduchý podmíněný výraz nebyl v danou chvíli schopen bezchybného vyhodnocení. Chce-li programátor tohoto "jevu" využít, musí znát, v jakém pořadí se vyhodnocování provádí a za jakých okolností dojde k přeskočení některých jednoduchých podmíněných výrazů. Platí zde tato pravidla: Jednoduché podmíněné výrazy se naprosto vždy vyhodnocují v tom pořadí, v němž následují za sebou ve zdrojovém programu. Přijde-li se na vyhodnocování některého jednoduchého podmíněného výrazu, zjistí se (pokud ovšem jeho vyhodnocování neskončí chybou) jeho pravdivost či nepravdivost: v jednom případě se pak přechází na vyhodnocování bezprostředně následujícího jednoduchého výrazu a v druhém případě se odskakuje, a to buďto na vyhodnocování jednoduchých podmíněných výrazů, anebo už je přímo určeno, že celý složený podmíněný výraz je pravdivý nebo nepravdivý. Je-li při vyhodnocování výrazu typu A AND B výraz A shledán nepravdivým, nutně musí být celý výraz A AND B též nepravdivým, a proto se vyhodnocování výrazu B již neprovádí. Je-li při vyhodnocování výrazu typu A OR B výraz A shledán pravdivým, nutně musí být celý výraz A OR B též pravdivým a proto se vyhodnocování výrazu B již neprovádí. Pravdivostní hodnotu složeného podmíněného výrazu můžeme přesně určit tak, že místo zjednodušené tabulky 9 použijeme následující úplnou tabulku: Tabulka 10: Přesný význam logických operátorů NOT, AND, OR. -------------------------------------------------------------- | A | B || NOT A | A AND B | A OR B | |----------|-----------||-----------|-----------|------------| |pravdivý | pravdivý || nepravdivý| pravdivý | pravdivý | |pravdivý | nepravdivý|| nepravdivý| nepravdivý| pravdivý | |pravdivý | chybný || nepravdivý| chyba | pravdivý | |nepravdivý| pravdivý || pravdivý | nepravdivý| pravdivý | |nepravdivý| nepravdivý|| pravdivý | nepravdivý| nepravdivý | |nepravdivý| chybný || pravdivý | nepravdivý| chyba | |chybný | pravdivý || chyba | chyba | chyba | |chybný | nepravdivý|| chyba | chyba | chyba | |chybný | chybný || chyba | chyba | chyba | -------------------------------------------------------------- Poznámka: Pořadí výrazů A a B ve složených výrazech typu A AND B a A OR B není tedy zaměnitelné! Příklad: Podmíněný výraz A NUMERIC AND A NOT = 0 AND B / A > 1 se vyhodnocuje takto: ------------- ------------- ano ----------- ne -------------ano| podmíněný | |A NUMERIC ?|-->--| A = 0 ? |-->-| B/A > 1 ? |->-| výraz je | ------------- ----------- ------------- | pravdivý | | ne |ano |ne ------------- | | -------------- | | | podmíněný | ------------------------>---| výraz je | | nepravdivý | -------------- Při uvedeném pořadí jednoduchých podmíněných výrazů nedojde k chybě a k ukončení výpočtu v žádném případě, ani když je A nenumerické anebo když je rovno nule. Při jakémkoliv jiném pořadí jednoduchých podmíněných výrazů A NUMERIC, A NOT = 0 a B / A > 1 zřejmě může za určitých okolností k chybě dojít. Příklad: Jsou-li A,B,C,D,E,F podmínková jména, vyhodnocuje se podmíněný výraz (A AND B OR C) AND D OR E AND F takto: --------->------- --------------->------------- |ne | |ano | | | | ------------ -----ano-----ne -----ano-----ne -----ano-----ano| podmíněný| | A |->-| B |->-| C |->-| D |-->| E |->-| F |->-| výraz je | ----- ----- ----- ----- | ----- ----- | pravdivý | |ano |ne | | |ne |ne ------------ --------|->------ | | ------------- | | | | podmíněný | ------>------ ->-| výraz je | | nepravdivý| ------------- 5.4.8. Zamlčené levé operandy a relační operátory Ve složeném podmíněném výrazu lze za určitých podmínek zkrátit zápis jednoduchých podmíněných výrazů, které mají určitou část (levý operand a případně i relační operátor) shodnou s předcházejícím jednoduchým podmíněným výrazem: a) U relačního, znaménkového nebo třídního testu, který následuje bezprostředně za jiným relačním, znaménkovým nebo třídním testem, lze vynechat levý operand. Podmíněný výraz se pak zpracovává tak, jako kdyby u druhého testu byl uveden stejný levý operand jako u prvního testu. b) U relačního testu, který následuje bezprostředně za jiným relačním testem, lze vynechat levý operand i relační operátor. Podmíněný výraz se pak zpracovává tak, jako kdyby u druhého testu byl uveden stejný levý operand i stejný relační operátor jako u prvního testu. c) Levý operand a případně i relační operátor mohou být vynechány i v několika testech za sebou, přičemž lze libovolně kombinovat oba způsoby vynechávání (pouze levý operand nebo levý operand i relační operátor). Místo zamlčeného levého operandu se použije nejblíže před ním uvedený levý operand a podobně místo zamlčeného relačního operátoru se použije nejblíže před ním uvedený relační operátor. d) První test v celém podmíněném výrazu a dále každý test následující bezprostředně po testu podmínkového jména nebo po testu UPSI-bytu nesmí mít vynechán ani levý operand ani relačním operátor. Test následující bezprostředně po znaménkovém nebo po třídním testu smí mít vynechán levý operand, nesmí však mít vynechán relační operátor. Naproti tomu levá ani pravá závorka nezakazují vynechávání levých operandů a relačních operátorů u následujících testů. Formáty: 1) Relační test s vynechaným levým operandem: IS [NOT] relační-operátor pravý-operand 2) Relační test s vynechaným levým operandem i s vynechaným relačním operátorem: pravý-operand 3) Znaménkový nebo třídní test s vynechaným levým operandem: - - | NEGATIVE | IS [NOT] < POSITIVE > | NUMERIC | | ALPHABETIC | - - (Při znaménkovém testu se slovem ZERO není vynechávání levého operandu povoleno, protože jinak by mohlo dojít k záměně s relačním testem s pravým operandem ZERO). Příklady: a) A = B AND (C OR < D) AND E OR F = G OR > H OR I se překládá jako: A = B AND (A = C OR A < D) AND A < E OR F = G OR F > H OR F > I. b) A NUMERIC AND (= B OR C) AND POSITIVE se překládá jako: A NUMERIC AND (A = B OR A = C) AND A POSITIVE. Poznámka: Je-li vynechán levý operand a není-li uvedeno slovo IS, pak by u slova NOT mohlo dojít ke dvojznačnosti. Platí, že pokud by slovo NOT mohlo být interpretováno buďto jako logický operátor nebo jako součást relačního operátoru, dává se přednost té interpretaci, při níž se slovo NOT považuje za součást relačního operátoru. (Tak je tomu tehdy, když za slovem NOT stojí <, LESS, =, EQUAL, >, GREATER, NEGATIVE, POSITIVE, NUMERIC nebo ALPHABETIC). Tedy výraz A < B OR NOT = C OR D se překládá tak, že slovo NOT se považuje za součást relačního operátoru "NOT=", tedy jako A < B OR A NOT = C OR A NOT = D a nikoliv tak, že by se slovo NOT považovalo za logický operátor stojící před zkráceným relačním testem "=C", tedy jako A < B OR NOT A = C OR A = D. Tento zápis se však v některých implementacích jazyka COBOL interpretuje právě druhým z obou uvedených způsobů, takže je vhodné jej nevyužívat. Poznámka: Je-li operand vynechán, přenáší se z předchozího testu přesně v tom tvaru, v jakém je zapsán. Je-li tento levý operand náročný na vyhodnocování (např. aritmetický výraz, numerická editovaná nebo exponenciální znaková položka apod.), je výhodné převést jeho hodnotu předem do vhodné položky a tu pak použít v podmíněném výrazu. Příklad: Podmíněný výraz A + B + C = 2 OR 4 OR 6 OR 8 by byl vyhodnocován jako A + B + C = 2 OR A + B + C = 4 OR A + B + C = 6 OR A + B + C = 8. Proto je výhodné provést předem výpočet COMPUTE POM = A + B + C a podmíněný výraz pak zapsat ve tvaru POM = 2 OR 4 OR 6 OR 8.