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);