Hlavní navigace

Programovací jazyk Ada: atributy, zobrazení číselných hodnot a úvod do procedur a funkcí

28. 5. 2015
Doba čtení: 5 minut

Sdílet

V minulém dílu našeho seriálu jsme poměrně zevrubně probrali různé příklady a ukázky silné typové kontroly jazyka Ada. V dnešním dílu se zaměříme na další atributy, doplníme popis těch již známých a podíváme se také na zobrazení číselných hodnot na výstupu v terminálu. Také načneme kapitolu o procedurách a funkcích.

V průběhu čtení článků jste si jistě všimli, že se zde používají zdánlivě velmi podobné atributy, které ale určitě nejsou stejné a proto si v dalším příkladu ukážeme, jak vlastně fungují. Jedná se o atributy Img/Image a Val/Value. Je samozřejmě možné si o nich přečíst v ALRM nebo v celkovém přehledu atributů. My si ale ukážeme názorné a jednoduché příklady. Vytvoříme proto novou proceduru:

with Ada.Text_IO;  use Ada.Text_IO;                         --1
    procedure Ada11 is                  --2

    x : Integer := 5;                   --3
    xx : String := "55";                    --4
    y : Float := 5.5;                   --5
    yy : String := "55.5";                  --6

    begin                           --7

        Put_Line("X = " & X'Img);           --8
        Put_Line("X = " & Integer'Image(X));        --9

        Put_Line("Y = " & Y'Img);           --10
        Put_Line("Y = " & Float'Image(Y));      --11

        Put_Line("XX = " & Integer'Val(X)'Img);     --12
        Put_Line("XX = " & Integer'Value(XX)'Img);  --13

--      Put_Line("YY = " & Float'Val(Y)'Img);       --14
        Put_Line("YY = " & Float'Value(YY)'Img);    --15

    end Ada11;                      --16

Výsledek:

./ada11
X =  5
X =  5
Y =  5.50000E+00
Y =  5.50000E+00
XX =  5
XX =  55
YY =  5.55000E+01
  • Na řádcích 3 – 6 vidíme deklaraci čtyř proměnných včetně nastavení jejich hodnoty. V těle procedury jsou pak 4 dvojice příkazů:
  • řádky 8 – 9 – zdánlivě stejné výsledky. Rozdíl je pouze v tom, že atribut Img se může použít přímo na objekt i na typ, kdežto atribut Image dává podtyp objektu
  • řádky 10 – 11 – to samé pro typ Float
  • řádky 12 – 13 – atribut P'Val má jeden parametr celočíselného typu a výsledek je typu P. Atribut P'Value má oproti tomu parametr typu String a výsledek je opět typu P.
  • řádky 14 – 15 – z výše uvedeného důvodu příkaz na řádku 14 vyhodí chybu, protože parametr atributu je Float, nikoliv očekávaný Integer. Value funguje stejně jako v předchozím případě.

Výsledný kód je v příloze ada11

Když už jsme narazili na atributy, které mohou sloužit k převodu typů mezi sebou, nesmíme zapomenout na jednu věc. Pokud konvertujeme celočíselný typ na typ s desetinnou čárkou, tak to není žádný problém. Obráceně už to může ale vypadat trochu jinak a je třeba dávat pozor na zaokrouhlování! Ukážeme si to na jednoduchém příkladu:

with Ada.Text_IO;  use Ada.Text_IO;
    procedure Ada12 is

    x : Float := 4.4;
    y : Float := 5.3;
    z1,z2 : Integer;

    begin

        z1 := Integer(x) + Integer(y);
        z2 := Integer (x+y);

        Put_Line("Z1 = " & Z1'Img);
        Put_Line("Z2 = " & Z2'Img);

    end Ada12;

Výsledek asi není třeba blíže komentovat:

./ada12
Z1 =  9
Z2 =  10

Konečný kód je v příloze ada12. Když už jsme narazili na zaokrouhlování, tak se v dalším příkladu podíváme na některé funkce, které mohou s tímto úkonem pomoci. Kód a výsledky jsou zde:

with Ada.Text_IO;  use Ada.Text_IO;
    procedure Ada13 is

    x : Float := 1.49;
    y : Float := 1.51;

    begin

        Put_Line("Floor(X) = " & Float'Floor(X)'Img);
        Put_Line("Floor(Y) = " & Float'Floor(Y)'Img);

        Put_Line("Ceiling(X) = " & Float'Ceiling(X)'Img);
        Put_Line("Ceiling(Y) = " & Float'Ceiling(Y)'Img);

        Put_Line("Rounding(X) = " & Float'Rounding(X)'Img);
        Put_Line("Rounding(Y) = " & Float'Rounding(Y)'Img);

        Put_Line("Floor(X) = " & Integer(Float'Floor(X))'Img);
        Put_Line("Floor(Y) = " & Integer(Float'Floor(Y))'Img);

        Put_Line("Ceiling(X) = " & Integer(Float'Ceiling(X))'Img);
        Put_Line("Ceiling(Y) = " & Integer(Float'Ceiling(Y))'Img);

        Put_Line("Rounding(X) = " & Integer(Float'Rounding(X))'Img);
        Put_Line("Rounding(Y) = " & Integer(Float'Rounding(Y))'Img);

    end Ada13;

./ada13
Floor(X) =  1.00000E+00
Floor(Y) =  1.00000E+00
Ceiling(X) =  2.00000E+00
Ceiling(Y) =  2.00000E+00
Rounding(X) =  1.00000E+00
Rounding(Y) =  2.00000E+00
Floor(X) =  1
Floor(Y) =  1
Ceiling(X) =  2
Ceiling(Y) =  2
Rounding(X) =  1
Rounding(Y) =  2

Kompletní kód je také v příloze ada13.

Kromě celočíselných typů a typů s plovoucí desetinnou čárkou definuje Ada také typy s pevnou desetinnou čárkou. Jedním z těchto typů je duration. Tento typ je typem předdefinovaným a používá se hlavně při práci s knihovnou Ada.Calendar. Zde je funkce Time, která vrací klasický aktuální čas (kolik je teď vlastně hodin?). Duration pak vrací uplynulý čas (za jak dlouho ten vlak vlastně jede?). Hodnota je v sekundách nebo jejich zlomcích. Největší hodnota je pak 24×60×60 = 86 400 s. Pro bližší informace bych případné zájemce odkázal na příslušný ALRM.

V minulém dílu jsme uvedli jednu z možností, jak zobrazit číselné hodnoty pomocí řetězcového výstupu na terminál. Existuje ještě jedna možnost, kterou si teď krátce předvedeme. Jedná se o to, že doposud jsme všude pro výstup používali knihovnu Ada.Text_IO. Kromě ní jsou ale k dispozici další dvě knihovny, a sice Ada.Integer_Text_IO a Ada.Float_Text_IO. Pomocí těchto knihoven můžeme zobrazovat dané hodnoty přímo, bez použití dalších atributů. Jejich použití je poměrně univerzální, ale to by bylo už nad rámec dnešního článku. My si jejich funkci proto ukážeme pouze na jednoduchém příkladu:

with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;
use Ada;
    procedure Ada14 is

    x : Float := 14.9;
    i : Integer := 51;

    begin

    Text_IO.Put_Line("I = ");
    Integer_Text_IO.Put(i);

    Text_IO.New_Line;
    Text_IO.Put_Line("X = ");
    Float_Text_IO.Put(x);

    end Ada14;

./ada14
I =
         51
X =
 1.49000E+01

Výsledný kód je v příloze ada14.

Tímto bychom mohli předchozí kapitoly uzavřít a pustit se do kapitoly další, velmi důležité. Tato kapitola se bude týkat podprogramů. Ada rozlišuje dva typy podprogramů: funkce a procedury. Volání procedury je samo o sobě příkazem a nevrací žádnou hodnotu. Funkce vrací hodnotu deklarovaného typu a musí být součástí nějakého výrazu. Podprogramy jazyka Ada mohou mít parametry tří typů:

  • in – aktuální hodnota parametru se přenáší do volání a nemůže být v podprogramu změněna. Formální parametr je konstantní, a tedy pouze ke čtení. Toto je výchozí mód, pokud není nic jiného deklarováno. Aktuální parametr je výraz
  • in out – aktuální parametr se přenáší do volání a může být redefinován. Formální parametr je proměnná a může být použit ke čtení i k zápisu
  • out – hodnota aktuálního parametru před voláním nemá smysl, hodnota se totiž přiřadí až při volání. Formální parametr může být pro čtení i zápis

Zvláštním typem formálního parametru může být typ access. Tento typ je podobný známým ukazatelům neboli pointerům z jiných jazyků. Nebudeme jej zatím nijak rozebírat, jenom je třeba upozornit na velmi široké možnosti, které třeba proti Pascalu nabízí.

Cloud23

Od standardu Ada 2012 mohou být parametry funkcí pouze typu in, takže je vlastně není nutné nijak definovat. Nejjednodušší bude, když si ukážeme a okomentujeme jednoduchou deklaraci i volání funkce a procedury na příkladě. Ten si ale necháme až do příštího dílu

Tímto dnešní díl ukončíme. Byl věnován hlavně atributům a zobrazení výstupních veličin (včetně konverze typů a zaokrouhlování). Také jsme lehce započali kapitolu o procedurách a funkcích. V příštím dílu se zaměříme hlavně na procedury a funkce (deklarace i volání) a na závěr se podíváme na aktuální verzi vývojového prostředí Ada.