Masz pytanie ? Zadaj je na naszym Forum Turbo Pascal. Rejestracja w 5 sekund ;-)
Co to jest mniej więcej typ
pisałem w poprzednim dziale, a w niniejszym
opiszę dość dokładnie poszczególne typy wraz ze sposobami ich definicji w programie.
Podział typów danych:
Typy proste są podstawowymi typami języka Turbo Pascal i za ich pomocą określa się bardziej złożone struktury danych. Wszystkie typy proste składają się ze skończonego i uporządkowanego zbioru wartości. Dzięki temu na wartościach tych typów możemy m.in. wykonywać operacje porównań. Typy proste dzielimy na
Typami porządkowymi nazywamy wszystkie typy proste z wyjątkiem typów rzeczywistych. Wyróżnienie to jest spowodowane faktem, że typy rzeczywiste często nie mogą występować w kontekście dozwolonym dla innych typów prostych. Dla wartości każdego typu porządkowego są określone wartości poprzednie i następne (z wyjątkiem wartości krańcowych). Do typów porządkowych zaliczamy:
Typ wyliczeniowy stosuje się zwykle dla zbiorów o niewielkiej liczbie elementów, na których nie wykonuje się operacji arytmetycznych. Definicja jednego typu wyliczeniowego jest następująca:
TYPE identyfikator_typu = (lista_identyfikatorów);
Elementy typu wyliczeniowego są uporządkowane zgodnie z kolejnością ich wyliczenia w definicji typu i posiadają liczby porządkowe odpowiednio 0,1,2 itd. Przyklady:
TYPE Uczniowie = (Antek, Franek, Zenek); {Antek ma 0, Franek ma 1, a Zenek 2}
P_roku = (wiosna, lato, jesien, zima);
Typy całkowite są w języku TP predefiniowane i nie wymagają opisu w programie. Wszystkie typy całkowite są podzbiorami zbioru liczb całkowitych. Wśród typów całkowitych wyróżniamy:
Przyklad, przypuśćmy, że zdefiniowaliśmy nowy typ:
TYPE Liczba = Integer;
W takim razie poniższa deklaracja :
VAR i,j: Liczba;
jest równoważna deklaracji
VAR i,j: Integer;
Standardowymi typami logicznymi są typy Boolean, ByteBool, WordBool i LongBool. Wartości typów logicznych są oznaczone za pomocą dwu predefiniowanych literałów (stałych): True i False, oznaczających odpowiednio wartości logiczne fałsz i prawda, przy czym w sensie uporządkowania stała False poprzedza stałą True. Liczbami porządkowymi elementów typu Boolean są tylko 0 (False) i 1 (True). Elemanty pozostałych typów logicznych mogą posiadać inne (wyższe) liczby porządkowe.
Do oznaczenia typu znakowego służy predefiniowany identyfikator Char. Elementami typu znakowego są znaki ASCII, z których każdy jest pamiętany w jednym bajcie pamięci.
Typy okrojone służą do ograniczania zakresów wartości dowolnego z dotychczas opisanych typów porządkowych. Definicja jednego typu okrojonego ma postać :
TYPE identyfikator_typu = stała .. stała;
Pierwsza stała podaje ograniczenie dolne i nie może być większa od drugiej - ograniczenia górnego. Stałe te muszą być tego samego typu porządkowego. Przyklad:
TYPE Litery = 'A' .. 'Z';
Do typów prostych należą także standardowe typy rzeczywiste, które jednak nie są typami porządkowymi. Każdy z dostępnych typów rzeczywistych jest dyskretnym i skończonym podzbiorem zbioru liczb rzeczywistych. Dostępnych jest pięć standardowych typów rzeczywistych o następujących predefiniowanych identyfikatorach:
Typy łańcuchowe służą do reprezentowania ciągu znaków, w tym niewidocznego znaku spacji. Elementami typu łańcuchowego są łańcuchy o długości od 0 do długości podanej w definicji typu łańcuchowego. Typ ten definiuje się następująco:
TYPE identyfikator_typu = String[rozmiar];
lub
TYPE identyfikator_typu = String;
gdzie rozmiar jest liczbą typu Byte. Brak wyspecyfikowania rozmiaru powoduje domyślne przyjęcie długości 255 znaków (warość maksymalna). Przykład:
TYPE Nazwisko = String[20];
Typy stukturalne stosuje się do opisu obiektów złożonych, przy czym dany obiekt możemy opisać na kilka róznych sposobów. Każdy z typów strukturalnych definiowany jest przez podanie typów składowych i metody strukturalizacji, która zarazem określa sposób dostępu do elementów składowych. W ogólności definicja pojedyńczego typu strukturalnego ma postać:
TYPE Identyikator_typu = Opis_typu_strukturalnego;
przy czym opis typu strukturalnego może być opisem typu.
Typ tablicowy, a konkretnie tablica składa się z ustalonej liczby elementów tego samego typu, zwanego typem składowym, który może być zarówno typem prostym lub łańcuchowym, jak i typem strukturalnym. Za pomocą tablic są reprezentowane regularne układy danych, np. wektory i macierze. Dostęp do poszczególnych elementów tablic uzyskuje się za pomocą indeksowania. Indeksem może być dowolne wyrażenie, którego wartość jest zgodna w sensie przypisania z typem indeksowym. Dopuszczalny zakres indeksów jest podany w definicji typu tablicowego. Definicja pojedynczego typu tablicowego ma postać:
TYPE Identyfikator_typu = array[typy_indeksowe] of typ_składowy;
gdzie typy indeksowe są opisami typu porządkowego (z wyjątkiem typu LongInt), przy czym poszczególne opisy oddziela się przecinkami. Typ składowy oznacza dowolny typ. Przykłady:
TYPE Macierz = array[1..20,1..30] of Real; Tablica = array[Boolean,1..20,znak] of Char;
Typem rekordowym, a dokładniej rekordem nazywamy złożoną strukturę danych, której składowe, zwane polami, mogą mieć rózne charakterystyki (należeć do różnych typów). Poszczególne pola mogą być same strukturami złożonymi, przy czym liczba pól rekordu jest ustalona. Definicja typu rekordowego określa typ i identyfikator dla każdego pola. Definicja ta rozpoczyna się słowem kluczowym record, po którym podaje się deklarację każdego pola, a kończy słowem kluczowym end. Poszczególne deklaracje pól oddziela się średnikami. Ostatnia deklaracja może być wariantowa (case .. of). Definicja pojedynczego typu rekordowego ma postać:
TYPE Identyfikator_typu = record Lista_deklaracji_pól end;
gdzie każda z deklaracji pól ma postać:
lista_nazw_pól : opis_typu;
a ostatnia deklaracja może mieć postać (deklaracja wariantowa):
case deklaracja_pola_wyróżnikowego of wykaz_wariantów;
lub
case identyfikator_typu_porządkowego of wykaz_wariantów;
przy czym deklaracja pola wyróżnikowego wygląda następująco:
identyfikator_pola_wyróżnikowego : identyfikator_typu_porządkowego;
lub
lista_etykiet_wyboru : (lista_deklaracji_pól);
Przykłady rekordów:
TYPE Data = record rok : Integer; miesiac : 1 .. 12; dzien : 1 .. 31; end; TYPE Rejestry = record case Integer of 1: (AX, BX, CX, DX : Word); 2: (AL, AH, BL, BH, CL, CH, DL, DH : Byte); end; end;
Typ zbiorowy jest zbiorem potęgowym danego typu porządkowego, tzn. jest zbiorem wszystkich podzbiorów tego typu, w tym zbioru pustego. Liczba elementów typu zbiorowego nie może przekraczać 256 (przedział od 0 do 255). Definicja pojedynczego typu zbiorowego ma postać:
TYPE Identyfikator_typu = set of typy_porządkowy;
Przykład:
TYPE Klasy = set of (LO_1d, LO_2d, LO_3d,LO_4d);
ementami typu Klasy może być dowolny podzbiór zbioru podanych nazw
klas, m.in.:
[ LO_1d, LO_2d ] - podzbiór dwuelementowy
[ LO_3d ] - podzbiór jednoelementowy
[ ] - zbiór pusty
[ LO_1d, LO_2d, LO_3d, LO_4d ] - podzbór czteroelementowy
Typy plikowe są ściśle powiązane z plikami. Plik jest ciągiem elementów tego samego typu, tyle że liczba jego składowych jest zmienna. Jest ona uzależniona od przebiegu wykonywania programu, a w szczególności od skojarzenia pliku z fizycznym zbiorem danych. Od tablicy plik różni się ponadto metodą dostępu do poszczególnych elementów. Definicja pojedynczego typu plikowego ma postać:
TYPE Identyfikator_typu = file of opis_typu_elementów_pliku;
lub
TYPE Identyfikator_typu = file;
Jeżeli w definicji typu plikowego pominięto słowo kluczowe of i opis typu jego elementów, to przyjmuje się, że dany typ plikowy jest niezdefiniowany. Niezdefiniowane pliki są stosowane głównie w celu dostępu do fizycznych zbiorów dyskowych zgodnie z ich wewnętrznym formatem. W Pascalu istnieje predefiniowany plik tekstowy o nazwie Text (standardowy typ plikowy).
Przykłady:
TYPE Dane = file of Integer; Zbior = file; Wyniki = Text;
Typy wskaźnikowe. Zmienne dotychczas omówionych typów, tj. typów prostych i strukturalnych, charakteryzują się tym, że istnieją przez cały czas wykonywania tej części , w której są zadeklarowane. Są to tzw. zmienne statyczne. W języku Turbo Pascal występują też zmienne dynamiczne reprezentujące obiekty, dla których pamięć jest przydzielana i zwalniana na okreśolne żądanie. Zmienne te nie posiadają identyfikatorów, a odwołanie do nich następuje za pomocą wskaźnika. Wartościami wskaźników są elementy typu wskaźnikowego, które określają adresy pamięci zmiennych dynamicznych. Zastosowanie w programie zmiennych dynamicznych pociąga za sobą konieczność zdefiniowania odpowiednich typów wskaźnikowych. Definicja pojedynczego typu wskaźnikowego ma postać:
TYPE Identyfikator_typu = ^Identyfikator_typu_bazowego;
Poprzyjmy to przykładem:
TYPE wskaznik = ^zapis;
zapis = record
Tekst: String[80];
Liczba: Integer;
end;
Definicja ta wiąże typ wskaznik ze zbiorem wskazań danych typu zapis. Jeśli wprowadzimy teraz deklarację:
VAR adres : wskaznik;
to zmiennej wskażnikowej adres będą mogły być w programie przypisywane adresy
pamięci danych typu zapis.
W Pascalu występują dwa predefiniowane typy
wskaźnikowe są to typy Pointer (zmienne tego typu są zgodne z dowolnym
innym typem wskaźnikowym) i PChar (reprezentuje wskaźnik do łańcuchów
zakończonych znakiem pustym).
Jednym ze słów kluczowych jest słowo
nil, które oznacza stałą typu wskaźnikowego nie określającą żadnego
adresu (nil wskazuje na adres pusty).
Procedury i funkcje mogą być traktowane nie tylko jako części programu wykonywane na skutek wywołania, ale także jako elementy, które mogą być przypisywane do zmiennych i przekazywane do innych funkcji lub procedur jako parametry. Zmienne tego rodzaju powinny być typu proceduralnego. Definicja pojedynczego typu proceduralnego może mieć jedną z następujących postaci:
TYPE Nazwa = procedure;
lub
TYPE Nazwa = procedure(lista_parametrów);
lub
TYPE Nazwa = function: typ_wartości_funkcji;
lub
TYPE Nazwa = function(lista_parametrów): typ_wartości_funkcji;
Przykłady:
TYPE Procedura = procedure; Proc = procedure(x,y: Byte); Funkcja = function(x,y: Byte): Boolean;
Typ obiektowy. Obiektem w Pascalu nazywa się złożoną strukturę danych o ustalonej liczbie elementów składowych, z których każdy może być polem lub metodą (m.in. procedurą lub funkcją), tj. elementem opisującym operację wykonywaną na danym obiekcie. W definicji typu obiektowego, podobnie jak w definicji typu rekordowego, dla każdego pola specyfikuje się jego typ i identyfikator. Opis metody składa się z nagłówka procedury, funkcji, konstruktora lub destruktora, przy czym definicja pojedynczego typu obiektowego może zawierać opisy wielu metod. Opis typu obiektowego rozpoczyna się od słowa kluczowego object, a kończy słowem kluczowym end. Definicja pojedynczego typu obiektowego ma postać:
TYPE Identyfikator_typu = object dziedzictwo Lista_deklaracji_pól Lista_deklaracji_metod end;
lub
TYPE Identyfikator_typu = object dziedzictwo Lista_deklaracji_pól Lista_deklaracji_metod Sekcje_list end;
przy czym elementy wyszczególnione pomiędzy słowami object i end są opcjonalne, a każda z sekcji list może mieć jedną z poniższych postaci:
private Lista_deklaracji_pól Lista_deklaracji_metod
lub
public Lista_deklaracji_pól Lista_deklaracji_metod
przy czym w sekcjach tych oba elementy są także opcjonalne.
Dziedzictwo
oznacza ujęty w nawiasy okrągłe identyfikator innego, zdefiniowanego wcześniej,
typu obiektowego. Jeśli w definicji typu obiektowego wystąpi ten element, oznacza
to, że dany typ obiektowy zawiera (dziedziczy) wszystkie elementy podane w definicji
typu obiektowego o wyspecyfikowanej nazwie.
Każda z deklaracji pól ma postać:
Lista_nazw_pól : opis_typu;
a każda deklaracja metody jest następująca:
nagłowek_metody;
lub
nagłowek_metody; virtual;
gdzie nagłowek metody oznacza nagłowek funkcji, procedurey, konstruktora
lub destruktora. Słowo kluczowe virtual określa daną metodę jako wirtualną (?).
Definicję poszczególnych metod podaje się poza definicją typu obiektowego. Każda
definicja metody zawiera w nagłówku nazwę funkcji, procedury, konstruktora lub
destruktora, poprzedzoną kropką i nazwą odnośnego typu obiektowego.
Jeśli definicja typu obiektowego zawiera dyrektywę private, oznacza to,
że zakres ważności pól i (lub) metod podanych po tej dyrektywie jest ograniczony
do modułu (lub programu), który zawiera definicję danego typu obiektowego.
Tego typu pola i metody nazywami polami i metodami prywatnymi. Użycie po sekcji
z dyrektywą private dyrektywy public powoduje anulowanie
ograniczenia zakresu ważności dla dalszych pól i (lub) metod.
Przykłady:
TYPE punkt = object X, Y:Integer; end; TYPE piksel = object (punkt) Kolor:Byte; end;
Typ obiektowy piksel zawiera elementy typu obiektowego punkt.
TYPE odcinek = object X, Y:Byte; procedure zaznacz(dx, dy: Byte); end;
Dla powyższego typu konieczne jest podanie w dalszej części programu definicji procedury zaznacz:
procedure odcinek.zaznacz(dx, dy: Byte); begin ... Jakieś_instrukcje end;
Spis treści, następny wątek : Instrukcje