Abychom se postupně dostali k ukázce dříve popsaných či naznačených možností a vlastností GPS, provedeme několik jednoduchých kroků:
- v pracovním adresáři GPS si vytvoříme nový podadresář s názvem Kvadr_rov
- přímo v GPS vybereme menu Project → New a ve známém formuláři opět necháme vytvořit Single Project
- projekt nazveme kvadr_rov a umístíme ho do nově vytvořeného podadresáře Kvadr_rov
- nově vytvořený projekt nahradí v přehledu projektů GPS náš původní zkušební projekt z minulého příkladu
- vytvoříme pomocí menu File → New nový soubor a uložíme ho pod názvem (automaticky se nám nabízí) kvadr_rov.adb. Pokud bychom totiž začali vkládat text ještě před uložením souboru příslušného typu, přišli bychom o jednu zásadní vlastnost GPS – inteligentní kontextovou nápovědu při psaní kódu a doplňování výrazů, názvů proměnných a podobné vymoženosti, kvůli který vlastně vývojová prostředí vznikají a používají se
- postupně pak vložíme kód a kdykoliv v průběhu psaní můžeme použít nám již známou funkci Check Semantic
- výsledný kód vypadá následovně:
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; --1 with Ada.Text_IO; use Ada.Text_IO; --2 procedure kvadr_rov is --3 r1,r2 : Float; --4 plati : Boolean; --5 procedure Quadra (A, B, C : Float; R1, R2 : out Float; Valid : out Boolean) is --6 Z : Float; --7 begin --8 Z := B**2 - 4.0 * A * C; --9 if Z < 0.0 or A = 0.0 then --10 Valid := False; --11 R1 := 0.0; --12 R2 := 0.0; --13 else --14 Valid := True; --15 R1 := (-B + Sqrt (Z)) / (2.0 * A); --16 R2 := (-B - Sqrt (Z)) / (2.0 * A); --17 end if; --18 end Quadra; --19 begin --20 Quadra(1.0,3.0,1.0,r1,r2,plati); --21 Put_Line("Vysledky reseni: " & plati'Img); --22 Put_Line("R1 = " & r1'Img); --23 Put_Line("R2 = " & r2'Img); --24 end kvadr_rov; --25
- Na 1. řádku se volá standardní knihovna numerických funkcí, protože při výpočtu budeme v proceduře potřebovat funkci SQRT (odmocnina).
- Na 4. řádku jsou definovány proměnné pro výstup z procedury výpočtu – kořeny rovnice
- Na 5. řádku je definována proměnná pro výstup z procedury – platnost výpočtu
- Na 6. řádku je definovaná procedura, která má tři vstupní údaje – koeficienty kvadratické rovnice, dva výstupní parametry – kořeny rovnice a jeden výstupní parametr – platnost výpočtu
- Na 9. řádku probíhá výpočet diskriminantu
- V proceduře nejsou nijak řešeny chyby, takže na 10. řádku se kontroluje hodnota diskriminantu a koeficientu A. Výpočet proběhne řádně pouze tehdy, když jsou kořeny reálné. Pro komplexní kořeny se vrátí nuly a výsledná platnost je nastavena na FALSE
- Na řádku 22 si můžeme všimnout textu, který není s diakritikou. Zatím ponecháme bez komentáře a vrátíme se k tomu později
Kompletní kód je v příloze kvadr_rov.adb.
Nyní můžeme postupně vyzkoušet funkce Check Semantic, Build Main a Run Main. Výsledky jsou vidět na prvních třech obrázcích galerie. Na čtvrtém obrázku jsou vidět výsledky pro zadání, které vrací (tedy spíše nevrací…) komplexní kořeny rovnice. Uvedený příklad je sice trochu „umělý“ a spíše připomíná škrábání levou nohou za pravým uchem, ale pro názornost v první fázi je dostačující a také se nám bude hodit později. Navíc si teď ukážeme ještě jednu možnost, kterou Ada nabízí – využití uživatelských balíčků v dalších programech a aplikacích. Vytvoříme si tedy nový podadresář a v GPS nový projekt (Kvadrov) a postupně vytvoříme tři (nikoliv tedy pouze dva) soubory: solve.adb, kvadrov.ads a kvadrov.adb. Jejich obsahy uvedeme zde a také do přílohy - solve1.adb, kvadrov1.ads a kvadrov1.adb.
Začneme od konce a jako první vytvoříme soubor kvadrov.ads:
package kvadrov is --1 procedure Quadra (A, B, C : in Float; R1, R2 : out Float; Valid : out Boolean); --2 end kvadrov; --3
Jak je vidět, je to velmi jednoduchý soubor se třemi řádky.
- 1. řádek – jediná změna proti minulým příkladům je název – místo klíčového slova procedure je použito klíčové slovo package
- 2. řádek – zde je deklarovaná procedura s parametry bez dalšího kódu
Dále vytvoříme soubor kvadrov.adb:
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; --1 package body kvadrov is --2 procedure Quadra (A, B, C : in Float; R1, R2 : out Float; Valid : out Boolean) is --3 Z : Float; --4 begin --5 Z := B**2 - 4.0 * A * C; --6 if Z < 0.0 or A = 0.0 then --7 Valid := False; --8 R1 := 0.0; --9 R2 := 0.0; --10 else --11 Valid := True; --12 R1 := (-B + Sqrt (Z)) / (2.0 * A); --13 R2 := (-B - Sqrt (Z)) / (2.0 * A); --14 end if; --15 end Quadra; --16 begin --17 null; --18 end kvadrov; --19
I zde došlo ke zkrácení a zjednodušení původního kódu.
- 1. řádek – zůstal pouze řádek s odkazem na numerickou knihovnu, protože zde žádný výstup použit není
- 2. řádek – znovu je použito klíčové slovo package a k němu ještě body – jedná se o tělo balíčku
- 3. – 17. řádek – žádná změna proti minulému příkladu
- 18. řádek – překladač zde vyžaduje nějaký (ale pro něj přijatelný…) kód, jinak hlásí chybu
Jako poslední vytvoříme soubor solve.adb:
with Ada.Text_IO; use Ada.Text_IO; --1 with kvadrov; --2 procedure solve is --3 r1,r2 :Float; --4 plati : Boolean; --5 begin --6 kvadrov.Quadra(1.0,3.0,1.0,r1,r2,plati); --7 Put_Line("Vysledky reseni: " & plati'Img); --8 Put_Line("R1 = " & r1'Img); --9 Put_Line("R2 = " & r2'Img); --10 end solve; --11
- 1. řádek – zde je oproti předchozímu kódu jenom odkaz na výstupní knihovnu, žádné výpočty nejsou třeba
- 2. řádek – odkazujeme se na námi vytvořený balíček. Použije se pouze direktiva with, bez use – vysvětlíme si později
- 3. řádek – opět použito klíčové slovo procedure, jak jsme byli zvyklí
- 4. – 5. řádek – deklarace lokálních proměnných stejná jako v původním příkladu
- 7. řádek – volání externího balíčku a funkce v něm. Z tohoto důvodu nebyla ve 2. řádku použita direktiva use, aby bylo úplně jasné, ze kterého balíčku se volá jaká funkce či procedura (GPS i zde vzorně napovídá!)
Pro vyzkoušení překladu a spuštění vytvořené aplikace je nutné jako Main File označit solve. adb a spustit funkce Build Main a Run Main. Výsledek výpočtu je pro zadané koeficienty (1.0,3.0 a 1.0 – reálné kořeny) v příloze solve1.txt. Když nyní porovnáme oba dnešní příklady, tak si můžeme všimnout několika rozdílů:
- první je celý v jednom souboru
- druhý obsahuje soubory tři
- první soubor má celkem 25 řádků
- tři soubory z druhého příkladu mají celkem 33 řádků, což není zase takový rozdíl
- druhý příklad ukazuje možnosti, jak využít nejen dělení balíčků na specifikaci a tělo, ale jak je volat z jiných balíčků nebo procedur, a to opakovaně
- druhý příklad se bude jednodušeji udržovat a měnit, protože každý ze souborů má jasně danou strukturu
Tímto srovnáním dnešní díl ukončíme a v příštím dílu budeme pokračovat dalšími ukázkami možností jazyka Ada na tomto příkladu.