Turbo Pascal - Typy danych
W języku Turbo Pascal każda stała, zmienna, funkcja itp. musi być ściśle określonego typu. Na podstawie tego typu kompilator rezerwuje odpowiednią ilość pamięci na dany element. Typ ten charakteryzuje zbiór wartości przyjmowanych przez niego. W Pascal'u istnieje bardzo wiele różnych typów. Programista ma możliwość również tworzenia własnych. Możemy wyróżnić cztery standardowe typy:
Dodatkowo typy definiowane przez użytkownika można podzielić na:
Typ całkowity
Wszystkie elementy tego typu stanowią zbiór liczb całkowitych. Różnią się tylko przedziałem, a co za tym idzie ilością pamięci potrzebnej na zapisanie danej liczby. Istnieją następujące typy całkowite:
TYP ZAKRES ROZMIAR
Shortint -128..127 1
Byte 0..255 1
Integer -32768..32767 2
Word 0..65635 2
Longint -2147483648..2147483647 4
Typ rzeczywisty
Dane tego typu stanowią zbiór liczb rzeczywistych. Poszczególne podtypy różnią się między sobą zakresem oraz ilością zajmowanej przez nie pamięci. Mamy więc następujące podtypy:
TYP ZAKRES LICZBA CYFR ZNACZĄCYCH ROZMIAR
Single 1.5e-45..1.7e38 7-8 4
Real 2.9e-39..1.7e38 11-12 6
Comp -2.63+1..2e63-1 19-20 8
Double 5.0e-324..1.7e308 15-16 8
Extended 3.4e-4932..1.1e4932 19-20 10
Jeśli przy deklaracji elementu typu Comp lub Extended pokaże się komunikat: "Must be in 8087 mode to compile this.", to znaczy, że musisz w menu OPTIONS/COMPILER w dziale Numeric processing wybrać opcję 8087/80287 :-).
Typ łańcuchowy
Dane typu łańcuchowego składają się z ciągu znaków. Ciąg ten poprzedzony jest jednym bajtem, w którym zapisana jest jego długość. Z tego też względu maksymalna długość ciągu wynosi 255 znaków. (Jeśli potrzebujesz zmiennej typu łańcuchowego dłuższej niż 255 znaków, to zajrzyj do strony Dyrektywy). Typ łańcuchowy deklarujemy za pomocą słowa kluczowego STRING. Zadeklarowany element domyślnie przyjmuje długość 255 bajtów. Zalecane jest, aby określać jego długość samemu. W tym celu po słowie STRING w nawiasach kwadratowych wpisujemy liczbę określającą długość naszego elementu, a co za tym idzie ilość pamięci potrzebnej na jego zapamiętanie. Zmienne i stałe tego typu mogą być traktowane przez użytkownika jako tablica, np. aby zmienić trzecią literę zmiennej na K napiszemy:
Nazwa_zmiennej[3]:='K';
Jeśli chcemy dowiedzieć się o długości naszej zmiennej posłużymy się funkcją Length bądź odczytamy zerowy bajt naszej zmiennej za pomocą polecenia Ord np.:
długość_łańcucha:=Ord(Nazwa_zmiennej[0]);
Gdybyśmy chcieli zmienić wszystkie litery z małych na wielkie moglibyśmy posłużyć się funkcją Upcase. Jednak pozwala ona zmieniać tylko jedną literę. Przykładowy ciąg instrukcji zmienia wielkość liter w zmiennej NAPIS na wielkie:
VAR NAPIS : STRING[10];
{deklarowanie zmiennej NAPIS typu string o długości 10 znaków}
BEGIN
FOR I:=1 TO LENGTH(NAPIS) DO
NAPIS[I]:=UPCASE(NAPIS[I]);
END;
Typ wyliczeniowy
Typ wyliczeniowy definiuje zbiór identyfikatorów oznaczających poszczególne wartości przez ich wyliczenie. Pierwszy identyfikator ma wartość 0, dla kolejnego 1 itd. Przykład:
TYPE Tydzien=(Niedziela, Poniedzialek, Wtorek, Sroda, Czwartek, Piatek, Sobota);
Typ znakowy
Typ znakowy określa zbiór znaków. Do zmiennej tego typu można więc zapamiętać kod ASCI jednego znaku.
TYPE Znak=CHAR;
Typ logiczny
Typ logiczny jest typem wyliczeniowym, który może przyjąć tylko dwie wartości: FALSE, wtedy wartość porządkowa wynosi 0 (fałsz) i TRUE wartość porządkowa jest większa niż 0 (prawda). Istnieją cztery podtypy:
TYP ROZMIAR W BAJTACH
Boolean 1
ByteBool 1
WordBool 2
LongBool 4
Typ proceduralny
Język Turbo Pascal traktuje procedury i funkcje jako elementy języka, które można przywiązywać do zmiennych i przesyłać jako parametry. Przykładowa deklaracja typu proceduralnego może wyglądać tak:
TYPE
A=Procedure;
B=Procedure(a:Byte);
C=Function(A:Byte):CHAR;
Zmienne typu proceduralnego nie mogą być zwracane przez funkcję.
Typ okrojony
Typ okrojony określa podzbiór dowolnego typu porządkowego lub wyliczeniowego. Jest on ograniczony pewnym zakresem. Wykorzystywany jest do określania typu zmiennych, które mogą przyjąć wartości ze ściśle określonego przedziału, np.
TYPE Rok=1990..1999;
VAR a : Rok;
Teraz zmienna "a" może przyjąć wartości od 1990 do 1999.
Typ wskaźnikowy
Typ wskaźnikowy pozwala na określenie zmiennych, za pomocą których będziemy mogli odwoływać się od pewnych obszarów pamięci operacyjnej. Istnieją następujące deklaracje typu wskaźnikowego.
TYPE
Wsk_1 = ^Typ_podstawowy;
Wsk_2 = Pointer;
Wsk_3 = PChar;
Więcej informacji znajdziesz w dziale Programowanie dynamiczne
Typ tablicowy
Typ ten określa tablicę składającą się ze stałej liczby elementów. Wszystkie elementy tablicy muszą być również określonego typu. Do każdego elementu odwołujemy się poprzez indeks podawany w nawiasach kwadratowych i określający pozycję danego elementu. Każda tablica może być wielowymiarowa. Przykładowa deklaracja tablicy 100 znaków może wyglądać następująco:
Nazwa_tablicy : ARRAY[1..100] of Char;
Słowo kluczowe ARRAY, służy właśnie do definiowania tablic. Na końcu tej definicji, typ Char oznacza, że każdy element tej tablicy jest typu Char, czyli jest to znak. By zmienić trzeci element tablicy możemy napisać tak:
Nazwa_tablicy[3]:='K';
Każdą tablicę można przedstawić w postaci tabeli. By stworzy tablicę, w której zapamiętalibyśmy tabliczkę mnożenia do 10, moglibyśmy napisać:
Mnozenie : Array[1..10,1..10] of Word;
Powyższa deklaracja tworzy tablicę, którą graficznie można przedstawić jako tabelę o 10 wierszach i 10 kolumnach.
Typ rekordowy
Opisuje złożoną strukturę danych. Taka struktura składa się z kilku pól. Każde z nich jest ściśle określonego typu. Definicję rekordu zamieszcza się między słowami kluczowymi RECORD i END;.
Przykładowo by zapamiętać dane o pracownikach w jakiejś firmie, używając samej definicji tablicy byłoby to bardzo trudne, lub nawet niemożliwe. Używając tablicy typu X, gdzie X jest typem rekordowym, wykonanie powyższego zadania jest bardzo proste:
TYPE
Osoba = RECORD
Imie : String[10];
Nazwisko : String [20];
Wiek : Byte;
END;
VAR Ludzie : Array[1..1000] of Osoba;
Do odczytania informacji zapisanych w danym polu rekordu używa się kropki ("."). np.:
Writeln(Ludzie[10].imie);
Ludzie[11].nazwisko:='Nowak';
Jeśli chcemy np. podać wszystkie dane osoby nr. 2 można napisać:
WIDTH Ludzie[2] DO
BEGIN
Imie:='Jan';
Nazwisko:='Nowak';
Wiek:=20;
END;
Można również deklarować rekordy z wariantami o zmiennej strukturze. Rekord taki zawiera specjalne pole, którego wartość decyduje o wyborze wariantu układu pól w zmiennej części rekordu. Pole to nazywa się wyróżnikowym. Rekord wariantowy zajmuje obszar pamięci potrzebny do zapamiętania rekordu o najdłuższej części wariantowej. Jednak odmiennie interpretuje dane różnych wariantów. Przykładowy rekord z wariantem:
TYPE Osoba = RECORD
Imie : String[10];
Nazwisko : String[20];
Case Stan_cywilny OF
samotny : ();
zonaty : (Data_slubu : String[10]);
rozwiedziony : (Data_slubu : String[10];
Data_rozw : String[10]);
Pole wariantowe musi być ostatnim polem rekordu.
Typ obiektowy
Typ obiektowy opisuje złożoną strukturę danych. Składa się ona z pól, podobnie jak struktura rekordu, oraz tzw. metod, czyli operacji wykonywanych na obiekcie. Definicja obiektu rozpoczyna się słowem OBJECT, i kończy END;. Ma następującą budowę:
OBJECT (dziedziczność)
Pole : Typ;
Pole : Typ;
..
..
Metoda;
Metoda;
END;
Typ zbiorowy
Typ ten określa zbiór potęgowy, którego elementy są typu porządkowego. Przez zbiór potęgowy należy rozumieć zbiór wszystkich możliwych podzbiorów wartości typu porządkowego, włączając w to zbiór pusty. Definicja tego typu jest następująca:
Typ_zbiorowy = SET OF Typ;
np.:
TYPE
Litery = SET OF 'a'..'z';
Cyfry=SET OF '0'..'9';
Teraz zmienne typu Cyfry mogą przyjmować tylko wartości od '0' do '9'.
Na zbiorach można wykonywać następujące operacje:
+ - dodawanie
- - odejmowanie
* - mnożenie (iloczyn zbiorów)
IN - sprawdzanie przynależności
= - sprawdzanie równości
<=,>= - sprawdzanie relacji inkluzji zbiorów
Typ plikowy
Typ ten określa zbiór danych sekwencyjnych o zmiennej liczbie elementów tego samego typu. Elementy składowe nie mogą być typu plikowego oraz typu, który zawiera w sobie deklaracje typu plikowego.
Ogólna postać definicji typu plikowego jest następująca:
Plik_1 : FILE OF Typ_podstawowy;
Plik_2 : FILE;
Plik_3 : Text;
np.:
VAR Plik : FILE OF Byte;