Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 6: Tablice, rekordy, zbiory © Jan Kaczmarek
Typy strukturalne Typy strukturalne są używane do opisu obiektów złożonych, tzn. takich, które w danym momencie przechowują nie jedną, ale kolekcję wielu wartości. Typy strukturalne definiuje się na podstawie pewnych schematów strukturalizacji podając typy składowych i metodę strukturalizacji, określającą mechanizm dostępu do danych elementów struktury. W Pascalu mamy cztery rodzaje struktur: - tablice – opisywane typami tablicowymi - rekordy – opisywane typami rekordowymi - zbiory – opisywane typami zbiorowymi - pliki – opisywane typami plikowymi
Tablice Tablica składa się z elementów jednakowego typu, przy czym każdy element tablicy może być jawnie nazwany (wskazany), a liczbę elementów ustala się w chwili opisywania (deklarowania) tablicy i nie można tej liczby zmienić. Tablica posiada regularną strukturę i dlatego jest używana do reprezentowania regularnych układów danych, np. wektorów: lub macierzy: 8 -4 6 12 -3 10 2 4 9 2 7 3 10 4 5 1 11 6 9 8 12
Typy tablicowe Definicja typu tablicowego ma postać: type identyfikator-typu = array [typy-indeksów] of typ-bazowy; gdzie: typy-indeksów – oddzielone przecinkami opisy typów porządkowych (najczęściej wykorzystuje się tu typy okrojone lub wyliczeniowe) typ-bazowy – dowolny typ prosty lub strukturalny. Rozmiar tablicy ustalony jest na etapie kompilacji. Przykłady: type wektor = array [1..10] of integer; //10 elementów macierz = array [-10..10, 1..8] of real; //168 elementów tab1 = array [5..8, Boolean] of byte; //8 elementów tab2 = array [1..5] of array [1..20] of real; //100 elementów tablica = array [1..5, 1..20] of real; //100 elementów var T1: macierz; //deklaracja tablicy typu macierz T2: array [1..20] of byte; //deklaracja tablicy 20 elementów typu byte
Dla tablic metoda dostępu do danych nazywa się indeksowaniem Dla tablic metoda dostępu do danych nazywa się indeksowaniem. Indeksem może być dowolne wyrażenie zgodne z odpowiadającym mu na danej pozycji typem indeksu podanym w definicji typu tablicowego. Wartości indeksów są wyliczane w chwili odwołania się do elementu tablicy. Przykłady: T1[3, 7] := 2.5; T1[3][7] := 2.5; T2[5] := 5; var //wczytywanie danych do tablicy T1 : macierz; i, j : integer; begin for i:=-10 to 10 do for j:=1 to 8 do begin write (‘kolejny element = ’); readln (T1[i, j]); end; end.
program suma; {program znajdowania sumy n elementów jednowymiarowej tablicy A} {$APPTYPE CONSOLE} uses SysUtils; var n, i : integer; suma : real; A : array [1..100] of real; //tablica A ma co najwyżej 100 elementów begin write (‘podaj n: ‘); readln (n); //1<=n<=100 for i:=1 to n do //wczytywanie elementów tablicy A begin write (’podaj A[’, i, ’] =’); readln (A[i]); end; suma := 0; for i:=1 to n do suma := suma+A[i]; write (’suma = ’ , suma); readln; end.
program maximum; {program znajdowania największego elementu w tablicy A} {$APPTYPE CONSOLE} uses SysUtils; var n, i : integer; max : real; A : array [1..100] of real; //tablica A ma co najwyżej 100 elementów begin write (‘podaj n: ‘); readln (n); //1<=n<=100 for i:=1 to n do //wczytywanie elementów tablicy A begin write (’podaj A[’, i, ’] =’); readln (A[i]); end; max := A[1]; for i:=2 to n do if A[i]>max then max := A[i]; write (’najwiekszy element = ’ , max); readln; end.
Rekordy Rekordem nazywamy złożoną strukturę danych, której elementy, zwane polami, mogą być (w odróżnieniu od tablic) różnych typów (prostych lub strukturalnych). Pola muszą mieć różne identyfikatory, a ich ilość jest z góry ustalona. Rekord posiada strukturę używaną do reprezentowania układów różnego typu danych, tworzących pewne całości: Nr indeksu D123456 Imię Adam Nazwisko Kowalski Miejscowość Poznań Adres ul. Mickiewicza 22 m. 3 Kierunek studiów informatyka Rok 3 Semestr Z Pesel 88021601123 NIP 777-888-23-24 Telefon (61) 8765432
Typy rekordowe Definicja typu rekordowego ma postać: Typy rekordowe Definicja typu rekordowego ma postać: type identyfikator-typu = record lista-deklaracji-pól; end; gdzie lista-deklaracji-pól ma postać: lista-identyfikatorów-pól : opis-typu; Ostatnie pole może być polem wariantowym postaci: case pole-wyróżnikowe of wykaz-wariantów; gdzie pole-wyróżnikowe może być identyfikatorem typu porządkowego lub deklaracją zmiennej porządkowej wykaz-wariantów ma postać: lista-etykiet-wyboru : (lista-deklaracji-pól)
Przykład: type data = record. //typ rekordowy. dzien : 1. 31; Przykład: type data = record //typ rekordowy dzien : 1..31; //typ okrojony miesiac : 1..12; rok : integer; end; rodzaj = (ciezarowy, osobowy); //typ wyliczeniowy pojazd = record //typ rekordowy marka, kolor : string[20]; data_rejestracji : data; case typ : rodzaj of //pole wariantowe ciezarowy : (ladownosc : real); osobowy : (ilosc_osob : byte); end; var auto : pojazd; //deklaracja zmiennej rekordowej
Metody dostępu do pól rekordów - kwalifikowanie za pomocą selektora, który ma postać: identyfikator-rekordu.identyfikator-pola gdzie identyfikator-rekordu to zmienna rekordowa Uwaga! Kropka oddziela nazwę zmiennej rekordowej od identyfikatora pola. - instrukcja wiążąca postaci: with lista-zmiennych do instrukcja; Umieszczenie zmiennej rekordowej na liście-zmiennych oznacza, że do pól tej zmiennej można odwoływać się wewnątrz instrukcji wiążącej za pomocą samych identyfikatorów pól. Identyfikatory te są traktowane w instrukcji wewnętrznej tak, jak zmienne. Instrukcja with z1, z2, ..., zn do instrukcja; jest równoważna instrukcji zagnieżdżonej with z1 do with z2 do .............. with zn do instrukcja;
Przykłady: auto. marka := ’Ford’; auto. data_rejestracji Przykłady: auto.marka := ’Ford’; auto.data_rejestracji.dzien := 4; auto.data_rejestracji.miesiac := 6; auto.data_rejestracji.rok := 2007; with auto do begin marka := ’Ford’; data_rejestracji.dzien := 4; data_rejestracji.miesiac := 6; data_rejestracji.rok := 2007; end; with auto.data_rejestracji, auto do begin marka := ’Ford’; dzien := 4; miesiac := 6; rok := 2007; end;
Zbiory Zbiory wraz z operacjami na nich zdefiniowanymi umożliwiają zapis obliczeń teoriomnogościowych. Struktury te mają jednak zastosowanie w ograniczonym zakresie. Każdy zbiór jest zbiorem wszystkich podzbiorów (tzw. zbiorem potęgowym), łącznie ze zbiorem pustym, typu bazowego. Typ bazowy musi być typem porządkowym o maksymalnie 256 elementach (liczby porządkowe elementów muszą być z przedziału 0-255). Przykład: Typ bazowy = {a, b, c} Zbiór = {[ ], [a], [b], [c], [a,b], [a,c], [b,c], [a,b,c]}
Typy zbiorowe Definicja typu zbiorowego ma postać: Typy zbiorowe Definicja typu zbiorowego ma postać: type identyfikator-typu = set of typ-porządkowy; Zmienne tego typu zajmują od 1 do 32 bajtów. Ilość zajmowanych bajtów = ord(max) div 8 – ord(min) div 8 + 1. Konstruktor zbioru ma postać [ ]. Przykłady: type pory_roku = (wiosna, lato, jesien, zima); //typ wyliczeniowy pory = set of pory_roku; //typ bazowy – pory_roku liczby = set of 1..8; //typ bazowy – 1..8 litery = set of ’a’..’z’; //typ bazowy – ’a’..’z’ var Z1 : pory; //1 bajt Z2 : liczby; //2 bajty Z3 : litery; //4 bajty ord(’z’)=122, ord(’a’)=97 Z1 := [ ]; //przykłady podstawień Z1 := [lato, zima]; Z2 := [1, 2, 5]; Z3 := [’a’..’d’];
Wartości zmiennych typu zbiorowego nie można wypisać w standardowy sposób przy pomocy instrukcji write, writeln. Na zmiennych zbiorowych można wykonywać operacje teoriomnogościowe. Operatory teoriomnogościowe operator operacja argumenty wynik ----------------------------------------------------------------------------------------------------- + suma zbiorów typ zbiorowy typ zbiorowy – różnica zbiorów typ zbiorowy typ zbiorowy * iloczyn zbiorów typ zbiorowy typ zbiorowy <= jest zawarty, jest podzbiorem typ zbiorowy Boolean >= zawiera, jest nadzbiorem typ zbiorowy Boolean = równy typ zbiorowy Boolean <> różny typ zbiorowy Boolean in należy, jest elementem typ bazowy, zbiór Boolean
Przykład: var z1, z2, zw : set of (a, b, c, d); w : Boolean; begin z1 := [a..c]; z2 := [a, b]; zw := z1+ z2; // zw=[a, b, c] zw := z1+ [d]; // zw=[a, b, c, d] zw := z1 – z2; // zw=[c] zw := z1 – [c]; // zw=[a, b] zw :=z1*z2; // zw=[a, b] zw := z1+ [ ] // zw=z1 w := a in z1; // w=true w := z1<= [a, c] // w=false end.