Object Pascal/Typy zmiennych

Z Wikibooks, biblioteki wolnych podręczników.

Typy zmiennych określają zewnętrzną postać zmiennej, czyli zakres jej wartości i zestaw dozwolonych operacji, które może na niej wykonać programista, a także jej reprezentację wewnętrzną, czyli sposób traktowania je przez inne obiekty programu.

Spis treści

[edytuj] Typ prosty

[edytuj] Porządkowy

[edytuj] Całkowity

Typ predefiniowany.

[edytuj] Typy ogólne
Nazwa typu Zakres Format
Integer typ zależny od typu programowania, najczęściej od -32768 do 32767 znak, 16 lub 32 lub 64 bitowy (w zależności od platformy na którą programujemy)
Cardinal typ zależny od typu programowania, najczęściej 0..65535 bez znaku, 16 lub 32 lub 64 bitowy (w zależności od platformy na którą programujemy)
[edytuj] Typy podstawowe
Nazwa typu Zakres Format
Shortint –128..127 znak, 8-bitowy
Smallint –32768..32767 znak, 16-bitowy
Longint –2147483648..2147483647 znak, 32-bitowy
Int64 –2^63..2^63–1 znak, 64-bitowy
Byte 0..255 bez znaku, 8-bitowy
Word 0..65535 bez znaku, 16-bitowy
Longword 0..4294967295 bez znaku, 32-bitowy
[edytuj] Dodatkowe informacje

Predefiniowane w module System stałe MaxLongint i MaxInt określają maksymalną wartość w typach LongInt i Integer.

[edytuj] Logiczny

Typ predefiniowany.

Nazwa typu Format
Boolean 8 - bitowy
ByteBool 8 - bitowy
WordBool 16 - bitowy
LongBool 32 - bitowy

Wartością zmiennej typu logicznego może być predefiniowana stała FALSE lub TRUE.

[edytuj] Znakowy

Typ predefiniowany.

[edytuj] Typy podstawowe
Nazwa typu Format Uwagi
AnsiChar 8 - bitowy rozszerzony zestaw znaków ASCII (standard 7 bitów)
WideChar 16 - bitowy zestaw znaków Unicode
[edytuj] Typ ogólny
Nazwa typu Format Uwagi
Char 8 - bitowy zgodny z typem AnsiChar w Object Pascal

[edytuj] Wyliczeniowy

Typ niepredefiniowany, wymaga opisu programisty.

[edytuj] Definicja typu
 type  identyfikator-typu = (lista identyfikatorów)  
[edytuj] Przykład
 type samochody = (fiat, polonez, opel, volkswagen);
 Ord(fiat) = 0
 Ord(polonez) = 1 itd.
 var
 x,y:samochody;
 begin
   x:=polonez;		//x – 00000001 (liczba 1)
   y:=opel;		//y  – 00000010 (liczba 2)
 end;
[edytuj] Uwagi dotyczące stosowania typów wyliczeniowych
  • Element tego typu zajmuje 8 lub 16 bitów.
  • Identyfikatory na liście muszą być różne, błędna jest na przykład deklaracja
 type znaki = (a,b,b,c)
  • W dwóch różnych typach o tym samym zasięgu nie może wystąpić ten sam identyfikator, np. w zasięgu deklaracji typu samochody błędna jest deklaracja
 type ciezarowki = (opel, volkswagen, scania)
  • Porządek w typie wyliczeniowym jest zgodny z kolejnością wyliczenia w definicji typu.
  • Wartości zmiennych tego typu nie można wypisać standardową procedurą write.
  • Nie można na nich wykonywać operacji arytmetycznych.
  • Maksymalna ilość elementów to 256.

[edytuj] Okrojony

Typ niepredefiniowany, wymaga opisu programisty. Służy do definiowania podzbiorów dowolnego zbioru wartości określonego przez typy porządkowe.

[edytuj] Definicja
 type identyfikator-typu = stala1 .. stala2;

