Programovací jazyk Ada: numerický příklad, dělení do balíčků a jejich volání

Jaromír Vojtaj 18. 6. 2015

Minulý díl byl kompletně věnován instalaci nejnovější verze vývojového prostředí GNAT na OS Linux. Byla zmíněna i možnost využití dvou souborů v jednom projektu – specifikace a deklarace. V dnešním dílu se začneme věnovat práci v GPS a ukážeme si trochu složitější aplikaci včetně využití překladových jednotek.

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ů:

  1. v pracovním adresáři GPS si vytvoříme nový podadresář s názvem Kvadr_rov
  2. přímo v GPS vybereme menu Project → New a ve známém formuláři opět necháme vytvořit Single Project
  3. projekt nazveme kvadr_rov a umístíme ho do nově vytvořeného podadresáře Kvadr_rov
  4. nově vytvořený projekt nahradí v přehledu projektů GPS náš původní zkušební projekt z minulého příkladu
  5. 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
  6. 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
  7. 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.adbkvadrov1.ads a kva­drov1.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:

widgety

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.

Našli jste v článku chybu?
Vitalia.cz: Opuncie je plod kaktusu. Pozor na trny

Opuncie je plod kaktusu. Pozor na trny

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...

Vitalia.cz: Tahák, jak vyzrát nad zápachem z úst

Tahák, jak vyzrát nad zápachem z úst

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Vitalia.cz: Test dětských svačinek: Tyhle ne!

Test dětských svačinek: Tyhle ne!

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?

Lupa.cz: Patička e-mailu závazná jako vlastnoruční podpis?

Patička e-mailu závazná jako vlastnoruční podpis?

Podnikatel.cz: Chystá se smršť legislativních novinek

Chystá se smršť legislativních novinek

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

DigiZone.cz: Rapl: seriál, který vás smíří s ČT

Rapl: seriál, který vás smíří s ČT

DigiZone.cz: Ginx TV: pořad o počítačových hráčích

Ginx TV: pořad o počítačových hráčích

Podnikatel.cz: Babišovi se nedá věřit, stěžovali si hospodští

Babišovi se nedá věřit, stěžovali si hospodští

Podnikatel.cz: EET pro e-shopy? Postavené na hlavu

EET pro e-shopy? Postavené na hlavu

Vitalia.cz: Jaký je rozdíl mezi brambůrky a chipsy?

Jaký je rozdíl mezi brambůrky a chipsy?

Vitalia.cz: Když všichni seli řepku, on vsadil na dýně

Když všichni seli řepku, on vsadil na dýně

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

DigiZone.cz: Numan Two: rozhlasový přijímač s CD

Numan Two: rozhlasový přijímač s CD

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

Vitalia.cz: Jsou vegani a vyrábějí nemléko

Jsou vegani a vyrábějí nemléko