Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 5: Typy porządkowe, wyliczeniowe i okrojone. Definiowanie typów. Instrukcja wyboru © Jan Kaczmarek
Przypomnienie o typach danych ! Określenie typu danych to określenie, jaki jest zbiór wartości, które może przyjmować dany obiekt. Z typem związany jest ponadto zbiór operacji, jakie można wykonać na jego wartościach. Najprostsze typy danych w Pascalu to typy standardowe (predefiniowane): - całkowite (integer, shortint, smallint, longint, byte, word) - rzeczywiste (real, single, double, extended) - logiczny (Boolean) - znakowy (char) - łańcuchowe (string, string[zakres]) Programista może sam określać (opisywać) bardziej złożone typy, może też definiować identyfikatory odpowiadające tym opisom.
Typy porządkowe Typy całkowite, typ logiczny i typ znakowy tworzą specjalny rodzaj typów nazywanych typami porządkowymi. Do typów porządkowych nie zaliczamy jednak typów rzeczywistych i łańcuchowych. Elementy typów porządkowych są ustawione w określonej kolejności. Każdy element, z wyjątkiem pierwszego, ma swój poprzednik (poprzedni element). Każdy element, z wyjątkiem ostatniego, ma swój następnik (następny element). Każdy element ma też swój numer porządkowy w typie, który jest wartością funkcji standardowej ord(x), gdzie x jest argumentem typu porządkowego. Pierwszy element ma numer 0, drugi 1 itd.(z wyjątkiem typów całkowitych, dla których ord(x)=x).
Typy porządkowe Na argumentach typu porządkowego określone są funkcje standardowe: pred(x)wartością jest poprzednik argumentu x succ(x)wartością jest następnik argumentu x odd(x)wartością jest TRUE, gdy x (typu całkowitego) jest nieparzyste, a FALSE, gdy x jest parzyste Na argumentach typu porządkowego możemy wykonać dwie standardowe operacje: dec(x)równoważne x := pred(x)(dekrementacja) inc(x)równoważne x := succ(x)(inkrementacja) Do typów porządkowych zaliczamy także dwa rodzaje typów, które nie są predefiniowane: - typy wyliczeniowe - typy okrojone
Typy wyliczeniowe Typ wyliczeniowy nie jest predefiniowany, tzn. wymaga opisu. Opis typu wyliczeniowego ma następującą postać: (lista-identyfikatorów) gdzie lista-identyfikatorów zawiera identyfikatory tworzące zbiór wartości danego typu, oddzielone przecinkami. Obiekty, które są danego typu wyliczeniowego mogą przyjmować wartości, które są z tego zbioru. Typ wyliczeniowy stosuje się dla zbiorów o niewielkiej liczbie elementów (maksymalna ilość elementów wynosi 256), na których nie wykonuje się operacji arytmetycznych. * Identyfikatory na liście muszą być różne. * Ten sam identyfikator nie może wystąpić w dwóch różnych typach. * Porządek w typie wyliczeniowym jest zgodny z kolejnością na liście. * Wartości zmiennych tego typu nie można wypisać instrukcją write (writeln). Przykłady: type barwa = (bialy, czerwony, zielony, niebieski, czarny); kolor = (trefl, karo, kier, pik, bez_atu); waluta = (jen, korona, zloty, dolar, euro, funt);
Typy okrojone Typ okrojony nie jest predefiniowany, tzn. wymaga opisu. Opis typu okrojonego ma następującą postać: stala-1.. stala-2 gdzie stala-1 i stala-2 są stałymi tego samego typu porządkowego, nazywanego typem bazowym dla danego typu okrojonego, przy czym ord(stala-1) <= ord(stala-2). Obiekty, które są danego typu okrojonego mogą przyjmować wartości, które są ze zbioru ograniczonego wartościami podanych stałych. Porządek w typie okrojonym jest zgodny z porządkiem w typie bazowym. Przykłady: type zakres = ;{typ bazowy integer} liczba_lat = ;{typ bazowy byte} cyfra = 0.. 9;{typ bazowy char} znaki = !.. +;{typ bazowy char} silna_waluta = dolar.. funt;{typ bazowy waluta}
Definiowanie typów Definicja typów ma postać: type sekwencja-definicji-typów gdzie każdy element sekwencji-definicji-typów ma postać: identyfikator-typu = opis-typu; identyfikator-typu to identyfikator, a opis-typu to inny identyfikator lub opis typu, który jest niestandardowy. Definicja typów powinna wystąpić w części {definicje i deklaracje} po deklaracjach modułów i stałych, a przed deklaracjami zmiennych. Przykład: type marka = (fiat, opel, honda, bmw, porsche, jaguar); zakres = ; duza_litera = A.. Z;
Typy porządkowe w instrukcji dla (for...) Instrukcja dla ma jedną z dwóch postaci: for z:=w1 to w2 do instrukcja; for z:=w1 downto w2 do instrukcja; gdzie w ogólnym przypadku z jest zmienną typu porządkowego (tzw. zmienną sterującą), a w1 i w2 to wyrażenia typu porządkowego, wyliczane na początku wykonania instrukcji dla jeden raz. Wykonanie instrukcji dla w ogólnym przypadku ilustrują następujące fragmenty schematu blokowego:
z:= w1 z := succ(z)z <= w2 instrukcja TAK NIE z:= w1 z := pred(z)z >= w2 instrukcja TAK NIE for z:=w1 to w2 do instrukcja; for z:=w1 downto w2 do instrukcja;
Instrukcja wyboru (case …) case selektor of case selektor of sekwencja-instrukcji-wyboru sekwencja-instrukcji-wyboru end; else instrukcja end; selektor to dowolne wyrażenie typu porządkowego sekwencja-instrukcji-wyboru to lista instrukcji, z których każda poprzedzona jest stałą wyboru typu porządkowego, postaci: stała lub stała.. stała bądź listą stałych tej postaci oddzielonych przecinkami. Wykonanie instrukcji wyboru polega na wyznaczeniu wartości selektora i wykonaniu tylko tej z instrukcji wewnętrznych, która jest poprzedzona stałą równą obliczonej wartości selektora. Jeśli żadna z instrukcji wewnętrznych nie jest poprzedzona stałą równą obliczonej wartości selektora, to wykonywana jest instrukcja występująca po else (o ile występuje) lub nic się nie wykonuje.
program wybor; {program ilustruje wykonanie instrukcji case} {$APPTYPE CONSOLE} uses SysUtils; var x, y : integer; begin readln (x); readln (y); case x-y of 0: writeln (roznica liczb wynosi zero'); , 1..4: writeln (roznica liczb jest miedzy -4 a -1 lub miedzy 1 a 4'); , 5..9: writeln(roznica liczb jest miedzy -9 a -5 lub miedzy 5 a 9'); else writeln ('roznica liczb poza przedzialem'); end; end.