Turbo Pascal Web Page

programowanie w języku Turbo Pascal ( kurs typy danych w pascalu )

Turbo Pascal | Forum Turbo Pascal | Kurs Turbo Pascal | Programy w Turbo Pascalu (Kody źródłowe)

Masz pytanie ? Zadaj je na naszym Forum Turbo Pascal. Rejestracja w 5 sekund ;-)

Google
 

Kurs Turbo Pascala dla początkujących

#4 Typy danych i ich krótki opis

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