Výraz - syntaxe i sémantika podobné jako v matematice - obsahuje proměnné, konstanty, operátory, závorky, volání funkcí - všechny operátory nutno zapisovat (nelze např. vynechat znak násobení) - argumenty funkcí vždy v závorce (nelze např. sin x, musí být sin(x) ) - typ výsledné hodnoty je určen typem použitých proměnných, konstant, operátorů a funkcí - závorky pouze kulaté ( ), libovolně hluboko vnořené do sebe Vyhodnocování výrazu (pořadí provádění operátorů): 1. podle uzávorkování 2. podle priorit operátorů (násobení/dělení dříve než sčítání/odčítání) 3. operátory téže priority zleva doprava Příklady: (y + (sin(2*x) + 1)*2)/3 1 + 3/2 * 5 = 8.5 (1+3)/2 * 5 = 10 1 + 3/(2 * 5) = 1.3 Pavel Töpfer, 2017 Programování 1-3 1
Celočíselný výraz - konstanty a proměnné typu integer (příp. jiných celočíselných typů) - aritmetické operátory +, -, *, div, mod (celočíselné dělení a zbytek) - standardní funkce abs(x) absolutní hodnota z X sqr(x) druhá mocnina X Definice mod: (X div Y) * Y + (X mod Y) = X Pozor na záporné argumenty (způsob počítání může záviset na implementaci). Příklad: 7 div 3 = 2 7 mod 3 = 1-7 div 3 = -2-7 mod 3 = -1 7 div (-3) = -2 7 mod (-3) = 1 Použití: Y := X mod 10 - do Y se dá hodnota poslední cifry čísla X X := X div 10 - z čísla X se odebere jeho poslední cifra test, zda platí X mod 3 = 0 - test, zda X je dělitelné třemi Pavel Töpfer, 2017 Programování 1-3 2
Příklad: Spočítej ciferný součet zadaného kladného celého čísla načti vstupní hodnotu do proměnné X; Y := 0; dokud X není rovno 0 dělej ( Y := Y + X mod 10; X := X div 10 ); vypiš jako výsledek hodnotu proměnné Y Totéž jako program v Pascalu: program CifernySoucet; var X, Y: integer; begin read(x); Y := 0; while X <> 0 do begin Y := Y + X mod 10; X := X div 10 end; writeln(y) end. Pavel Töpfer, 2017 Programování 1-3 3
Výraz typu real - konstanty a proměnné typu real (příp. i celočíselné provádí se automatická konverze do typu real) - aritmetické operátory +, -, *, / - standardní funkce abs(x) absolutní hodnota z X sqr(x) druhá mocnina X sqrt(x) druhá odmocnina z X ln(x) přirozený logaritmus z X exp(x) e X sin(x) cos(x) arctan(x) goniometrické funkce Výraz typu integer lze dosadit do proměnné typu real (provádí se automatická konverze), obráceně nikoliv. Výraz 10/5 má sice hodnotu 2, ale je typu real (reálné dělení). Převod výrazu typu real na integer: konverzní funkce round(x) zaokrouhlení round(3.8) = 4 trunc(x) oříznutí desetinné části trunc(3.8) = 3 Pavel Töpfer, 2017 Programování 1-3 4
Cyklus while Podmínka do Příkaz - dokud je podmínka splněna, příkaz v těle cyklu se opakuje - cyklus s podmínkou na začátku tělo se nemusí provést ani jednou - více akcí v těle cyklu složený příkaz repeat Příkaz1; Příkaz2; ; PříkazN until Podmínka - příkazy v těle cyklu se opakují až do splnění podmínky - cyklus s podmínkou na konci tělo se vždy provede aspoň jednou - více akcí v těle cyklu lze přímo zapsat Příklady: Ciferný součet byl vysvětlen dříve Eukleidův algoritmus verze s odčítáním a s modulem Prvočíselný rozklad zkoušíme dělit 2, 3, 4, 5, dokud je co Pavel Töpfer, 2017 Programování 1-3 5
Cyklus FOR for Řídicí_Proměnná := Dolní_Mez to Horní_Mez do Příkaz - řídicí proměnná musí být normálně deklarovaná proměnná celočíselného typu, dolní o horní mez jsou celočíselné výrazy Příklad: součet deseti čísel zadaných na vstupu S:=0; for I:=1 to 10 do begin read(x); S:=S+X end; writeln(s); Pavel Töpfer, 2017 Programování 1-3 6
Sémantika for-cyklu - řídicí proměnná nabývá všech celočíselných hodnot počínaje dolní mezí a konče horní mezí (včetně), pro každou z nich se vykoná příkaz v těle cyklu - v příkazu lze využívat hodnoty řídicí proměnné (výhodné zejména pro indexování polí později) - výrazy určující meze se vyhodnocují jen jednou při vstupu do cyklu cyklus s pevným počtem opakování (případné změny horní meze v průběhu výpočtu cyklu již neovlivní počet opakování) - pokud je dolní mez větší než horní mez, příkaz se nevykoná ani jednou - pokud se horní mez rovná dolní mezi, příkaz se vykoná právě jednou - řídicí proměnná má po skončení cyklu poslední hodnotu, kterou nabyla, tzn. horní mez (podle normy není její hodnota definována) - změna řídicí proměnné uvnitř cyklu je možná a ovlivní počet opakování (tzn. je nebezpečná, může vést i k zacyklení, podle normy nebyla vůbec povolena raději nepoužívat) Pavel Töpfer, 2017 Programování 1-3 7
Varianta for-cyklu pro opačný směr průchodu for Řídicí_Proměnná := Horní_Mez downto Dolní_Mez do Příkaz - hodnota řídicí proměnné klesá po 1 od horní meze dolů k dolní mezi (jinak totéž) - použití není příliš časté, hodí se někdy při indexování polí Pavel Töpfer, 2017 Programování 1-3 8
Předčasné ukončení cyklu Občas se hodí mít možnost za určitých podmínek výpočet cyklu předčasně ukončit standardní procedura break použitá v těle cyklu (for, while, repeat), zpravidla v podmíněném příkazu. for I:=1 to N do begin ; ; ; if PodmínkaPředčasnéhoUkončení then break; ; ; ; end; Výpočet pokračuje příkazem následujícím bezprostředně za cyklem. Alternativní řešení: - ve for-cyklu dosadit do řídicí proměnné uměle hodnotu horní meze - v cyklu while/repeat přidat podmínku ukončení do podmínky cyklu V obou případech se ještě dopočítá až do konce aktuální průchod tělem cyklu (na rozdíl od použití break). Pavel Töpfer, 2017 Programování 1-3 9
Standardní procedura continue předčasné ukončení aktuální iterace cyklu, pokračuje se další iterací, pokud se ještě má provádět (provede se nové vyhodnocení podmínky cyklu). Pavel Töpfer, 2017 Programování 1-3 10
Procedura pro vstup dat read(a) - A je proměnná typu číslo (integer, real, atd.), znak (char) nebo znakový řetězec (string) - po vykonání příkazu je běžící program pozastaven a čeká na vstupní data - uživatel zadává vstupní data na klávesnici, čísla odděluje mezerami nebo pomocí Enter, zadávání dat musí ukončit klávesou Enter - dosavadní hodnota proměnné A se ztratí, proměnná A nabude hodnoty čtené ze vstupu - je-li A typu char: ze vstupu se do A přečte jeden znak - je-li A typu string: ze vstupu se přečtou všechny znaky až do konce řádku (tzn. do Enter) a uloží se do proměnné A - je-li A číslo: ze vstupu se přečtou případné úvodní mezery nebo Enter, dále se čtou znaky až do první mezery nebo do Enter, tato sekvence se zkonvertuje do požadované číselné hodnoty (pokud to lze, jinak nastane běhová chyba!) a uloží do proměnné A Pavel Töpfer, 2017 Programování 1-3 11
Je povolen tvar příkazu read(a, B, C) s libovolným počtem parametrů jakožto zkratka za read(a); read(b); read(c) readln ignorovat znaky ze vstupu až do Enter (včetně Enter), tzn. pokračovat ve čtení na začátku nového řádku readln(a) read(a); readln Pavel Töpfer, 2017 Programování 1-3 12
Procedura pro výstup dat write(a) - A je výraz typu číslo (integer, real, atd.), znak (char) nebo znakový řetězec (string) - výraz A je vyhodnocen a jeho hodnota vypsána na obrazovku Je povolen tvar příkazu write(a, B, C) s libovolným počtem parametrů jakožto zkratka za write(a); write(b); write(c) writeln přechod na nový řádek (vlastně vypsat Enter) writeln(a) write(a); writeln Příklad: var A, B, C: integer; A:=14; B:=7; C:=356; write(a, B, C); na výstupu: 147356 - bez oddělení! Pavel Töpfer, 2017 Programování 1-3 13
Je nutné zajistit oddělení hodnot na výstupu 1. použít pro každou hodnotu writeln výstupy jednotlivých čísel na samostatné řádky 2. použít oddělující mezery write(a,, B,, C); na výstupu: 14 7 356 3. Použít formátování výstupu write(a, B:5, C:5); na výstupu: 14 7 356 Formátování celočíselné hodnoty write(a: N) N je výraz typu integer, určuje počet znakových pozic na výstupu. Kratší hodnota se zleva doplní mezerami, delší hodnota se vypíše celá (na více pozic, tzn. nedodrží se předepsaný formát). Pavel Töpfer, 2017 Programování 1-3 14
Formátování hodnoty typu real write(r: N) - exponenciální tvar na N výstupních pozic -1.2E+01 (N=8) -1.2345678901E+01 (N=17) - pro N mezi 8 a 17 se doplňují desetinná místa (poslední cifra hodnoty je korektně zaokrouhlena) - pro N<8 výpis stejný jako pro N=8 - pro N>17 výpis jako pro N=17 doplněný zleva mezerami write(r) write(r:17) write(r: N: M) - desetinné číslo na N výstupních pozic, z toho M desetinných míst (poslední cifra hodnoty je korektně zaokrouhlena) - podle potřeby zleva doplněno mezerami - pokud hodnota nedovoluje dodržet předepsaný formát, nedodrží se Pavel Töpfer, 2017 Programování 1-3 15
Inicializace proměnných Proměnné hlavního programu mají v TP 7.0 automaticky počáteční hodnotu 0. Pozor - je to věc implementace, ještě v TP 6.0 nebyly inicializovány nijak (měly náhodnou hodnotu co zbylo v paměti počítače na příslušném místě), v jiném prostředí také nemusí být raději si zvyknout nespoléhat na to. Navíc ostatní proměnné (deklarované v procedurách a funkcích, dynamicky alokované bude později) nejsou ani v TP 7.0 nijak inicializovány. Možnost použít v programu inicializované proměnné požadovaná počáteční hodnota se uvádí v místě deklarace. Pavel Töpfer, 2017 Programování 1-3 16
Inicializované proměnné = typované konstanty - deklarují se pomocí const jako konstanty, jsou to ale proměnné (tzn. jsou umístěny v paměti a jejich hodnotu lze měnit dosazováním jako hodnotu každé jiné proměnné) - syntakticky se odlišují od konstant uvedením typu v deklaraci - syntaxe: const Jméno: Typ = Hodnota; (některé implementace ale používají var Jméno: Typ = Hodnota;) - lze použít i pro proměnné strukturovaného typu (např. pole) bude ukázáno později Příklad: const X = 10; {konstanta} var Y: integer; {obyčejná proměnná} const Z: integer = 10; {inicializovaná proměnná} Pavel Töpfer, 2017 Programování 1-3 17
Podmínka - jednoduchá relace < > = <= >= <> mezi dvěma výrazy - složená sestavená z více jednoduchých podmínek pomocí logických spojek not negace and konjunkce or disjunkce (alternativa) nevylučující xor vylučující disjunkce exclusive OR (nonekvivalence, negace ekvivalence) Příklady: if (A>=0) and (A<10) then while not ((X=0) or (Y=0)) do while (X<>0) and (Y<>0) do {A je nezáporné jednociferné} {oboje znamená totéž} Pavel Töpfer, 2017 Programování 1-3 18
Jednotlivé relace obsažené ve složené podmínce musí být uzavřeny v závorkách (relační operátory mají nižší prioritu než logické spojky)! Další kulaté závorky (s libovolnou úrovní vnoření do sebe) určují pořadí vyhodnocování složené podmínky. Kde nejsou závorky, rozhodují priority logických spojek: 1. not 2. and 3. or, xor Příklad: while not (X=0) or (Y=0) do while (not (X=0)) or (Y=0) do {znamená totéž jako:} Doporučení: raději psát závorky (prevence chyby). Pavel Töpfer, 2017 Programování 1-3 19
Test prvočíselnosti Úkol: otestovat dané číslo N, zda je prvočíslem 1. zkusit všechny dělitele od 2 do N-1 časová složitost O(N) cca N testů 2. stačí zkoušet všechny dělitele od 2 do N/2 (větší dělitel neexistuje) časová složitost opět O(N) cca N/2 testů, tedy o něco lepší 3. stačí zkoušet všechny dělitele od 2 do N (má-li N vlastního dělitele, musí mít i dělitele z tohoto intervalu) časová složitost O( N) cca N testů, asymptoticky lepší 4. stačí zkoušet dělitele od 2 do N, do nalezení prvního asymptotická časová složitost opět O( N), většinou se ale vykoná o dost méně testů - v nejhorším případě se vykoná N testů časová složitost O( N) - v nejlepším případě stačí pouze jeden test časová složitost O(1), tzn. konstantní Pavel Töpfer, 2017 Programování 1-3 20