M 4%
....... •
Adam Boduch
Helion
Adam Boduch |||f
■ ■ V
T A B L IC E
L - i i
IN FO R M A T Y C Z N E
BUDOWA APLIKACJI
Każdy program napisany w Delphi
identyfikowany jest przez słowo kluczowe
Znaczenie poszczególnych słów kluczowych
jest następujące:
program, które musi rozpoczynać pierwszą linię
program — słowo identyfikujące nazwę
w pliku
*.dpr:
programu;
program Project1;
uses —
słowo kluczowe włączające
moduły do aplikacji;
uses
begin —
blok rozpoczynający właściwe
Windows;
instrukcje programu;
end —
blok kończący instrukcje
begi n
programu.
// kod programu
end.
KOMPILACJA I URUCHAMIANIE
Kompilacja i uruchomienie projektu następuje
po wybraniu z menu
Run
pozycji
Run
lub
skorzystaniu ze skrótu
F9.
W menu
Project
istnieje jeszcze kilka opcji związanych
z kompilacją:
Compile
— sprawdza błędy, po czym
kompiluje tylko te moduły, które
zostały zmodyfikowane od czasu
ostatniej kompilacji;
KOMENTARZE
Komentarz liniowy
Komentarz liniowy zaczyna się od znaków //
i obowiązuje do końca danego wiersza
programu. Wszystko, co występuje w tej linii za
znakami //, nie jest brane pod uwagę przez
kompilator:
begi n
// komentarz
Foo; // wywołanie procedury (też
// prawidłowy komentarz)
end.
Build
— sprawdza błędy, po czym
kompiluje wszystkie moduły, dla
których dostępny jest kod
źródłowy (również te, które nie
zostały zmodyfikowane);
Syntax
— sprawdza błędy w kodzie
źródłowym, nie tworzy kodu
wynikowego.
Komentarz blokowy
W Delphi istnieją dwa rodzaje komentarzy
blokowych. Komentarze blokowe rozpoczynają
się od pewnego znaku (np. {) i obowiązują do
napotkania znaku kończącego komentarz (}):
{ komentarz
blokowy
)
W Delphi istnieje także możliwość używania
komentarza z użyciem znaków (* oraz *):
(* komentarz blokowy
{ może zawierać znaki { oraz )
*)
Przykład deklaracji prostej zmiennej I typu
Integer:
var
I : Integer;
Istnieje możliwość zadeklarowania kilku
zmiennych tego samego typu jednocześnie:
var
X, y, Z : Integer;
W niektórych przypadkach można zastosować
taką konwencję:
var
X : Integer;
Y : Integer;
Niejednokrotnie jednak grupowa deklaracja ma
znaczenie — np. w przypadku deklaracji tablic
(powiem o tym w dalszej części).
Nazwy zmiennych mogą się składać z małych
oraz dużych liter alfabetu angielskiego oraz cyfr
(pod warunkiem, że cyfra nie stanowi
pierwszego znaku nazwy zmiennej).
Nie można korzystać ze znaków specjalnych
(np. !() -=+1 \/<
>
/~~) oraz polskich
znaków diakrytycznych. Można natomiast
stosować znak podkreślenia (_). Dla Delphi nie
ma znaczenia wielkość liter w nazwie zmiennej.
Z : Integer;
Typy zmiennych
Typ zmiennej
Opis
Integer
-2147483648..2147483647
Int64
-2~63..2~63-l
Smalllnt
-32768.32767
Shortlnt
-128.. 127
Longlnt
-2147483648..2147483647
Byte
0..255
Word
0..65535
LongWord
0..4294967295
Char
pojedynczy znak
Boolean
TRUE lub FALSE
ShortString
do 255 znaków
AnsiString
~2 ~ 31 znaków (2 GB)
WideString
~2 ~ 30 znaków (2 GB)
1
String
Domyślnie równoważny z AnsiString
2
Extended
3.6x I0~-495I .. 1.1 x 10^4932
Double
5.0 x 10^-324.. 1.7 x 10 ~ 308
Single
1.5 x IO~-45 .. 3.4x I0~38
Currency
-922337203685477.5808..922337203685477.5807 19-20 8
Typ WideString jest zgodny
z kodem Unicode.
■ Przełącznik kompilacji {$H-
z AnsiString w sensie przypisania. Łańcuchy WideString są kompatybilne
-} powoduje, iż typ String będzie traktowany jako ShortString.
Przypisywanie danych
var
I : Integer;
begin
I := 0;
end.
Przypisanie danych może, ale nie musi,
odbywać się w bloku begin. .end. Do zmiennej
można przypisać dane w trakcie deklaracji (tak
jak dzieje się to w języku C):
I : Integer = 0;
W takim przypadku korzystamy z operatora =.
Przypisując do zmiennej dane tekstowe, musisz
otoczyć je znakami apostrofu:
var
S : String = *To jest łańcuch
^tekstowy*;
begin
S :=
1
Zmi ana danych
1
;
end.
const
Stała = 'Stała wartość';
begin
end.
Stałe deklarujemy po słowie kluczowym const,
podobnie jak zmienne po słowie kluczowym
var. Jak widzisz, wartość stałej jest nadawana
w momencie jej deklaracji i nie podlega
późniejszym zmianom
3
. Przypisanie danych do
stałej nie wymaga określenia typu (kompilator
sam określi typ na podstawie danych, które
chcemy przypisać). Możliwe jest jednakże
jawne nadanie typu:
const
Stała : String = 'Stała wartość';
begin
Writein(Stala); // wyświetl dane na
// konsoli
end.
Zmiana zawartości stałej jest możliwa przy
zastosowaniu przełącznika {$)+}, aczkolwiek nie
zaleca się tego:
($J+)
OPERATORY
Operatory arytmetyczne
Operator
Język Delphi
const
C : Integer = 10;
begin
C := 20;
end.
Operatory logiczne
Operator_________ Język Delphi
Dodawanie
Odejmowanie
Mnożenie
Dzielenie rzeczywiste
/
Dzielenie całkowite
di v
Reszta z dzielenia
mod
Logiczne i
Logiczne lub
Istnieje możliwość użycia operatorów + oraz -
w innym kontekście (tzw.
unary operators
), np.:
var
X : Integer;
begin
X := ~7; // otrzymamy -7
X := X + 8; // otrzymamy 1
X := -X; // otrzymamy -1
end.
Zaprzeczenie
not
Operatory porównania
Operator
Język Delphi
Nierówności
<>
Równości
Większości
>
Mniejszości
<
Większe lub równe
>=
Mniejsze lub równe
<=
Tablice służą do deklarowania „ciągu”
elementów tego samego typu. Tablice
deklarujemy z użyciem słowa kluczowego
array:
var
Tablica : array[0..1] of Integer;
W powyższym przykładzie mamy do czynienia
z dwuelementową tablicą typu Integer. W tym
przypadku po zadeklarowaniu tablicy jako
zmiennej wypełnienie jej danych wiąże się
z podaniem indeksu tablicy:
begin
Tablica[0] := 0;
Tablica[l] := 1;
end.
Oto przykład deklaracji tablicy jako stałej:
const
Tablica : array[0..1] of String =
('Elementl', 'Element2');
Tablice dynamiczne
W przypadku tablic dynamicznych ich rozmiaru
nie określamy w trakcie
pisania
programu, lecz
w trakcie jego
działania.
Deklaracja jest
następująca:
var
Tablica : array of Integer;
Nadawanie liczby elementów w trakcie
działania programu
begin
SetLength(Tablica, 2);
end.
Indeksem pierwszego elementu tablicy
dynamicznej jest zawsze zero.
Tablice wielowymiarowe
Istnieje możliwość zadeklarowania tablicy
wielowymiarowej, np.:
program Project1;
{$APPTYPE C0NS0LE}
var
Tablica
String;
array[1..2, 1..2] of
begi n
Tabli ca[1][1] := 'Wartość 1*
Tabli ca[1][2] := 'Wartość 2'
Tabli ca[2][1] := 'Wartość 3'
Tabli ca[2][2] := 'Wartość 4'
// lub...
Tablica[l, 1] := 'Wartość 1*
Tablica[l, 2] := 'Wartość 2'
Tabli ca[2, 1] := 'Wartość 3'
Tablica[2, 2] := 'Wartość 4*
end.
W takim programie łączna ilość elementów
tablicy wynosi 4 (dwuwymiarowa tablica, po
dwa elementy na każdy wymiar).
Grupowanie zmiennych
Grupowa deklaracja tablic powoduje, iż
z punktu widzenia kompilatora są one
równoważne:
var
X, Y : array[l..100] of Byte;
Z : array[1..100] of Byte;
begin
X := Y;
Z := Y; // błąd
end.
Ciąg dalszy na stronie 2 >
DELPHI
------------------------------1
TABLICE c.d.
chcemy umieścić blok el se przynależący do
instrukcji case, średnik przed słowem el se
if i =5 then Break; // wyjście
// z pętli, gdy zmienna I osiągnie ■
begin
Foo('String', 1, 1000);
Funkcje Low i High
Funkcje Low i High w połączeniu z tablicami
zwracają, odpowiednio, numer najmniejszego
oraz największego indeksu w tablicy
4
:
var
A : array[10..100] of String;
begin
Writeln(Low(A)); // zwróci 10
Writein(High(A)); // zwróci 100
end.
4
Funkcje Low oraz High zwracają także wartości
graniczne podanego typu, np.:
Writeln(Low(Byte)); // zwróci 0
Writeln(High(Byte)); // zwróci 255
INSTRUKCJE WARUNKOWE
Instrukcja if
Podstawowa instrukcja warunkowa ma postać:
if (warunek) then
begin
{ instrukcje do wykonania )
end else
begin
{ instrukcje do wykonania )
end;
Instrukcje Else
W najprostszej postaci można zrezygnować
z bloku el se, gdzie znajdują się instrukcje, które
mają zostać wykonane w przypadku, gdy
warunek nie zostanie spełniony. Przykład:
if 20 > 10 then
Writeln('Warunek spełniony')
else
Wri teln('Warunek ni espełni ony');
W takim wypadku warunek będzie zawsze
spełniony, gdyż liczba 20 jest większa od liczby
10. Zwróć uwagę, że gdy po słowie then
znajduje się tylko jedna instrukcja, możliwe jest
opuszczenie bloku begin. .end.
Przed
instrukcją el se nigdy nie może
znajdować się znak średnika!
Else if
W przypadku chęci sprawdzenia kilku
warunków można zastosować następującą
konwencję:
if X < Y then
{ instrukcje )
else
if X = Y then
{ instrukcje }
else
{ instrukcje )
Pamiętajmy o tym, aby kod umieścić
w dodatkowym bloku begin. .end, jeżeli mamy
do wykonania wiele instrukcji:
if X < Y then
begin
{ instrukcja 1 }
{ instrukcja 2 )
end else
begin
if X = Y then
begin
{ zagnieżdżony warunek if }
end;
end;
Instrukcja case
Druga instrukcja warunkowa, case, ma
następującą budowę:
case (wyrażenie) of
wartości: { instrukcja 1 );
wartość2: { instrukcja 2 );
end;
Instrukcji case używamy w sytuacji, gdy mamy
wiele warunków do sprawdzenia. Przykład:
case Zmienna_Typu_Integer of
10: Writeln('Zmienna ma wartość 10');
20: Writeln('Zmienna ma wartość 20');
30: Writeln{*Zmienna ma wartość 30');
end;
Powyższy przykład sprawdza wartość zmiennej
Zmienna_Typu_Integer i w zależności od jej
wartości wykonuje stosowne instrukcje (w tym
przypadku wyświetlenie tekstu na ekranie
konsoli).
Blok else
Napisałem poprzednio, że przed instrukcją el se
nie może znajdować się średnik. Fakt, to
prawda, lecz jedynie w połączeniu z i f. Jeżeli
musi się znaleźć:
Zmienna_Typu_Integer := 30;
case Zmienna_Typu_Integer of
10: Writeln('10');
20: Writeln(*20*);
else Writein('30');
end;
Po uruchomieniu programu na ekranie zostanie
wyświetlona liczba 30.
Zakresy
Zakresy służą do określania przedziałów,
w jakich może znaleźć się wartość:
Zmienna_Typu_Integer := 16;
case Zmienna_Typu_Integer of
10..
15: Writeln('Wartość od 10 do
15');
16..
20: Writeln(*Wartość od 16 do
20*);
else Writeln('30');
end;
Po uruchomieniu programu na ekranie zostanie
wyświetlony napis Wartość od 16 do 20.
// wartość 5
end;
end.
Instrukcja continue
PĘTLE
Pętla for
Pętla
for
ma ogólną postać:
for (wyrażenie początkowe) to
(wyrażenie końcowe) do
(instrukcje do wykonania);
Przykład:
for I := 1 to 10 do
Writeln(*Wykonanie nr ' +
‘■►IntToStr(i));
Powyższy przykład spowoduje 10-krotne
wykonanie kodu z ciała pętli.
Możliwe jest odliczanie w odwrotną stronę
— od liczby większej do mniejszej:
for I := 10 downto 1 do
Writeln('Wykonanie nr ' +
‘■►IntToStr(i));
Funkcja IntToStr znajduje się w module Sysllti 1 s.
1
Pętla while
Budowa pętli whi 1 e przedstawia się następująco:
while (warunek) do
begin
instrukcje;
end;
Blok begi n.. end nie jest obowiązkowy dla
jednej instrukcji, która ma zostać wykonana
w ramach działania pętli:
var
i : Integer;
begin
i := 0;
while (i < 20) do
begin
Writein('Wykonanie nr ' +
‘■►IntToStr(i));
Inc(i);
end;
end.
Pętla repeat
Budowa pętli repeat:
repeat
intrukcje;
until (warunek zakończenia);
Przykład:
var
i : Integer;
begin
i := 0;
repeat
Writeln('Wywołanie nr ' +
‘■►IntToStr(i));
Inc(i);
until I = 10;
end.
Instrukcja break
Instrukcja break umieszczona w ciele pętli
powoduje jej przerwanie i wyjście z pętli:
var
i : Integer;
begin
i := 0;
while (i < 20) do
begin
Writeln('Wykonanie nr ' +
‘■►IntToStr(i));
Inc(i);
W odróżnieniu od break, continue powoduje
przeskok do kolejnej iteracji pętli i sprawdzenie
warunku jej zakończenia:
var
i : Integer;
begi n
i := 0;
while (i < 20) do
begi n
if i =5 then
begin
{ gdy wartość osiągnie 5 - zwiększ
licznik i nie wykonuj żadnego
dalszego kodu - przejdź do następnej
iteracji i sprawdź warunek jej
zakończenia )
Inc(i);
Continue;
end;
Writeln('Wykonanie nr ' +
‘■►IntToStr(i));
Inc(i);
end;
end.
PROCEDURY I FUNKCJE
Procedury
Procedura musi być zadeklarowana z użyciem
słowa kluczowego procedurę:
procedurę Foo;
begin
{ kod procedury }
end;
Obowiązkowe elementy procedury:
procedurę — słowo kluczowe definiujące
procedurę;
nazwa — nazwa procedury (w tym wypadku
Foo);
blok begi n..end — właściwy kod procedury
(ciało).
Procedury zagnieżdżone
procedurę Foo;
procedurę Bar;
begin
{ kod procedury )
end;
begi n
Bar; // wykonaj procedurę
end;
Zmienne lokalne
Zmienne lokalne mogą być użyte jedynie
w ramach konkretnej procedury bądź funkcji
i nie są widoczne poza nią:
procedurę Foo;
var
S : String;
begin
S := 'Zmienna lokalna';
end;
Pamięć na potrzeby danej zmiennej jest
rezerwowana w momencie wywołania
procedury bądź funkcji, a zwalniana — po
zakończeniu jej działania. Zmiennym lokalnym
nie można przypisywać domyślnych wartości
w trakcie pisania programu, tak jak to ma
miejsce w przypadku zmiennych globalnych.
Parametry procedur
Parametry są elementami przekazywanymi do
procedury w momencie jej wywołania:
procedurę Foo(A : String);
begin
Writeln('Otrzymałem parametr: ' + A);
end;
begin
Foo('Parametr*);
end.
Kilka parametrów procedur
Poszczególne parametry procedury muszą być
oddzielone znakiem średnika:
procedurę Foo(S : String; B : Byte; I :
‘■►Integer);
begin
{ kod obsługi )
end;
end.
Grupowanie parametrów tego samego
typu
procedurę Foo(Sl, S2, S3 : String);
begin
{ kod obsługi )
end;
Parametry domyślne
Parametry procedur mogą mieć wartości
domyślne. Wówczas w trakcie wywołania danej
procedury nie jest konieczne podanie ich
wartości:
procedurę Foo(SI : String = 'Domyślny
‘■►parametr');
begin
end;
W przypadku wywołania procedury Foo bez
podania parametru domyślną wartością
parametru będzie Domyślny parametr.
Tablice jako parametry funkcji
i procedur
Procedura może zawierać parametr, który jest
tablicą otwartą:
procedurę ArrayProc(A : array of
‘■►String);
begin
// wyświetli górny indeks tablicy
Writein(High(A));
end;
var
A
array[0..1] of String;
begin
A[0] := 'Adam';
A[l] := 'Boduch';
ArrayProc(A); // wywołanie funkcji
Readln;
end.
Tutaj kryje się pewna pułapka — spójrz bowiem
na taki kod:
procedurę ArrayProc(A : array of
String);
begi n
Writein(High(A));
Writeln(Low(A));
Writein(A[0]);
end;
var
A
array[2..5] of String;
begi n
A[2] := 'Adam';
A[5] := 'Boduch';
ArrayProc(A); // wywołanie funkcji
end.
Po uruchomieniu programu na ekranie konsoli
wyświetlony zostanie następujący tekst:
3
0
Adam
Pomimo iż w programie najmniejszym
indeksem tablicy było 2, a największym — 5.
Funkcje
Funkcje deklarujemy przy użyciu słowa
kluczowego function. W odróżnieniu od
procedur funkcje zwracają rezultat:
function Foo : String;
begin
{ zwrócenie rezultatu )
Result := 'Funkcja Foo';
end;
begin
Writein(Foo); // na konsoli wyświetli
//'Funkcja Foo*
end.
Jeżeli chodzi o parametry funkcji i procedur, to
nie ma tutaj żadnych różnic.
Przeciążanie funkcji i procedur
Proces ten umożliwia deklarację dwóch funkcji
lub procedur o tej samej nazwie:
function Mnozenie(X, Y : Integer) :
‘■►Integer; overload;
begin
Result := X * Y;
end;
function Mnożenie(X, Y : Currency) :
‘■►Currency; overload;
begin
Result := X * Y;
end;
DELPHI
Warunkiem jest posiadanie przez funkcje bądź
procedurę różnych typów danych
w parametrze:
Mnozenie(2, 2);
Mnożenie(2.2, 2.2); // taki kod także
//jest dobry
Przekazywanie parametrów
do procedur i funkcji
Przekazywanie przez wartość
Przekazanie parametru do funkcji bądź
procedury przez wartość wiąże się
z utworzeniem jego lokalnej kopii. Deklaracja
parametru przekazywanego przez wartość nie
zawiera żadnego dodatkowego parametru:
procedurę Foo(S : String);
Przekazywanie przez referencję
Przekazanie parametru przez referencję wiąże
się z poprzedzeniem nazwy parametru słowem
var:
procedurę Foo(var S : String);
begin
S := 'Foo';
end;
Przekazywanie parametru poprzez referencję
powoduje, że wszelkie operacje będą
wykonywane bezpośrednio na nim — nie jest
w tym momencie tworzona żadna lokalna kopia.
W miejsce słowa kluczowego var można także
wstawić out dla zaznaczenia, że nieistotna jest
wartość wejściowa, a interesuje nas wartość
zwrócona przez procedurę.
Przekazywanie parametru przez stałą
Przekazanie parametru przez stałą wiąże się
z poprzedzeniem nazwy parametru słowem
const:
procedurę Foo(const S : String);
begin
end;
W takim przypadku nie są dozwolone
jakiekolwiek operacje zapisu danych
dokonywane na parametrze, jednak, podobnie
jak w przypadku referencji, nie jest tworzona
lokalna kopia parametru.
WŁASNE TYPY DANYCH
Własne typy można zadeklarować z użyciem
słowa kluczowego type:
type
TCustomType = 0..20;
var
CustomType : TCustomType;
begin
CustomType := 10;
end.
Typy tablicowe
type
TCustomType = array of Integer;
var
CustomType : TCustomType;
begin
SetLength(CustomType, 2);
CustomType[0] := 0;
CustomType[1] := 1;
end.
Typy zwracane przez funkcję
type
TCustomType = array of Integer;
function Foo : TCustomType;
begin
SetLength(Result, 2);
Result[0] := 0;
Result[1] := 1;
end;
ALIASY TYPÓW
Delphi umożliwia deklarowanie typów
będących równoznacznymi z już istniejącym:
type
TInt = Integer;
Od tej pory typ TInt będzie równoznaczny
typowi Integer.
Aliasowanie oznacza jednak tylko częściową
zgodność:
type
TInt = type Integer;
var
Intl : Integer;
Int2 : TInt;
procedurę A(var Value
begin
end;
TInt);
MyArray[l].X := 13;
MyArray[l].Y := 23;
MyArray[l].Str := 'ABCDEEF'
{itd.}
end.
procedurę B(var Value : Integer);
begin
end;
begin
Intl := 10;
Int2 := Intl;
A(Intl);
B(Int2);
end.
Typy Integer oraz TInt są traktowane przez
kompilator jako dwa odrębne typy
w kontekście przekazywania do parametrów
poprzez referencję.
REKORDY
Budowa rekordów
type
TRecord = record
X, Y : Integer;
end;
var
Rec : TRecord;
begin
Rec.X := 10;
Rec.Y := 10;
end.
Do elementów rekordu odwołujemy się za
pomocą operatora odwołania (znak kropki).
Rekord jako parametr funkcji
type
TMyRecord = record
X : Integer;
Y : Integer;
end;
function Dzielenie(MyRecord :
TMyRecord) : Integer;
begin
Result := MyRecord.X div
MyRecord.Y;
end;
Rekord jako zmienna
Możliwe jest pominięcie tworzenia nowego
typu dla rekordu i zadeklarowanie rekordu jako
zmiennej:
INSTRUKCJA WIĄŻĄCA WITH
Instrukcja wi th służy ukróceniu zapisu
związanego z rekordami:
var
Rec : packed record
X, Y : Integer;
Imię : String[20];
Nazwisko : String[20];
Wiek : Byte;
end;
begin
with Rec do
begin
X := 12;
Y := 24;
Imię := 'Jan';
Nazwisko := 'Kowalski';
Wiek := 20;
end;
end.
var
Rec
X,
S :
end;
begin
Rec.X
Rec.Y
Rec.S
end.
record
Y : Integer;
String;
=
10
;
=
100
;
= 'Dane tekstowe';
Kompresja rekordu
Użycie słowa kluczowego packed w połączeniu
z rekordami spowoduje zmniejszenie miejsca
w pamięci, jaką zajmuje rekord:
type
TRecord = packed record
X, Y : Integer;
end;
Przy użyciu klauzuli packed rozmiar rekordu
będzie sumą wszystkich pól rekordu. Minusem
takiego działania jest w niektórych wypadkach
nieco wolniejsze działanie programu.
Deklaracja tablic rekordowych
type
TMyRecord = record
X, Y : Integer;
Str : String;
end;
MyArray : array[0..10] of TMyRecord;
begin
MyArray[0].X := 1;
MyArray[0].Y := 2;
MyArray[0].Str := 'ABC';
MODUŁY
Moduły to pliki tekstowe zawierające kod
źródłowy języka Delphi. Przykładowy moduł
został przedstawiony poniżej:
unit Mainllnit;
interface
implementation
end.
Charakterystyczne elementy:
unit — nazwa identyfikująca moduł;
i nterface — sekcja publiczna modułu;
impl ementation — sekcja prywatna modułu;
end — koniec modułu.
Deklaracja i definicja procedury
unit MainUnit;
interface
{ deklaracja )
procedurę Foo;
function Bar : Integer;
implementation
{ definicja )
procedurę Foo;
begin
end;
function Bar : Integer;
begin
end;
end.
Initialization oraz finalization
Sekcje te służą do ustalenia kodu, który będzie
wykonywany po włączeniu modułu do pamięci
oraz jego zwolnieniu, czyli de facto po
uruchomieniu lub zakończeniu programu albo
załadowaniu lub zwolnieniu biblioteki DLL,
która korzysta z owego modułu:
unit MainUnit;
interface
uses Windows; // włączamy moduł Windows
procedurę ProcMain(Parami, Param2 :
^Integer);
implementation
procedurę ProcMain(Parami, Param2 :
^Integer);
begin
end;
initialization
MessageBox(0, 'Rozpoczynamy pracę
**z modułem...', *0K', MB_0K);
finalization
MessageBox(0, 'Kończymy pracę
**z modułem...', 'OK', MB_0K);
end.
WSKAŹNIKI
Deklaracja wskaźnika
Wskaźnik jest zmienną wskazującą na inną
zmienną. Deklaracja następuje z użyciem
operatora
var
S : ''String; // wskaźnik typu String
I : 'Tnteger; // wskaźnik typu
Integer
Uzyskiwanie adresu zmiennej
var
S
P
String;
''String;
begin
S := 'Delphi'; // przypisanie danych
// do zwykłej zmiennej
P := @S; // uzyskanie adresu zmiennej
P
7
' := 'Borland Delphi 7 Studio';
// modyfikacja danych
Writeln(S);
end.
Przydział i zwalnianie pamięci
Do zwalniania i przydzielania pamięci związanej
ze wskaźnikami służą funkcje New oraz Dispose:
program NewPointer;
uses
Dialogs;
type
{ dekaracja rekordu )
TInfoRec = packed record
FName : String[30];
SName : String[30];
Age : Byte;
Pesel : Int64;
Nip : String[60]
end;
PInfoRec = 'TInfoRec; // utworzenie
// wskaźnika na rekord
var
InfoRec: PInfoRec;
begin
{ rezerwacja pamięci potrzebnej na
rekord }
New(InfoRec);
{ przydzielenie danych rekordowi }
InfoRec
7
'.FName := 'Jan';
InfoRec
7
'.SName := 'Kowalski';
InfoRec
7
'.Age := 41;
InfoRec
7
'.Pesel := 55012010013;
InfoRec
7
'.Nip := *34234-23432-23423*;
ShowMessage(InfoRec
7
'. FName);
// wyświetlenie zmienionej wartości
{ zwolnienie rekordu )
Dispose(InfoRec);
end.
W powyższym przykładzie można pominąć
operator * — Delphi automatycznie rozpozna,
iż odwołujemy się do pola wskazującego na
rekord typu PInfoRec.
Wartość pusta dla wskaźnika
var
S : ''String;
begin
S := nil;
end.
DELPHI
Klasy można zadeklarować korzystając
z poniższego schematu:
type
[Nazwa klasy] = class [(Nazwa Klasy
^Bazowej)]
end;
Klasy deklarujemy po słowie kluczowym type:
type
TMyClass = class
end;
Tworzenie instancji klasy
Przed użyciem, klasa musi zostać utworzona na
skutek wywołania jej konstruktora:
type
TMyClass = class
end;
var
MyClass : TMyClass;
begin
MyClass := TMyClass.Create;
MyClass.Free; // zwolnienie obiektu
end.
Pola klasy
type
TMyClass = class
X : Integer;
S : String;
end;
Odwołanie do pól obiektu
var
MyClass : TMyClass;
begin
MyClass := TMyClass.Create;
MyClass.X := 10;
MyClass.S := 'Pole obiektu';
MyClass.Free; // zwolnienie obiektu
end.
Metody
Metoda to procedura lub funkcja znajdująca się
w klasie:
type
TMyClass = class
X : Integer;
S : String;
procedurę MetodaA;
function MetodaB : Integer;
end;
{ implementacja metod }
procedurę TMyClass.MetodaA;
begin
{ kod }
end;
function TMyClass.MetodaB : Integer;
begin
{ kod }
end;
Metody klasy
Metody klasy nie mają związku z konkretnym
obiektem. Deklarowane są przy użyciu słowa
kluczowego class, dzięki czemu możliwe jest
ich użycie bez tworzenia instancji klasy:
type
TMyClass = class
X : Integer;
S : String;
class procedurę MetodaA;
end;
{ TMyClass }
class procedurę TMyClass.MetodaA;
begin
end;
begin
TMyClass.MetodaA;
end.
Metody klasy nie mogą odwoływać się do pól
obiektu oraz metod niebędących metodami
klasy.
Klasa może mieć kilka sekcji dostępu: pri vate,
publi c, protected oraz publ i shed:
type
TMyClass = class
private
X : Integer;
protected
S : String;
publi c
procedurę MetodaA;
published
function MetodaB : Integer;
end;
Dziedziczenie
type
TBaseClass = class
procedurę Foo;
end;
TChildClass = class(TBaseClass)
procedurę Bar;
end;
W przypadku deklaracji nowej klasy, gdy nie
podamy klasy bazowej, kompilator automatycznie
przyjmie, iż klasą bazową będzie TObject. Tak
więc oba poniższe zapisy są sobie równoważne:
type
TMyClass = class
end;
TMyClass = class(TObject)
end;
Metody dynamiczne i wirtualne
TChildClass = class(TBaseClass)
procedurę Foo; virtual; // wirtualna
procedurę Bar; dynamie; // dynamiczna
end;
Polimorfizm
Metoda Foo z klasy TChi 1 dCl ass może mieć inne
znaczenie niż metoda Foo z klasy TBaseCl ass:
type
TBaseClass = class
procedurę Foo; virtual;
end;
TChildClass = class(TBaseClass)
procedurę Bar;
procedurę Foo; override;
end;
procedurę TBaseClass.Foo;
begin
Wri teln('TBaseClass');
end;
procedurę TChildClass.Foo;
begin
Wri teln('TChi1dClass');
end;
var
MyClass : TBaseClass;
Rand : Byte;
begi n
Randomize;
Rand := Random(2); // losujemy liczbę
if Rand = 0 then
MyClass := TBaseClass.Create
// jeżeli wylosowano 0 - wywołaj
// klasę TBaseClass
else
MyClass := TChildClass.Create;
MyClass.Foo; // wywołanie metody Foo
// z klasy TChildClass
MyClass.Free;
Readln;
end.
Przy dziedziczeniu klasa dziedzicząca przejmuje
wszystkie metody z klasy dziedziczonej
znajdujące się w sekcjach protected, publ i c
oraz publ i shed:
program Spark;
{$APPTYPE C0NS0LE)
type
TBaseClass = class
procedurę Foo;
end;
TChildClass = class(TBaseClass)
procedurę Bar;
end;
{ TBaseClass )
procedurę TBaseClass.Foo;
begin
Writein('Metoda Foo z klasy
TBaseClass');
end;
{ TChildClass )
procedurę TChildClass.Bar;
begin
{ kod )
end;
ChildClass : TChildClass;
begin
ChildClass
:=
TChildClass.Create;
ChildClass.Foo;
ChildClass.Free;
Readln;
end.
Przedefiniowanie metod
program Spark;
{$APPTYPE C0NS0LE)
type
TBaseClass = class
procedurę Foo; virtual;
end;
TChildClass = class(TBaseClass)
procedurę Foo; override;
procedurę Bar; dynamie;
end;
{ TBaseClass )
procedurę TBaseClass.Foo;
begin
Writein('Metoda Foo z klasy
TBaseClass');
end;
{ TChildClass )
procedurę TChildClass.Bar;
begin
{ kod )
end;
procedurę TChildClass.Foo;
begin
inherited; // wywołanie metody Foo
// z klasy bazowej
Writein('Metoda Foo z klasy
TChildClass');
end;
ChildClass : TChildClass;
begin
ChildClass
:=
TChildClass.Create;
ChildClass.Foo;
ChildClass.Free;
Readln;
end.
Konstruktory
Konstruktor w Delphi deklaruje się słowem
kluczowym eon struć tor; musi on być metodą
publiczną, jeżeli chcemy go wykorzystać
w innym module:
type
TChildClass = class(TBaseClass)
constructor CreateMain;
end;
var
ChildClass : TChildClass;
{ TChildClass )
constructor TChi1dClass.CreateMai n;
begin
{ kod konstruktora )
end;
begin
ChildClass := TChildClass.CreateMain;
ChildClass.Free;
Readln;
end.
Destruktory
Destruktory są wywoływane w momencie
zakończenia działań klasy i służą zwolnieniu
zasobów zajętych przez tę klasę:
type
TChildClass = class(TBaseClass)
constructor CreateMain;
destructor DestroyMain;
end;
ChildClass : TChildClass;
{ TChildClass )
constructor TChi1dClass.CreateMain;
begin
Writeln('Konstruktor klasy');
end;
destructor TChi1dClass.DestroyMai n;
begin
Writeln('Destruktor klasy');
end;
begin
ChildClass := TChildClass.CreateMain;
Chi 1dClass.DestroyMai n;
Readln;
end.
Można jednak pominąć deklarację własnego
destruktora na rzecz domyślnego — Destroy.
Właściwości
type
TBaseClass = class
private
FPropl : String;
FProp2 : Boolean;
public
property Propl : String read FPropl
write FPropl;
property Prop2 : Boolean read
FProp2 write FProp2;
end;
Właściwości mogą być tylko do odczytu,
wówczas zostawiamy jedynie taką frazę:
property Propl : String read FPropl;
Właściwości mogą także korzystać z funkcji
i procedur:
type
TBaseClass = class
private
FProp2 : Boolean;
procedurę SetPropl(Value : String);
function GetPropl : String;
publi c
property Propl : String read
GetPropl write SetPropl;
property Prop2 : Boolean read
FProp2 write FProp2;
end;
PLIKI DOŁĄCZANE
Pliki dołączane pozwalają na umieszczanie
fragmentów kodu w osobnych plikach
tekstowych. Program może wyglądać na
przykład tak:
program Projectl;
{$APPTYPE C0NS0LE)
procedurę About;
begin
{$1 FILE.INC)
end;
begin
About;
Readln;
end.
natomiast zawartość pliku
FILE. INC
może być
następująca:
Writeln(' 0 programie
');
Writeln('--------------------------- ');
Writeln('(c) 2004 by A.B.
');
Helion
Wydawnictwo Helion
Min ul. Chopina 6, 44-100 Gliwice
tel. (32) 231-22-19, (32) 230-98-63
g| e-mail: helion@helion.pl
^ WWW: http://helion.pl (księgarnia internetowa, katalog książek)
nformatyka w najl epszym wydani u
Zamów najnowszy katalog:
http://helion.pl/katalog
Zamów informacje o nowościach:
http://helion.pl/nowosci
Zamów cennik:
http://helion.pl/cennik
Aby ocenić tę tablicę, zajrzyj pod adres:
http://helion.pl/user/opinie7tidelp
ISBN 83-7361-576-8
9
7 8 8 3 7 3 6 1 5 7 6 2