Z każdym typem okrojonym związany jest bazowy, macierzysty typ porządkowy i obie stałe muszą być tego typu, przy czym ord(stala1) <= ord(stala2). Pierwsze wyrażenie stałe nie może zaczynać się od ‘(‘.

[edytuj] Przykład
 const 	
   a = 5;
   b = 2;
 type
   sam = fiat .. opel;  	      //typ bazowy samochody
   znaki = '!' .. '+';		      // typ bazowy Char
   zakres1 = 2+5 .. 2*5;		// typ bazowy Byte
   zakres2 = b+a .. b*a;		// typ bazowy Integer

[edytuj] Rzeczywisty

Typ predefiniowany.

[edytuj] Typy podstawowe

Nazwa typu Zakres Znaczące cyfry Format
Real48 2.9 x 10^–39 .. 1.7 x 10^38 11–12 48-bitowy
Single 1.5 x 10^–45 .. 3.4 x 10^38 7–8 32-bitowy
Double 1.5 x 10^–309 .. 1.7 x 10^309 15–16 64-bitowy
Extended 3.6 x 10^–4951 .. 1.1 x 10^4932 19–20 80-bitowy
Comp –2^63 .. 2^63 –1 19–20 64-bitowy
Currency –922337203685477.5808 .. 922337203685477.5807 19–20 64-bitowy

[edytuj] Typ ogólny

Nazwa typu Zakres Znaczące cyfry Format
Real 5.0 x 10^–324 .. 1.7 x 10^308 15–16 64-bitowy

[edytuj] Dodatkowe informacje

  • Typ Extended zapewnia najlepszą precyzję, nie jest jednak zalecany, gdy aplikacja ma być uruchamiana na różnych platformach.
  • Typ Comp służy do pamiętania dużych liczb całkowitych, nie jest jednak typem porządkowym (nie można go np. inkrementować), zachowany dla zgodności z wersjami wcześniejszymi, zaleca się używać typu Int64.
  • Typ Currency ma zastosowanie do obliczeń pieniężnych.

[edytuj] Typ łańcuchowy

Typ łańcuchowy służy do reprezentowania ciągów znaków.

[edytuj] Łańcuchowy krótki

  • string - w zasięgu takiej dyrektywy {$H-},
  • string[zakres] - zakres mniejszy lub równy od 255,
  • shortstring

[edytuj] Łańcuchowy długi

  • string - w zasięgu dyrektywy {$H+} (ustawienie standardowe)
  • ansistring;

[edytuj] Łańcuch znaków dwubajtowych

  • widestring

[edytuj] Typ strukturalny

[edytuj] Tablicowy

Typ przeznaczony do struktur składających się z wielu elementów konkretnego typu.

[edytuj] Tablice statyczne

Deklaracja typu tablicowego:

 type identyfikator_typu = array [typy_indeksowe] of  typ_bazowy;

gdzie:

  • typy_indeksowe – oddzielone przecinkami opisy typów porządkowych;
  • typ_bazowy – dowolny typ prosty lub strukturalny.

Przykłady:

 type
   Kolor = (bialy, zielony, czarny);
   Ttab1 = array [5..8] of array [Boolean] of array [Kolor] of real;
   Ttab2 = array [5..8, Boolean] of array [Kolor] of real;
   Ttab3 = array [5..8] of array [Boolean, Kolor] of real;

Deklaracja zmiennej w typie tablicowym:

 var
   liczba: array [1..100] of integer;

W nawiasach kwadratowych zapisywany jest zakres indeksów tablicy w postaci: od..do. Indeks tablicy musi należeć do typu porządkowego, ograniczenia (od i do) nie mogą być zmiennymi. Ograniczeniom nie podlega zakres indeksów (jedyny warunek to indeks od musi być mniejszy od indeksu do. Typ_bazowy może być typem prostym, ale także typu strukturalnego.

Istnieją również tablice wielowymiarowe, np. dwuwymiarowa:

 var
   liczba: array[1..10] of array[1..10] of integer;

albo dla skrócenia zapisu:

 var
   liczba: array[1..10,1..10] of integer;

Nie ma ograniczeń na liczbę wymiarów tablicy, najczęściej stosuje się tablice jedno- i dwuwymiarowe.

[edytuj] Tablice dynamiczne

Deklaracja:

 type 
   identyfikator_typu = array of typ_bazowy;   		//tablica jednowymiarowa
 type 
   identyfikator_typu = array of array of typ_bazowy 	//tablica 2-wymiarowa

Informacje:

  • Zmienne tego typu zajmują 32 bity pamięci.
  • Pamięć na tablicę alokowana jest w wyniku wykonania procedury SetLength (zmienna, indeksy) lub w wyniku przypisania.
  • Pamięć jest zwalniana w wyniku przypisania zmienna := nil; lub w wyniku wykonania procedury Finalize (zmienna).

[edytuj] Rekordowy

Typem rekordowym nazywamy złożoną strukturę danych, której elementy (pola), mogą być różnych typów (prostych i strukturalnych).

[edytuj] Deklaracja typu rekordowego

 type identyfikator_typu = record
   {lista_deklaracji_pól};
 end;

gdzie lista_deklaracji_pól ma postać:

 lista_identyfikatorów_pól : opis-typu;

[edytuj] Ważne informacje

  • Ostatnie pole może być polem wariantowym postaci:
 case pole_wyróżnikowe of wykaz_wariantów;
    • 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)
  • Pola muszą mieć różne identyfikatory.
  • Żadne pole wariantowe nie może być:
    • typu łańcuchowego długiego,
    • typu tablicy dynamicznej,
    • typu wariantowego,
    • typu łącza programowego.

[edytuj] Przykład:

 type
   Data = record
     Dzien: 1..31;			
     Miesiac: 1..12;
     Rok: integer;
 end;

[edytuj] Zbiorowy

Typ zbiorowy jest zbiorem potęgowym typu porządkowego o maksymalnie 256 elementach.

[edytuj] Deklaracja typu

 type identyfikator_typu = set of typ_porządkowy;

Wartościami zmiennych typu zbiorowego są dowolne podzbiory zbioru bazowego, łącznie ze zbiorem pustym. Konstruktor zbioru ma postać [ ].

[edytuj] Przykłady:

 type Samochody = (fiat, polonez, opel, volkswagen);
 var 
   A : set of samochody;		
   B : set of 0..3;					
   C : set of 'a'..'z';
 begin		
   A:= [ ];
   A:= [opel];
   B:= [1,3];
   C:= ['a'..'f'];
 end.

Na zmiennych zbiorowych można wykonywać:

  • operacje mnogościowe,
  • operacje porównań,
  • operację należenia do zbioru in,
  • procedury:
  include(zb, el)  zb:=zb+[el]
  exclude(zb, el)  zb:=zb-[el]

[edytuj] Plikowy

[edytuj] Klasowy

Typ klasowy jest zbliżony do typu rekordowego, posiada jednak dodatkowo metody (procedury i funkcje). Słowo class, występujące tylko w ObjectPascalu, oznacza jakby wskaźniki, które posiadają konstruktorów (słowo kluczowe constructor) i destruktorów (destructor), deklarowanych poza tym jak inne metody (Domyślny konstruktor to Create a destruktory to Free i bardziej techniczne Destroy).

[edytuj] Przykład Object

 type
   Data = object(TObject)
     Dzien: 1..31;			
     Miesiac: 1..12;
     Rok: integer;
     procedure Drukuj;
 end;
 
 procedure Data.Drukuj;
 begin
   writeln(Dzien,'.',Miesiac,'.',Rok)
 end;

[edytuj] Przykład Class

Deklaracja oraz użycie konstruktora i destruktora

 type
   Data = class(TObject)
     Dzien: 1..31;			
     Miesiac: 1..12;
     Rok: integer;
     procedure Drukuj;
 end;
 
 procedure Data.Drukuj;
 begin
   writeln(Dzien,'.',Miesiac,'.',Rok)
 end;
 
 var
   Data1: Data;
 
 begin
   Data1 := Data.Create;
   {...}
   Data1.Free;
 end.

[edytuj] Odwołania do klasy

[edytuj] Łącza programowego

[edytuj] Typ wskaźnikowy

Wskaźnik zawiera adres zmiennej. Deklaracja zmiennych typu wskaźnikowego zawiera operator ^ przed nazwą typu, na który ma wskazywać. Kiedy chcemy uzyskać adres zmiennej, poprzedzamy ją operatorem @. Kiedy chcemy się odwołać do elementu wskazywanego przez wskaźnik, piszemy po nazwie wskaźnika ^. Można też tworzyć nowe zmienne dynamiczne, np. procedurą new(wskaźnik) i usuwać je, np. procedurą dispose(wskaźnik).

[edytuj] Przykłady:

 program wsk;
 
 var
   wsk1, wsk2: ^integer;
   i: integer;
 
 begin
   i := 1;
   wsk1 := @i;
   if @wsk1^ = wsk1 then
     writeln('tak');   {drukuje tak}
   writeln(wsk1^);   {drukuje 1}
   wsk1^ := 2;
   wsk1 := nil;
   if wsk1 = nil then
     writeln('tak');   {drukuje tak}
   writeln(i);  {drukuje 2}
   new(wsk2);
   wsk2^ := 3;
   writeln(wsk2^);   {drukuje 3}
   dispose(wsk2);
   new(wsk1);
   wsk2 := wsk1;
   wsk1^ := 4;
   writeln(wsk1^);   {drukuje 4}
   readln;
   dispose(wsk1);
   {dispose(wsk2); - to byłby błąd}
   if wsk2 = nil then
     writeln('tak');   {nic nie drukuje}
   readln;
 end.

[edytuj] Typ proceduralny

[edytuj] Typ wariantowy

[edytuj] Zgodność typów

[edytuj] Identyczność typów

Dwa typy a i b są identyczne, jeżeli:

  • posiadają ten sam identyfikator typu
  • dają się wywieźć od tego samego identyfikatora za pomocą konstrukcji: a=b.

[edytuj] Zgodność operacyjna

Dwa typy są zgodne operacyjne, jeśli są m.in.:

  • identyczne,
  • typami całkowitymi,
  • typami rzeczywistymi,
  • jeden jest typem okrojonym drugiego,
  • są typami okrojonymi tego samego typu bazowego,
  • typami zbiorowymi o zgodnych typach bazowych
  • jeden jest typem Pointer, a drugi dowolnym typem wskaźnikowym,
  • są typami proceduralnymi o identycznych typach wyników, jednakowej liczbie parametrów i identycznych typach odpowiadających sobie parametrów.

[edytuj] Zgodność w sensie przypisania

Instrukcja przypisania z := w jest poprawna, o ile typ a zmiennej z i typ b wyrażenia w spełniają jeden z warunków:

  • są typami rzeczywistymi,
  • są typami łańcuchowymi,
  • a i b są identyczne, ale nie są typami plikowymi, ani nie zawierają odwołań do typu plikowego,
  • a i b są zgodnymi typami porządkowymi i wartość w jest jedną z możliwych wartości typu a,
  • a jest typem rzeczywistym, a b typem całkowitym,
  • a jest typem łańcuchowym, a b jest typem znakowym,
  • są zgodnymi operacyjnie typami zbiorowymi,
  • są zgodnymi operacyjnie typami wskaźnikowymi,
  • są zgodnymi operacyjnie typami proceduralnymi.

[edytuj] Inne podziały typów

[edytuj] Predefiniowalność

  • standardowe – są one predefiniowane i nie wymagają opisu programisty.
  • niestandardowe – nie są predefiniowane i muszą być opisane przez programistę.

[edytuj] Uzależnienie od procesora i systemu operacyjnego

  • podstawowe – są niezależne od procesora i systemu operacyjnego.
  • ogólne – zależą od procesora i systemu operacyjnego.