Ada 95 #1/5 - typy - Politechnika Poznańska
Transkrypt
Ada 95 #1/5 - typy - Politechnika Poznańska
Plan wykładu • Hierarchia typów w Adzie • Typy skalarne • Typy dyskretne • Typ znakowy • Typ logiczny Ada 95 #1/5 - typy • Typy całkowite • Typy rzeczywiste Wojciech Complak, • Tablice i typ tablicowy Instytut Informatyki, Politechnika Poznańska e-mail : [email protected] www http://www.cs.put.poznan.pl/wcomplak : • Typ łańcuchowy • Typy rekordowe 2006-03-26, v. 0.14 Hierarchia typów w Adzie Typy skalarne typy Ady • wartości typów skalarnych są uporządkowane liniowo tablice • dostępne operatory : =, /=, <, <=, >, >= rekordy proste • ważniejsze atrybuty: złożone zadania wskaźnikowe dyskretne wyliczeniowe typy chronione skalarne rzeczywiste całkowite ze znakiem zmiennopozycyjne resztowe stałopozycyjne dziesiętne ¾ T’First – dolna granica zakresu typu T, typem wyniku jest typ T ¾ T’Last – górna granica zakresu typu T, typem wyniku jest typ T ¾ T’Range – równoważny zakresowi T’First .. T’Last ¾ T’Base – podtyp bazowy typu T zwykłe Typy dyskretne Typ znakowy • to takie typy skalarne, w których wartości mają numer pozycji będący liczbą całkowitą • w Adzie 83/95 są dostępne dwa typy znakowe • dodatkowe atrybuty: ¾ T’Pos – zwraca numer pozycji wartości będącej argumentem w zbiorze wartości typu dyskretnego T ¾ T’Val – zwraca tę wartość typu T, której numer wartości jest równy argumentowi wywołania ¾ Character – 8-bitowy typ znakowy, kod Latin-1 ¾ Wide_Character – 16-bitowy kod ISO 10646 • w Adzie 2005 pojawił się nowy typ znakowy ¾ Wide_Wide_Character – 32-bitowy typ znakowy Typ logiczny Typ całkowity • predefiniowany typ wyliczeniowy Boolean zawiera dwa literały True i False (False < True) • predefiniowany typ całkowity ze znakiem – Integer, przekroczenie zakresu powoduje wygenerowanie wyjątku Constraint_Error • typ Integer – standard, zakres co najmniej –2**15 .. +2**15-1, GNAT – 32 bity • typ Long_Integer – opcjonalny, jeśli jest, zakres co najmniej -2**31 .. +2**31-1, GNAT – 32 bity • pozostałe typy całkowite ze znakiem są opcjonalne, jeśli są muszą spełniać zależność : zakres(Long_Long_Integer) ≥ zakres(Long_Integer) ≥ zakres(Integer) ≥ zakres(Short_Integer) ≥ zakres(Short_Short_Integer) dla kompilatora GNAT : Long_Long_Integer ma 64 bity, Short_Integer ma 16 bitów, Short_Short_Integer ma 8 bitów • dodatkowe dostępne operatory : not, and, or, xor • w Adzie dostępne są skrócone formy sterowania „and then” i „or else”, w przypadku ich użycia lewy operand jest obliczany zawsze jako pierwszy i jeśli jego wartość wystarczy do określenia wartości wyrażenia prawy operand nie jest obliczany Typ całkowity resztowy Typy rzeczywiste • typ całkowity bez znaku, maksymalna podstawa to: • typ zmiennopozycyjny ¾System.Max_Binary_Modulus dla podstaw będących potęgami dwójki (GNAT – 2**Long_Long_Integer'Size) ¾System.Max_Nonbinary_Modulus dla pozostałych (GNAT : Integer'Last) type Byte is mod 256; type Word is mod 2**16; d : Byte; e : Word; a : Float; -- typ predefiniowany w pakiecie Standard type T1 is digits 8; -- dokładność 8 cyfr type T2 is digits 6 range 3.1 .. 5.4; -- dokładność 6 cyfr w podanym zakresie • typ stałopozycyjny zwykły i dziesiętny type T1 is delta 0.250 range 0.0 .. 10.0; -- wartości określane z rozdzielczością 0.250 -- w zadanym zakresie type T2 is delta 0.01 digits 9; -- typowe zastosowanie bankowo/księgowe -- 9 cyfrowe kwoty z dokładnością do groszy Tablice – deklaracje, typ tablicowy Tablice – inicjalizacja • przykłady deklaracji zmiennych tablicowych : • przykłady inicjalizacji ( :=, .., |, =>, others) W1 : array (1..3) of Integer; W2 : array (-5..4,2..3) of Boolean; • przykłady definicji typów i deklaracji tablic : -- typ tablicowy zawężony type T_W1 is array (1..5) of Integer; W1, W2 : T_W1; -- -------------------------------------------------------------------------------------------------------------------------------------------- -- typ tablicowy niezawężony type T_W2 is array (Positive range <>, Natural range <>) of Integer; W3 : T_W2(1..2,0..3); W4 : T_W2(2..2,3..3); -- -------------------------------------------------------------------------------------------------------------------------------------------- -- typ tablicowy niezawężony, rozmiar ustalany podczes inicjalizacji type T_W3 is array (Natural range <>) of Integer; W5 : T_W3 := (1,2,3,4,5); W1 : array (1 .. 3) of Integer := (1, 2, 3); -- OK -- W2 : array () of Integer := (others => 5); -- źle -- tak nie można, to nie C ! W2 : array (2 .. 4) of Integer := (others => 5); --- -- OK W3 : array (1 .. 8) of Integer := (1..2=>1, 3|6 =>4, 4..5=>2); -- źle -- inicjalizacja musi być kompletna W3 : array (1 .. 8) of Integer := (1..2=>1, 3|6=>4, 4..5=>2, others=>3); -- OK Tablice – atrybuty rozmiaru tablic (atrybut First) - dolna granica zakresu tablicy jednowymiarowej (lub pierwszego zakresu elementów tablicy wielowymiarowej), typem wyniku jest typ indeksu, (A jest zmienną/typem tablicowym) Tablice – atrybuty rozmiaru tablic (atrybut Last) • A’Last - górna granica zakresu tablicy jednowymiarowej (lub pierwszego zakresu elementów tablicy wielowymiarowej), typem wyniku jest typ indeksu, (A jest zmienną/typem tablicowym) • A’First(N) - dolna granica zakresu N-tego wymiaru elementów tablicy wielowymiarowej), typem wyniku jest typ indeksu, (A jest zmienną/typem tablicowym) • A’Last(N) - górna granica zakresu N-tego wymiaru elementów tablicy wielowymiarowej), typem wyniku jest typ indeksu, (A jest zmienną/typem tablicowym) Tablice – atrybuty rozmiaru tablic (atrybut Length) Tablice – atrybuty rozmiaru tablic (atrybut Range) • A’First • A’Length - liczba elementów tablicy jednowymiarowej (lub pierwszego wymiaru tablicy wielowymiarowej), typem wyniku jest liczba całkowita, (A jest zmienną/typem tablicowym) • A’Length(N)- liczba elementów N-tego wymiaru tablicy wielowymiarowej), typem wyniku jest liczba całkowita, (A jest zmienną/typem tablicowym) • A’Range - równoważne A’First..A’Last, typem wyniku jest zakres, (A jest zmienną/typem tablicowym) • A’Range(N) – równoważne A’First(N)..A’Last(N), typem wyniku jest zakres, (A jest zmienną/typem tablicowym) Tablice - korzystanie z atrybutów (#1/6) Tablice - korzystanie z atrybutów (#2/6) • przykład – atrybuty First, Last, Length, tablice jedno- i dwuwymiarowa • przykład – atrybuty First, Last, Length, Range wypełnianie tablicy jednowymiarowej with Ada.Text_IO, Ada.Integer_Text_IO; use Ada.Text_IO, Ada.Integer_Text_IO; procedure Test is W1 : array (1 .. 3) of Integer; W4 : array (1..2, 3..4) of Integer; begin Put_Line(""); Put(W1'First); Put(W1'Last(1)); Put(W1'Length); Put_Line(""); Put(W4'First); Put(W4'First(1)); Put(W4'First(2)); end Test; 1 1 3 1 3 3 procedure Test is W1 : array (1 .. 3) of Integer; begin for ind in 1 .. 3 loop W1(ind) := 1; end loop; -- fatalnie, 2! for ind in 1 .. W1'Length loop W1(ind) := 2; –- niby troche lepiej, 2+ end loop; end Test; Tablice - korzystanie z atrybutów (#3/6) Tablice - korzystanie z atrybutów (#4/6) • przykład – atrybuty First, Last, Length, Range wypełnianie tablicy jednowymiarowej • przykład – atrybuty First, Last, Length, Range wypełnianie tablicy jednowymiarowej procedure Test is W1 : array (1 .. 3) of Integer; begin procedure Test is W1 : array (1 .. 3) of Integer; begin for ind in W1'First .. W1'Last loop W1(ind) := 3; -- dobrze, rosnące indeksy end loop; for ind in W1'Last .. W1'First loop W1(ind) := 5; -- pętla się nie wykona, Last > First end loop; for ind in reverse W1'First .. W1'Last loop W1(ind) := 4; -- dobrze, malejące indeksy end loop; for ind in reverse W1'Last .. W1'First loop W1(ind) := 6; -- bezcelowe, pętla się nie wykona end loop; end Test; end Test; Tablice - korzystanie z atrybutów (#5/6) Tablice - korzystanie z atrybutów (#6/6) • przykład – atrybuty First, Last, Length, Range wypełnianie tablicy jednowymiarowej • przykład – dlaczego warto korzystać z atrybutu Range, tablica dwuwymiarowa procedure Test is W1 : array (1 .. 3) of Integer; begin for ind in W1'Range loop W1(ind) := 7; -- optymalne, rosnące indeksy end loop; for ind in reverse W1'Range loop W1(ind) := 8; -- optymalne, malejące indeksy end loop; end Test; procedure Test is W4 : array (1..2,2..3) of integer; begin for i in W4'First(1) .. W4'Last(1) loop for j in W4'First(2) .. W4'Last(1) loop W4(i,j) := 1; -- typowy błąd przy kopiuj/wklej end loop; end loop; for i in W4'Range(1) loop for j in W4'Range(2) loop W4(i,j) := 2; end loop; end loop; end Test; -- tak jest bezpieczniej Typ łańcuchowy (#1/3) Typ łańcuchowy (#2/3) • typ łańcuchowy jest zdefiniowany jako: • łańcuchy można porównywać za pomocą operatorów „=” i „/=” type String is array(Positive range <>) of Character; type Wide_String is array(Positive range <>) of Wide_Character; • łańcuchy można sortować leksykograficznie (operatory „<”, „<=”, „>”, „>=”) • dostępny jest operator konkatenacji „&” (łańcuch/znak & łańcuch/znak, wynikiem jest łańcuch) ¾ „fixed” – długość jest stała (tablice znaków), określana w trakcie kompilacji (SCRy) – pakiet Ada.Strings.Fixed with Ada.Text_IO; use Ada.Text_IO; procedure Test is Stars : String(1 .. 120) := (1 .. 120 => '*' ); Question : String := "How are you ?"; begin Put(Stars); Put(Question); Put(Stars & Question); end Test; • w Adzie są trzy typy łańcuchów : ¾ „bounded” – długość jest znana i/lub ograniczona (bazy danych, SCRy) – pakiet Ada.Strings.Bounded ¾ „unbounded” – długość jest dynamicznie zmienna, ograniczona zakresem liczb całkowitych (Integer’Last) i dostępną pamięcią sterty (systemy ogólnego przeznaczenia) – pakiet Ada.Strings.Unbounded Typ łańcuchowy (#3/3) Typ rekordowy nieparametryzowany • przykład z użyciem Unbounded_String • definicja typu rekordowego type Person is record Initial : Character; Age : Natural; end record; with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Strings.Unbounded; use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Strings.Unbounded; procedure Test is Str : Unbounded_String; begin -- Str := "test"; -- nie można, niezgodne typy Str := To_Unbounded_String("test"); Put(Length(Str)); end Test; Typ rekordowy z wariantami • definicja typu rekordowego type Device is (Printer, Disk, Drum); type State is (Open, Closed); type Peripheral(Unit : Device := Disk) is record Status : State; case Unit is when Printer => Line_Count : Integer range 1 .. Page_Size; when others => Cylinder : Cylinder_Index; Track : Track_Number; end case; end record; • deklaracje zmiennych Writer : Peripheral(Unit => Printer); type Cpx is record re, im : Float := 0.0; end record; • deklaracje zmiennych C1 : Cpx := (1.0, 2.0); A, B : Person := ('A',0);