Pobierz slajdy prezentacji multimedialnej (format PDF).

Transkrypt

Pobierz slajdy prezentacji multimedialnej (format PDF).
PODSTAWY
PROGRAMOWANIA
Andrzej Marciniak
Prezentacja multimedialna przygotowana za pomocą systemu Corel® Presentations X3
Copyright © 2003-2016 by Andrzej Marciniak
PP-4(1 z 88)
Na poprzednim wykładzie ...
‚ przegląd konstrukcji języka Delphi Pascal
(program, moduł, biblioteka, funkcje
i procedury, klasy i obiekty, typy danych,
zmienne, instrukcje)
‚ struktura programu i modułu
‚ podstawowe elementy języka (symbole
podstawowe, słowa kluczowe i dyrektywy
języka, identyfikatory, liczby, łańcuchy,
literały logiczne, komentarze i separatory)
PP-4(2 z 88)
Na tym wykładzie ...
‚ typy danych i ich opis
‚definiowanie typów
‚typy proste (porządkowe, rzeczywiste)
‚typy łańcuchowe
‚typy strukturalne (tablicowe, rekordowe,
zbiorowe, plikowe)
PP-4(3 z 88)
Definiowanie typów
Każda zmienna występująca w programie (module,
bibliotece łączonej dynamicznie) posiada swoją nazwę
(identyfikator) i przyjmuje wartości z określonego zbioru.
Zbiór ten nazywa się typem zmiennej.
Typ zmiennej może być określony w deklaracji zmiennej
(będzie dalej) lub w definicji typu. Jeśli zdefiniowano typ,
to w deklaracji zmiennej można do niego odwołać się za
pomocą identyfikatora typu.
Stosowanie w programie (module, bibliotece łączonej
dynamicznie) identyfikatorów typów (zamiast ich opisów) zwiększa
czytelność programu oraz ułatwia jego strukturalizację.
PP-4(4 z 88)
Definiowanie typów
W języku Delphi występują dwie kategorie typów:
‚ typy podstawowe,
‚ typy ogólne.
Postacie i zakresy wartości typów podstawowych są
niezależne od procesora i systemu operacyjnego, co
oznacza, że nie zmieniają się one przy różnych
implementacjach języka. Typy ogólne zależą od
procesora i systemu operacyjnego. W obecniej wersji
języka Delphi występują cztery rodzaje typów
predefiniowanych, w których rozróżnia się typy
podstawowe i ogólne. Są to niektóre typy całkowite
i rzeczywiste oraz typy znakowe i łańcuchowe.
PP-4(5 z 88)
Definiowanie typów
Typy dzielą się na:
‚ standardowe,
‚ niestandardowe.
Typy standardowe są predefiniowane i nie wymagają
żadnego opisu.
Wszystkie typy wprowadzone przez programistę muszą
zostać przez niego opisane. Opis taki może być używany
bez uprzedniego nadania temu opisowi nazwy (np.
w deklaracjach zmiennych) albo też może być podany
w definicji typu. Definicja opisuje typ i jednocześnie
przyporządkowuje mu identyfikator.
PP-4(6 z 88)
Definiowanie typów
Składnia definicji typów jest następująca:
type sekwencja-definicji-typów
przy czym każdy element sekwencji definicji typów ma
postać
identyfikator-typu = oznaczenie-typu;
gdzie oznaczenie typu jest opisem typu lub
identyfikatorem typu (identyfikatorem typu w opisie typu
może być identyfikator typu standardowego lub typu
zdefiniowanego wcześniej).
PP-4(7 z 88)
Definiowanie typów
Wystąpienie konstrukcji postaci
type identyfikator-typu-1 = identyfikator-typu-2;
powoduje, że typ określony za pomocą pierwszego
identyfikatora będzie uważany za identyczny z typem
podanym przez drugi identyfikator.
Podczas wykonywania programu konsekwencją tego
faktu będzie niemożliwość rozróżnienia typów zmiennych
zadeklarowanych następująco:
var zmienna-1 : identyfikator-typu-1;
zmienna-2 : identyfikator-typu-2;
PP-4(8 z 88)
Definiowanie typów
W celu rozróżnienia typów definiowanych przez inne
typy, należy posługiwać się konstrukcją
type identyfikator-typu-1 = type identyfikator-typu-2;
która wymusza na kompilatorze utworzenie nowego,
innego logicznie typu o nazwie określonej przez pierwszy
identyfikator.
Oczywiście zbiory wartości obu typów są takie same,
a typ określony drugim identyfikatorem powinien być
zdefiniowany wcześniej lub oznaczać identyfikator typu
standardowego.
PP-4(9 z 88)
Definiowanie typów
Do każdej definicji typu mogą być dołączone następujące
dyrektwy języka (nazywa się je dyrektywami wskazówkowymi):
platform
- oznacza, że definiowany typ jest specyficzny dla
określonego systemu operacyjnego i może nie
być implementowany w innych systemach,
library
- oznacza ograniczenie typu do pewnej biblioteki,
deprecated - oznacza, że definiowany typ jest przestarzały lub
został zdefiniowany dla zgodności z wcześniejszymi wersjami języka.
Dyrektywy te powodują wyłącznie wygenerowanie podczas
kompilacji pewnych wskazówek lub ostrzeżeń.
Mogą być stosowane także w deklaracjach zmiennych,
deklaracjach i definicjach funkcji, procedur i metod, deklaracjach
pól w rekordach i klasach oraz w nagłówkach modułów.
PP-4(10 z 88)
Typy proste
Typy proste są podstawowymi typami języka Delphi i za
ich pomocą określa się bardziej złożone struktury
danych.
Typy proste dzielimy na:
# typy porządkowe,
# typy rzeczywiste.
Wszystkie typy proste składają się ze skończonego
i uporządkowanego zbioru wartości. Dzięki temu
możliwe jest m. in. wykonywanie na wartościach tych
typów operacji porównań.
PP-4(11 z 88)
Typy proste
Typy porządkowe
Do typów porządkowych zaliczamy typy:
‚
‚
‚
‚
‚
wyliczeniowe,
całkowite,
znakowe,
logiczne,
okrojone.
PP-4(12 z 88)
Typy proste
Typy porządkowe
Dla wartości każdego typu porządkowego są określone
wartości poprzednie i następne (z wyjątkiem wartości
krańcowych).
Z każdą wartością typu porządkowego jest skojarzona
liczba porządkowa (wartość całkowita) jednoznacznie
określająca jej umiejscowienie wśród wszystkich
wartości danego typu.
Z wyjątkiem typów całkowitych domyślnie pierwsza
wartość w każdym typie porządkowym ma liczbę
porządkową 0, następna – numer 1 itd.
PP-4(13 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Typy wyliczeniowe 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);
W liście identyfikatorów specyfikuje się identyfikatory (nazwy),
które tworzą zbiór wartości danego typu wyliczeniowego. Należy
przy tym pamiętać, że ten sam identyfikator nie może być użyty
do oznaczania wartości w dwu różnych typach wyliczeniowych,
których zakresy pokrywają się, oraz że w obrębie danego typu
identyfikatory elementów muszą być różne.
PP-4(14 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Przykłady
type tydzień = (poniedziałek, wtorek, środa,
czwartek, piątek, sobota,
niedziela);
Typ tydzień sklada się z siedmiu elementów
o wyspecyfikowanych identyfikatorach. Liczbą
porządkową identyfikatora poniedziałek jest 0,
a identyfikatora niedziela – liczba 6.
PP-4(15 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Przykłady
Opis typu wyliczeniowego może być podany bezpośrednio w deklaracji
zmiennej, na przykład
var tydzień_1 : (poniedziałek, wtorek, środa, czwartek, piątek,
sobota, niedziela);
Jeśli jednak użyto powyższej deklaracji, to w zakresie ważności identyfikatora
tydzień_1 nie jest możliwe zadeklarowanie innej zmiennej o takich samych
elementach typu wyliczeniowego. W zakresie ważności identyfikatora
tydzień_1 ewentualna deklaracja
var tydzień_2 : (poniedziałek, wtorek, środa, czwartek, piątek,
sobota, niedziela);
jest błędna (błąd kompilacji).
PP-4(16 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Przykłady
W celu poprawnego zadeklarowania zmiennych tydzień_1 i tydzień_2 należy
użyć konstrukcji
var tydzień_1, tydzień_2 : (poniedziałek, wtorek, środa, czwartek,
piątek, sobota, niedziela);
PP-4(17 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Domyślnie liczby porządkowe kolejnych elementów
w typach porządkowych rozpoczynają się od 0. Można to
zmienić dodając po specyfikacji elementu znak równości
i odpowiednią wartość.
Przyjmuje się przy tym, że element, dla którego nie
podano liczby porządkowej ma liczbę porządkową
o jeden większą niż element poprzedni.
PP-4(18 z 88)
Typy proste
Typy porządkowe S typy wyliczeniowe
Przykład
Z następującej definicji:
type rozmiar = (mały = 2, średni = 4, duży = mały +średni);
wynika, że liczbą porządkową elementu mały jest 2, elementu średni S 4,
a elementu duży S 6. Definicja ta mogłaby sugerować, że typ rozmair ma trzy
elementy.
Elementów jest jednak pięć o liczbach porządkowych 2, 3, 4, 5 i 6, chociaż
tylko trzy z nich mają swoje nazwy. Pozostałe dwa elementy (o liczbach
porządkowych 3 i 5) mają „anonimowe” wartości.
Wartości te mogą być przypisane zmiennym typu rozmiar. Jeśli taką zmienną
jest np. mój_rozmiar, to poprawna będzie instrukcja
mój_rozmiar := rozmiar(3);
PP-4(19 z 88)
Typy proste
Typy porządkowe S typy całkowite
Typy całkowite są predefiniowane (nie wymagają
opisu).
Wszystkie typy całkowite są podzbiorami zbioru
liczb całkowitych.
Liczba porządkowa elementu dowolnego typu
całkowitego jest równa wartości tego elementu.
Wśród typów całkowitych wyróżniamy typy
podstawowe i ogólne.
PP-4(20 z 88)
Typy proste
Typy porządkowe S typy całkowite
Do podstawowych typów całkowitych zalicza się:
‚ typ ShortInt (Int8), zawierający liczby całkowite z
przedziału [!128, 127],
‚ typ SmallInt (Int16) - przedział [!32 768, 32 767],
‚ typ LongInt (Int32) - [!2 147 483 648, 2 147 483 647],
‚ typ Int64 - przedział [!263, 263 ! 1],
‚ typ Byte (UInt8) - przedział [0, 255],
‚ typ Word (UInt16) - przedział [0, 65 535],
‚ typ LongWord (UInt32) - przedział [0, 4 294 967 295],
‚ typ UInt64 - przedział [0, 264!1].
PP-4(21 z 88)
Typy proste
Typy porządkowe S typy całkowite
Ogólnymi typami całkowitymi, a więc typami zależnymi od rodzaju
procesora i systemu operacyjnego, są:
‚ typ Integer, którego wartościami w 32-bitowej
implementacji języka Delphi są liczby całkowite
z przedziału od !2 147 483 648 do 2 147 483 647,
‚ typ Cardinal, który przy implementacji 32-bitowej
obejmuje liczby całkowite z przedziału od 0
do 4 294 967 295.
PP-4(22 z 88)
Typy proste
Typy porządkowe S typy całkowite
Podstawowe typy całkowite (poza typem UInt64) są
podzbiorami typu Int64, chociaż wykonywanie operacji
arytmetycznych na elementach typów Int64 i UInt64 w
połączeniu z elementami innych typów całkowitych może
doprowadzić do błędnych wyników.
Dla typu LongInt istnieje predefiniowana stała
MaxLongint, która określa maksymalną wartość w tym
typie, tj. liczbę 2 147 483 647.
Dla typu Integer zdefiniowano stałą MaxInt określającą
maksymalną wartość w tym typie (w 32-bitowej
implementacji języka stała ta jest równa 2 147 483 647).
PP-4(23 z 88)
Typy proste
Typy porządkowe S typy znakowe
W języku Delphi zdefiniowano dwa podstawowe typy
znakowe i jeden ogólny typ znakowy. Każdy z tych typów
oznacza się za pomocą predefiniowanego identyfikatora.
Podstawowymi typami znakowymi są:
‚ AnsiChar,
‚ WideChar.
PP-4(24 z 88)
Typy proste
Typy porządkowe S typy znakowe
Wartościami typu AnsiChar są znaki zajmujące jeden
bajt pamięci, uporządkowane zgodnie z tabelą
rozszerzonego zestawu znaków ASCII. Elementy typu
WideChar zajmują dwa bajty pamięci (słowo) i są
znakami uporządkowanymi zgodnie z zestawem znaków
Unicode. Pierwszych 256 znaków z tego zestawu
pokrywa się ze znakami ASCII.
Ogólny typ znakowy jest oznaczany za pomocą
predefiniowanego identyfikatora Char. W obecnej
implementacji języka Delphi odpowiada on typowi
WideChar.
PP-4(25 z 88)
Typy proste
Typy porządkowe S typy logiczne
Standardowymi typami logicznymi są typy:
‚
‚
‚
‚
Boolean (elementy zajmują jeden bajt),
ByteBool (jeden bajt),
WordBool (dwa bajty),
LongBool (cztery bajty).
Wartości typów logicznych są oznaczane za pomocą
dwu predefiniowanych literałów (stałych): False i True,
oznaczających odpowiednio wartości logiczne fałsz
i prawda, przy czym w sensie uporządkowania stała
False poprzedza stałą True.
PP-4(26 z 88)
Typy proste
Typy porządkowe S typy okrojone
Typy okrojone służą do ograniczania zakresów wartości
dowolnego z dotychczas przedstawionych typów
porządkowych. Definicja jednego typu okrojonego ma
postać:
type identyfikator-typu = stała-1 .. stała-2;
przy czym obie stałe muszą być tego samego typu
porządkowego, zwanego typem bazowym. Pierwsza
z nich podaje ograniczenie dolne i nie może być większa
od drugiej – ograniczenia górnego.
PP-4(27 z 88)
Typy proste
Typy porządkowe S typy okrojone
Przykłady
type litera = ’A’ .. ’Z’;
Typ okrojony litera jest podzbiorem standardowego
typu Char (WideChar).
PP-4(28 z 88)
Typy proste
Typy porządkowe S typy okrojone
Przykłady
type tydzień
= (poniedziałek, wtorek,
środa, czwartek, piątek,
sobota, niedziela);
dni_robocze= poniedziałek .. piątek;
W definicji tej typ tydzień jest typem wyliczeniowym,
a typ dni_robocze typem okrojonym, którego
elementami są poniedziałek, wtorek, środa, czwartek
i piątek.
PP-4(29 z 88)
Typy proste
Typy porządkowe S typy okrojone
Przykłady
const a = 10;
b = 20;
type przedział = 2*(a!b) .. 2*(a+b);
W definicji typu okrojonego przedzial zastosowano
wyrażenia stałe. Elementami tego typu są liczby całkowite
z przedziału [!20, 60].
Następująca definicja jest błędna (dlaczego?):
type przedział = (a!b)*2 .. 2*(a+b);
PP-4(30 z 88)
Typy proste
Typy rzeczywiste
Wszystkie typy rzeczywiste są predefiniowane.
Każdy z dostępnych typów rzeczywistych jest
dyskretnym i skończonym podzbiorem zbioru liczb
rzeczywistych (w sensie matematycznym).
W języku Delphi zdefiniowano sześć
podstawowych typów rzeczywistych i jeden ogólny
typ rzeczywisty.
PP-4(31 z 88)
Typy proste
Typy rzeczywiste
Typami podstawowymi są:
‚ Real48, będący typem rzeczywistym, którego
elementy zajmują po sześć bajtów pamięci,
‚ Single, oznaczający typ rzeczywisty o pojedynczej
długości, którego elementy zajmują cztery bajty
pamięci każdy,
‚ Double, będący typem rzeczywistym o podwójnej
długości (każdy element tego typu zajmuje osiem
bajtów pamięci),
PP-4(32 z 88)
Typy proste
Typy rzeczywiste
Typami podstawowymi są:
‚ Extended, oznaczający typ rzeczywisty
o rozszerzonej długości, w którym każdy element
zajmuje 10 bajtów pamięci,
‚ Comp, którego elementy są liczbami całkowitymi
z przedziału od !263 do 263!1, tj. od około
!9.2e18 do około 9.2e18, zajmującymi po osiem
bajtów pamięci,
PP-4(33 z 88)
Typy proste
Typy rzeczywiste
Typami podstawowymi są:
‚ Currency, który jest typem danych
stałoprzecinkowych przeznaczonych do obliczeń
pieniężnych o wartościach
od !922 337 203 685 477.5808
do 922 337 203 685 477.5807,
zajmujących też po osiem bajtów.
PP-4(34 z 88)
Typy proste
Typy rzeczywiste
Mantysa wartości typu Real48 może zawierać do 11 lub
12 cyfr znaczących (w zależności od tego, czy
wyspecyfikowano kropkę dziesiętną czy nie). Dla typu
Single mantysa może zawierać odpowiednio 7 – 8 cyfr
znaczących, dla typu Double – 15 lub 16 cyfr, a dla typu
Extended – 19 lub 20.
Ogólnym typem rzeczywistym jest typ Real, który
w 32-bitowej implementacji języka jest równoważny
z typem Double. Oznacza to, że w implementacji tej
elementy (wartości) ogólnego typu Real zajmują po
osiem bajtów pamięci.
PP-4(35 z 88)
Typy proste
Typy rzeczywiste
W systemie pomocy środowiska Delphi podano
następujące najmniejsze dodatnie i największe wartości
elementów podstawowych typów rzeczywistych Real48,
Single, Double, Extended i ogólnego typu Real:
typ najmniejsza wartość dodatnia największa wartość
))))))))))))))))))))))))))))))))))))))))))))
Real48
2.9e!39
1.7e38
Single
1.5e!45
3.4e38
Double
5.0e!324
1.7e308
Extended
3.4e!4932
1.1e4932
Real
5.0e!324
1.7e308
PP-4(36 z 88)
Typy proste
Typy rzeczywiste
program FloatArithmetic;
{$APPTYPE CONSOLE}
{$R *.res}
Ten program wykazuje, że
type num = Single;
najmniejszą wartością dodatnią
var n : Integer;
zmiennej typu Single jest
ex: Extended;
x : num;
2!149 . 1,40129846432481707 !45.10
begin
x:=1;
n:=0;
Podobne testy można
repeat
ex:=x;
przeprowadzić dla
x:=x/2;
pozostałych typów
Inc (n)
until x=0;
rzeczywistych!
Writeln (’2^’, !n+1, ’ = ’, ex:26);
Readln
end.
PP-4(37 z 88)
Typy łańcuchowe
Łańcuchy służą do reprezentowania ciągu
znaków, w tym niewidocznego znaku spacji.
W języku Delphi występują następujące rodzaje
typów łańcuchowych:
‚
‚
‚
‚
‚
łańcuchy krótkie,
łańcuchy długie (ANSI),
łańcuchy Unicode,
łańcuchy zakończone znakiem pustym,
łańcuchy zasobowe.
PP-4(38 z 88)
Typy łańcuchowe
Typy łańcuchowe krótkie
Elementami typu łańcuchowego krótkiego są
łańcuchy, którym pamięć przydziela się statycznie
i których długość może zmieniać się dynamicznie
od 0 do maksymalnej długości podanej w definicji
typu łańcuchowego lub przyjmowanej domyślnie.
Przy wyłączonej dyrektywie $H (w stanie {$H!})
typ łańcuchowy krótki określa słowo kluczowe
string.
PP-4(39 z 88)
Typy łańcuchowe
Typy łańcuchowe krótkie
Jeśli po słowie string wyspecyfikowano rozmiar
ujęty w nawiasy kwadratowe (string [rozmiar]),
gdzie rozmiar oznacza liczbę całkowitą
z przedziału od 0 do 255 lub nazwę literału
o wartości całkowitej z tego samego przedziału,
to bez względu na stan dyrektywy kompilatora $H
określenie takie oznacza łańcuch krótki. Brak
wyspecyfikowania rozmiaru w stanie {$H!}
powoduje domyślne przyjęcie długości 255
znaków (dla łańcucha krótkiego).
PP-4(40 z 88)
Typy łańcuchowe
Typy łańcuchowe krótkie
Bez względu na stan dyrektywy kompilatora $H
typ łańcuchowy krótki można zdefiniować za
pomocą predefiniowanego identyfikatora
ShortString. Elementami typu ShortString są
łańcuchy (krótkie) o maksymalnej długości 255
znaków.
Każdy znak łańcucha krótkiego zajmuje jeden bajt pamięci,
a cała dana zajmuje liczbę bajtów pamięci wynikającą z liczby
znaków i zwiększoną o jeden. W tym dodatkowym bajcie pamięci
(o indeksie 0) jest przechowywana informacja o aktualnym
rozmiarze łańcucha.
PP-4(41 z 88)
Typy łańcuchowe
Typy łańcuchowe krótkie
Przykłady
type nazwisko = string [20];
Typ łańcuchowy krótki nazwisko może zawierać dane
będące łańcuchami o maksymalnej długości 20
znaków.
type napis = ShortString;
Bez względu na stan dyrektywy $H definicja ta określa
typ łańcuchowy krótki napis, którego elementami mogą
być łańcuchy o maksymalnej długości 255 znaków.
PP-4(42 z 88)
Typy łańcuchowe
Typy łańcuchowe długie
Typy łańcuchowe długie są oznaczane za pomocą
predefiniowanego identyfikatora AnsiString.
Dla elementów typów łańcuchowych długich nie jest
określona ich maksymalna długość. Pamięć jest im
przydzielana dynamicznie, a ich długość jest
ograniczona rozmiarem pamięci przeznaczonej dla
programu (teoretycznie do 2 GB).
PP-4(43 z 88)
Typy łańcuchowe
Typy łańcuchowe długie
Zmienna typu łańcuchowego długiego zajmuje cztery
bajty pamięci i zawiera wskaźnik do łańcucha, tj.
wskazuje na miejsce w pamięci, w którym znajduje się
łańcuch.
Łańcuch długi znajdujący się w pamięci jest zakończony
znakiem pustym (znakiem ASCII o kodzie 0), który
jednak nie jest jego częścią składową (nie zalicza się do
łańcucha).
Gdy zmienna typu łańcuchowego długiego nie zawiera
łańcucha (zawiera łańcuch o długości 0), jej wartością
jest adres pusty (nil).
PP-4(44 z 88)
Typy łańcuchowe
Łańcuchy Unicode
Do reprezentowania łańcuchów złożonych ze znaków
zestawu znaków Unicode służą predefiniowane typy
UnicodeString i WideString. W domyślnym stanie
dyrektywy kompilatora $H ({$H +}) typ UnicodeString
może też być oznaczany za pomocą słowa kluczowego
string. Maksymalne długości elementów obu typów
łańcuchowych są ograniczone wyłącznie dostępną
pamięcią.
Zmienne tych typów zajmują jednak tylko cztery bajty
pamięci i zawierają wskaźnik do dynamicznie
przydzielonego obszaru pamięci. Wartość nil takich
zmiennych oznacza, że łańcuch jest pusty.
PP-4(45 z 88)
Typy łańcuchowe
Łańcuchy Unicode
Elementami łańcucha typu UnicodeString mogą być
znaki jedno- lub wielobajtowe (w 32-bitowej
implementacji języka są to znaki dwubajtowe), a typu
WideString S znaki dwubajtowe zestawu znaków
Unicode.
PP-4(46 z 88)
Typy łańcuchowe
Łańcuchy zakończone znakiem pustym
Przez pojęcie łańcucha zakończonego znakiem pustym
rozumie się łańcuch podobny do łańcucha długiego
i łańcuchów typów UnicodeString i WideString, tyle że
opisany za pomocą tablicy znaków (niekoniecznie
jednobajtowych) indeksowanej od 0.
Przykłady
type nazwisko = array [0..15] of Char;
nazwa = array [0..92] of WideChar;
PP-4(47 z 88)
Typy łańcuchowe
Łańcuchy zakończone znakiem pustym
Podstawowa różnica w stosowaniu zwykłych łańcuchów
i łańcuchów zakończonych znakiem pustym polega na
wykonywaniu operacji na tych drugich za pomocą
wskaźników.
Do reprezentacji wskaźników do łańcuchów
zakończonych znakiem pustym służy predefiniowany typ
PChar. Zmiennej tego typu można przypisać literał
zmienny, a każde jej wystąpienie można zastąpić tablicą
znaków indeksowaną od 0.
PP-4(48 z 88)
Typy łańcuchowe
Łańcuchy zakończone znakiem pustym
Przykład
Jeśli zmienną wsk_znak zadeklarujemy następująco:
var wsk_znak : PChar;
to wykonanie instrukcji przypisania
wsk_znak := ’Delphi XE2’;
spowoduje, że zmienna ta będzie wskazywała na obszar pamięci
zawierający podany łańcuch. Ten sam skute da zastosowanie
konstrukcji
const łańcuch : array [0..10] of Char = ’Delphi XE2’;
var wsk_znak : PChar;
...
wsk_znak:=@łańcuch;
PP-4(49 z 88)
Typy łańcuchowe
Łańcuchy zasobowe
Łańcuchy zasobowe są to stałe, które są automatycznie
zapamiętywane w zasobie i kompilowane do plików .exe,
.dll i .dpl. Deklaracja pojedynczego łańcucha
zasobowego ma postać:
resourcestring identyfikator = wyrażenie-stałe;
gdzie wyrażenie stałe oznacza w ogólności wyrażenie
typu łańcuchowego, które może być obliczone przez
kompilator. W najprostszym przypadku jest to łańcuch.
PP-4(50 z 88)
Typy łańcuchowe
Łańcuchy zasobowe
Łańcuchy zasobowe umożliwiają przygotowanie programów
okienkowych, w których teksty ukazujące się na ekranie będą
wyświetlane w zależności od kraju użytkownika programu.
Łańcuchy zasobowe są zapisywane w oddzielnym pliku .drc. Aby
utworzyć dla danego programu jeden taki plik, wszystkie łańcuchy
zasobowe należy umieścić w jednym module.
Zasoby, które są w wyizolowanych plikach .drc mogą być łatwo
doprowadzone do odpowiednich wersji językowych za pomocą
programu narzędziowego Resource DLL Wizard, uruchamianego
poleceniem New 6 Other 6 Delphi Projects 6 Resource DLL
Wizard. Dotyczy to także plików .dfm, w których środowisko Delphi
automatycznie zapisuje zasoby zawierające menu, okienka
dialogowe i mapy bitowe.
PP-4(51 z 88)
Typy strukturalne
Typy te stosuje się do opisu obiektów złożonych.
Każdy z typów strukturalnych definiuje się przez podanie
typów elementów i metody strukturalizacji, która zarazem
określa sposób dostępu do elementów.
W ogólności definicja pojedynczego typu
strukturalnego ma postać
type identyfikator-typu = opis-typu-strukturalnego;
PP-4(52 z 88)
Typy strukturalne
Opis dowolnego typu strukturalnego może zaczynać się od słowa
kluczowego packed. Jego użycie jest wskazówką dla kompilatora,
aby wybrał reprezentację danej struktury zajmującą możliwie jak
najmniej bajtów pamięci. Reprezentację taką nazywamy postacią
spakowaną lub upakowaną.
Domyślnie kompilator umieszcza w pamięci poszczególne
elementy składowe struktur od granicy słowa lub podwójnego
słowa, co zapewnia szybszy dostęp do nich. Użycie słowa
kluczowego packed powoduje zapamiętywanie elementów struktur
w kolejnych bajtach, a tym samym zmniejsza całkowity obszar
pamięci zajętej przez strukturę.
Programista ma zatem do wyboru optymalizację programu albo ze
względu na szybsze jego działanie, albo na mniejszą zajętość
pamięci.
PP-4(53 z 88)
Typy strukturalne
Typy tablicowe
Tablica reprezentuje indeksowany zbiór elementów tego
samego typu.
Jeśli w opisie typu tablicowego podaje się liczbę
wymiarów i elementów w każdym wymiarze, to tablica
ma z góry określony rozmiar. Tablice takie nazywamy
tablicami statycznymi.
Drugim rodzajem tablic są tablice dynamiczne, dla
których w opisie typu tablicowego specyfikuje się
wyłącznie typ jej elementów, a pamięć przydziela się
w części wykonawczej jednostki programowej
(programu, modułu, biblioteki, funkcji lub procedury).
PP-4(54 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Tablica statyczna 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 (będzie dalej)
z typem indeksowym. Dopuszczalny zakres indeksów jest podany
w definicji typu tablicowego.
PP-4(55 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Definicja pojedynczego typu tablicy statycznej ma
postać
type identyfikator-typu = array [typy-indeksowe]
of typ-składowy;
gdzie typy indeksowe są opisami typu
porządkowego, przy czym poszczególne opisy
oddziela się przecinkami.
Typ składowy oznacza dowolny typ.
PP-4(56 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Przykłady
type wektor = array [0..50] of Integer;
Powyższa definicja określa typ wektor jako typ
tablicowy, o elementach ogólnego typu całkowitego
(Integer), ponumerowanych od 0 do 50.
PP-4(57 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Przykłady
type macierz = array [1..20] of array [1..30] of
Extended;
Typem składowym, tj. typem każdego z 20 elementów
typu tablicowego macierz, ponumerowanych od 1
do 20, jest 30-elementowa tablica liczb rzeczywistych
(Extended) o elementach ponumerowanych od 1
do 30. Elementami typu macierz są więc tablice
dwuwymiarowe o 600 elementach typu Extended.
PP-4(58 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Przykłady
type macierz = array [1..20, 1..30] of Extended;
Definicja ta określa taki sam typ tablicowy jak
poprzednio. Typ tablicowy macierz został tu wprost
zdefiniowany jako zbiór dwuwymiarowych tablic,
o zakresie pierwszego indeksu od 1 do 20 (liczby
całkowite) i drugiego indeksu – od 1 do 30 (także
liczby całkowite). Ze względu na nieco krótszy zapis,
tego rodzaju definicje zaleca się stosować do opisu
typów tablicowych wielowymiarowych.
PP-4(59 z 88)
Typy strukturalne
Typy tablicowe S tablice statyczne
Przykłady
type tablica = array [Boolean, 1..20, znak] of Char;
type tablica = array [Boolean, 1..20] of
array [znak] of Char;
type tablica = array [Boolean] of
array [1..20, znak] of Char;
type tablica = array [Boolean] of array [1..20] of
array [znak] of Char;
Wszystkie powyższe definicje typu tablica określają taki
sam typ tablicowy. Zauważmy, że typy indeksów
określone są w różny sposób.
PP-4(60 z 88)
Typy strukturalne
Typy tablicowe S tablice dynamiczne
Opis typu tablicowego (w definicji typu lub
deklaracji zmiennej), który nie zawiera określenia
typów indeksowych określa tablicę dynamiczną.
Definicja pojedynczego typu tablicy dynamicznej
ma postać
type identyfikator-typu = array of typ-składowy;
gdzie typ składowy oznacza dowolny typ.
PP-4(61 z 88)
Typy strukturalne
Typy tablicowe S tablice dynamiczne
W chwili deklaracji zmiennej typu tablicy statycznej następuje
przydzielenie jej odpowiedniego obszaru pamięci. Deklaracja
zmiennej typu tablicy dynamicznej powoduje przydzielenie jej tylko
czterech bajtów pamięci. Bajty te zawierają wskaźnik do miejsca
pamięci, począwszy od którego są pamiętane wartości elementów
tablicy (w chwili deklaracji zmiennej bajtom tym przypisuje się
wartość nil oznaczającą adres pusty).
Właściwe przydzielenie pamięci tablicy dynamicznej następuje
przez wywołanie procedury standardowej SetLength lub
DynArraySetLength, a zwolnienie – przez przypisanie danej
zmiennej wartości nil lub wywołanie dla niej procedury Finalize
(będzie dalej).
PP-4(62 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Rekordem (klasycznym) nazywa się złożoną
strukturę danych, której składowe, zwane polami,
mogą mieć różne 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.
PP-4(63 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Definicja pojedynczego typu rekordowego
(klasycznego) jest następująca:
type identyfikator-typu = record
lista-deklaracji-pól
end;
(cdn.)
PP-4(64 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Każda z deklaracji pól ma postać
lista-nazw-pól : opis-typu;
lub
var lista-nazw-pól : opis-typu;
Deklaracje pól mogą zawierać dyrektywy wskazówkowe.
Ostatnia deklaracja (wariantowa) może mieć postać
case deklaracja-pola-wyróżnikowego of
wykaz- wariantów;
lub
case identyfikator-typu-porządkowego of
wykaz- wariantów;
(cdn.)
PP-4(65 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Deklaracja pola wyróżnikowego wygląda następująco:
identyfikator-pola-wyróżnikowego :
identyfikator-typu- porządkowego
Każdy element wykazu wariantów ma postać
lista-etykiet-wyboru : (lista-deklaracji-pól)
PP-4(66 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Deklaracja pól ustala listę stałych pól danego typu
rekordowego i dla każdego pola określa jego nazwę
oraz typ.
Deklaracje wariantowe stosuje się co najmniej w dwóch
przypadkach. Po pierwsze, gdy chcemy utworzyć jeden
typ rekordowy zawierający różne typy danych, ale z góry
wiemy, że tylko z jednego rodzaju danych będziemy
korzystać dla każdej zmiennej tego typu rekordowego.
Po drugie, gdy zamierzamy w różny sposób
interpretować dane zapisywane w części wariantowej
rekordu.
PP-4(67 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Liczba bajtów zajętych przez elementy typów
rekordowych zależy od użycia lub nie słowa kluczowego
packed oraz od stanu dyrektywy przełącznikowej
kompilatora $A.
Przykłady
type data = record
rok
: SmallInt;
miesiac : 1 .. 12;
dzien : 1 .. 31
end;
PP-4(68 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Przykłady
W poniższej definicji typu rekwar występują dwa pola stałe (w tym
jedno wyróżnikowe). Pozostałe pola są wariantowe. Informacje
zapisane w odpowiednim miejscu pamięci będzie można odczytać
albo jako dwie wartości typu Byte, albo jako wartość typu
SmallInt.
type rekwar = record
a : Extended;
case b : Boolean of
True : (c, d : Byte);
False : (e : SmallInt)
end;
PP-4(69 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasyczne
Przykłady
Zastąpienie wiersza
case b : Boolean of
wierszem
case Boolean of
a więc zastąpienie deklaracji pola wyróżnikowego identyfikatorem
typu porządkowego, spowoduje, że typ rekordowy będzie miał
tylko jedno pole stałe i dwa lub jedno pole wariantowe.
W przypadku zadeklarowania zmiennej r2 takiego typu, dostęp
do jej pól wariantowych będzie możliwy za pomocą odwołań r2.c,
r2.d i r2.e.
PP-4(70 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasopodobne
Rekordy mogą mieć strukturę bardziej złożoną, która
przypomina strukturę klasy (będzie dalej).
Oprócz pól elementami rekordów mogą być:
- metody (w tym metody klasowe),
- konstruktory,
- własności (w tym własności klasowe),
- pola klasowe,
- typy zagnieżdżone.
Elementy te zostaną szczegółowo omówione przy okazji opisu
typu klasowego. Tutaj ograniczymy się do podania przykładu.
PP-4(71 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasopodobne
Przykład
type rekord_kl = record
type wzrost = Word;
typ zagnieżdżony
var wysoki : Word;
pole
class var niski : Word;
pole klasowe
constructor Utwórz (wartość : Word);
konstruktor
procedure Pokaż;
metoda
class procedure Zmień;
metoda klasowa
property własność_wysoki : wzrost
własność
read wysoki write wysoki;
class property własność_niski : wzrost
własność klasowa
read niski write niski;
end;
PP-4(72 z 88)
Typy strukturalne
Typy rekordowe S rekordy klasopodobne
Przykład (cd.)
Po definicji tego typu rekordowego powinny wystąpić (w przypadku
modułu w jego części implementacyjnej) definicje konstruktora
Utwórz, metody Pokaż i metody klasowej Zmień.
Różnice pomiędzy rekordami klasopodobnymi i klasami:
- rekordy nie mają własności dziedziczenia,
- w rekordach można przeciążać operatory,
- w rekordach nie można deklarować destruktorów,
metod wirtualnych, dynamicznych i metod do obsługi
wiadomości.
PP-4(73 z 88)
Typy strukturalne
Typy rekordowe S rekordy pomocnicze
Rekordy pomocnicze to rekordy skojarzone z innymi
rekordami, które definiują dla nich dodatkowe metody
i własności. Rekordy takie są wykorzystywane przy
modyfikacji kodu źródłowego, aby nie zmieniać definicji
rekordu oryginalnego.
Definicja:
type id-typu = record helper for id-typu-oryg
lista-elem-rekordu-pomoc
end;
PP-4(74 z 88)
Typy strukturalne
Typy rekordowe S rekordy pomocnicze
Lista elementów rekordu pomocniczego może zawierać
takie same elementy, jak w rekordzie klasopodobnym
z wyjątkiem deklaracji zwykłych pól.
Dla danego typu rekordowego można zdefiniować wiele
pomocniczych typów rekordowych, ale będzie
zastosowany ten, który znajduje się najbliżej zasięgu
oryginalnego typu rekordowego.
Jeśli w pomocniczym typie rekordowym zostanie
zdefiniowana metoda o takiej samej nazwie, jak w typie
oryginalnym, to przesłoni ona metodę zadeklarowaną
w typie oryginalnym.
PP-4(75 z 88)
Typy strukturalne
Typy zbiorowe
Każdy typ zbiorowy jest zbiorem potęgowym danego
typu porządkowego, tzn. jest zbiorem wszystkich
podzbiorów tego typu, w tym zbioru pustego.
Definicja pojedynczego typu zbiorowego ma postać
type identyfikator-typu = set of typ-porządkowy;
Liczba elementów typu porządkowego, zwanego typem
bazowym, nie może przekraczać 256, przy czym ich
liczby porządkowe muszą należeć do przedziału [0, 255].
PP-4(76 z 88)
Typy strukturalne
Typy zbiorowe
Oznacza to, że spośród standardowych typów
całkowitych jest dozwolone wyspecyfikowanie tylko
typu Byte.
Na ogół typ bazowy jest określany jako typ wyliczeniowy
lub okrojony.
Wartości typu zbiorowego zapisuje się przez podanie
w nawiasach listy elementów danego zbioru
(poszczególne elementy oddziela się przecinkami),
a zapis [ ] oznacza zbiór pusty.
Zapis taki nazywamy konstruktorem zbioru.
PP-4(77 z 88)
Typy strukturalne
Typy zbiorowe
Przykłady
type dni_pracy = set of (poniedziałek, wtorek,
środa, czwartek, piątek);
Elementami typu dni_pracy może być dowolny
podzbiór zbioru podanych nazw dni tygodnia, m. in.:
[poniedziałek, czwartek]
[]
[wtorek, środa, piątek], [wtorek, piątek, środa],
[środa, wtorek, piątek], [piątek, wtorek, środa]
- te same podzbiory
PP-4(78 z 88)
Typy strukturalne
Typy zbiorowe
Przykłady
type znaki
= set of AnsiChar;
małe_litery = set of ’a’ .. ’z’;
Elementami typu znaki są dowolne podzbiory zbioru
znaków ASCII, a elementami typu małe_litery
– dowolny podzbiór zbioru małych liter alfabetu
łacińskiego.
PP-4(79 z 88)
Typy strukturalne
Typy plikowe
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, tj. zbiorem danych rezydującym
w pamięci operacyjnej lub wprowadzanym czy
wyprowadzanym poprzez urządzenia zewnętrzne
(klawiatura, drukarka, napędy dysków).
Od tablicy plik różni się też metodą dostępu do
poszczególnych elementów.
PP-4(80 z 88)
Typy strukturalne
Typy plikowe
Plik jest logicznym modelem fizycznego zbioru danych.
Ze względu na rodzaj operacji wykonywanych na plikach
można uważać, że plik reprezentuje fizyczny zbiór
danych o dostępie sekwencyjnym. Oznacza to, że
w dowolnej chwili może być dostępny tylko jeden
element pliku, a dostęp do pozostałych elementów jest
możliwy dopiero po wykonaniu pewnych operacji na
pliku.
Za pomocą tego samego pliku można w programie
przetwarzać różne fizyczne zbiory danych.
PP-4(81 z 88)
Typy strukturalne
Typy plikowe
Pojedynczy typ plikowy definiuje się za pomocą
konstrukcji
type identyfikator-typu = file of
opis-typu-elementów-pliku;
Opis typu elementów pliku oznacza w ogólności
identyfikator typu prostego, opis typu porządkowego,
typ łańcuchowy krótki lub opis typu strukturalnego.
PP-4(82 z 88)
Typy strukturalne
Typy plikowe
Opis typu plikowego może składać się z samego słowa
kluczowego file. W takim przypadku przyjmuje się, że
dany typ plikowy jest niezdefiniowany.
Niezdefiniowane pliki są stosowane głównie w celu
dostępu do fizycznych zbiorów dyskowych bez względu
na ich wewnętrzny format.
PP-4(83 z 88)
Typy strukturalne
Typy plikowe
W języku Delphi istnieje też predefiniowany plik tekstowy
o nazwie TextFile (synonimem tej nazwy jest Text).
Elementami pliku tekstowego są wiersze podzielone na
znaki. Każdy wiersz takiego pliku zakończony jest parą
znaków sterujących CR/LF (skr. ang. carriage return
i line feed).
Pliki tekstowe stanowią logiczne modele służące do
obsługi zbiorów fizycznych dostępnych głównie za
pomocą takich urządzeń, jak: klawiatura, terminale,
drukarki i ekran monitora.
PP-4(84 z 88)
Typy strukturalne
Typy plikowe
Przykłady
type dane = file of LongInt;
wyniki = file of Extended;
Identyfikatory dane i wyniki zostały tu zdefiniowane
jako identyfikatory typów plikowych o elementach
odpowiednio LongInt i Extended.
PP-4(85 z 88)
Typy strukturalne
Typy plikowe
Przykłady
type complex = file of record
re, im : Extended
end;
Typ plikowy complex składa się z elementów
będących parami danych typu Extended.
PP-4(86 z 88)
Typy strukturalne
Typy plikowe
Przykłady
type data = file of record
rok
: SmallInt;
miesiac : 1 .. 12;
dzien : 1 .. 31
end;
PP-4(87 z 88)
PP-4(88 z 88)