02 2LVITTXNV5YLFAWI33HGQ7NAVX6F Nieznany (2)

background image

Rozdział 2.

Pascal bardziej zaawansowany

W tym rozdziale będziesz poznawać w dalszym ciągu tajniki języka Object Pascal. Za-

poznasz się z następującymi zagadnieniami:

υ

Instrukcja warunkowa

if

then

else

υ

Pętle:

for

,

while

i

repeat

υ

Instrukcja wyboru:

case

υ

Zakresy widzialności

υ

Rekordy

υ

Funkcje i procedury

if, then, else

Istnieją pewne słowa kluczowe, które występują we wszystkich językach programowania.
Jednym z nich jest instrukcja warunkowa if. Instrukcja ta służy do sprawdzania okre-

ślonego warunku w programie i w zależności od tego, czy warunek ten jest spełniony,

wykonywania różnych fragmentów kodu. Oto przykład:

var
X : Integer;
begin
X := StrToInt(Edit1.Text);
if X > 10 then
Label1.Caption := 'Podałeś liczbę większą od 10.';
end;

W przykładzie tym zawartość pola edycyjnego zapamiętywana jest w zmiennej typu
Integer. Jeżeli liczba ta jest większa od 10, wyrażenie x > 10 otrzymuje wartość

True i wyświetlany jest odpowiedni komunikat. W przeciwnym przypadku nic nie jest

wyświetlane. Innymi słowy – jeżeli wyrażenie warunkowe (zawarte między słowami
if i then) osiąga wartość True (prawda), wykonywana jest instrukcja znajdująca się

bezpośrednio za słowem then.

background image

64

Część I

64

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Instrukcja warunkowa if służy do sprawdzania określonego warunku, i w zależno-
ści od jego spełnienia wykonywania jednej lub więcej linii kodu.

Wykonywanie wielu instrukcji

Załóżmy, że chcesz, aby w przypadku spełnienia warunku wykonywany był blok kodu

składający się z wielu linii. W tym celu musisz te linie objąć słowami kluczowymi

begin

i

end

:

if X > 10 then begin
Label1.Caption := 'Podałeś liczbę większą od 10.';
ZrobCosZLiczba(X);
end;

Kiedy wyrażenie warunkowe jest fałszywe, cały ten blok jest ignorowany i wykonywa-

na jest pierwsza instrukcja następująca po tym bloku.

Object Pascal posiada wiele zapisów skrótowych ułatwiających pisanie ko-

du i zwiększających jego czytelność. Jeden z nich pozwala sprawdzać, czy

jakaś zmienna typu

Boolean

ma wartość

True

, podając tylko jej nazwę,

np.:

if OtwartoPlik then CzytajDane;

Powyższa instrukcja ma takie samo znaczenie, co

if OtwartoPlik = True then CzytajDane;

Metoda ta ma zastosowanie tylko w przypadku zmiennych typu Boolean. Z

kolei sprawdzić fałszywość takiej zmiennej można dodając słowo

not

przed jej nazwą, np.:

var
OtwartoPlik : Boolean;
begin
OtwartoPlik := OtworzJakisPlik;
if not OtwartoPlik then WyswietlKomunikatOBledzie;
end;

Kod z takimi skrótami wygląda po prostu „elegancko”. Poza tym poznawa-

nie ich ułatwi Ci czytanie kodu w programach przykładowych.

1

1

Dla dociekliwych: może to zaskakujące, ale warunek if X nie jest dokładnie tym samym, co wa-

runek if X = TRUE – pierwszy z nich jest prawdziwy, jeżeli reprezentacja zmiennej X zawiera

przynajmniej jeden bit niezerowy, drugi natomiast prawdziwy jest tylko wtedy, jeśli reprezentacja
ta równa jest d o kła dn ie wartości TRUE (w Delphi 4 Ord(TRUE) równe jest 1) (przyp. red.)

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

65

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

65

Dodajemy else

W niektórych przypadkach istnieje potrzeba wykonania pewnej sekwencji instrukcji,
gdy wyrażenie warunkowe będzie prawdą, i wykonania innej sekwencji instrukcji, gdy
wyrażenie warunkowe będzie fałszem. Do instrukcji warunkowej należy wtedy dodać
słowo

else

:

if X = 20 then
ZrobCos(X)
else
ZrobCosInnego(X);

Słowo kluczowe else używane jest w połączeniu z if i oznacza początek
instrukcji, które wykonywane są, gdy wyrażenie warunkowe osiąga wartość
False.

W powyższym przykładzie w zależności od wartości X wywołana będzie jedna albo
druga funkcja (ale nie obie).

Zwracam też uwagę na to, że instrukcja następująca po słowie

then

nie jest zakończona

średnikiem. Dzieje się tak dlatego, że cała sekwencja

if … then … else

traktowana jest

jako jedna instrukcja. Przy tym średnika tego nie stosuje się tylko wtedy, gdy między

then

i

else

jest tylko jedna instrukcja (tzn. nie ma ich kilku między słowami

begin

i

end

).

Oto kilka przykładów prawidłowej składni instrukcji warunkowej:

if X = 20 then
ZrobCos(X) {brak średnika, ponieważ jest to pojedyncza linia}

else
ZrobCosInnego(X);

if X = 20 then begin
ZrobCos(X);
end

{brak średnika, ponieważ blok begin/end traktowany}

else

begin

{jest jak pojedyncza linia}

ZrobCosInnego(X);
end;

if X = 20 then begin
ZrobCos(X); {wiele instrukcji w bloku begin/end, po każdej
X := 200;

{jest średnik}

Y := 30;
end

else begin
ZrobCosInnego(X);
X := 100;
Y := 15;
end;

background image

66

Część I

66

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Dla kompilatora nie ma znaczenia, czy słowa

then, begin

i

else

w jednej, czy też w wielu liniach. Poniższe dwa fragmenty kody są sobie
równoważne:

{Pierwsza wersja}
if X = 20 then begin
ZrobCos(X);
X := 200;
Y := 30;
end else begin
ZrobCosInnego(X);
X := 100;
Y := 15;

end;

{Druga wersja}
if X = 20
then
begin
ZrobCos(X);
X := 200;
Y := 30;
end
else
begin
ZrobCosInnego(X);

X := 100;
Y := 15;
end;

Najlepiej sam obierz sobie jakiś styl i stosuj go konsekwentnie. Najważ-
niejszym kryterium jest przy tym czytelność kodu.

Pamiętaj o tym, że znak „=” oznacza operator równości, natomiast „:=” jest
operatorem przypisania. Częstym błędem jest zamiana tych dwóch operato-
rów. Jednak w tym przypadku kompilator wyświetli odpowiedni komuni-
kat.

Zagnieżdżone instrukcje if

W razie potrzeby istnieje możliwość zagnieżdżania instrukcji

if

. Zagnieżdżanie jest niczym

innym, jak umieszczaniem instrukcji

if

wewnątrz innej instrukcji

if

.

if X > 10 then
if X < 20 then
Label1.Caption := 'Wartość X jest między 10 a 20.';

Jest to jednak bardzo uproszczona sytuacja. W rzeczywistości kod najczęściej jest

znacznie bardziej skomplikowany. Można się czasami naprawdę pogubić w gąszczu

słów

if

,

then

,

begin

i

end

. Spójrz na poniższy przykład:

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

67

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

67

if X > 100 then begin
Y := 20;
if X > 200 then begin
Y := 40;
if X > 400 then begin
Y := 60;
ZrobCos(Y);
end;
end;
end else if X < -100 then begin
Y := -20;
if X < -200 then begin
Y := -40;
if X < -400 then begin
Y := -60;
ZrobCos(Y);
end;
end;
end;

To jeszcze nie był najbardziej skomplikowany przykład, ale wiesz zapewne, o co mi
chodzi.

Jeżeli sytuacja wymaga zastosowania dwóch lub trzech zagnieżdżonych in-
strukcji if, może to być dobra okazja do użycia instrukcji case.

W przykładach przytoczonych do tej pory używałem tylko jednego wyrażenia warun-
kowego w instrukcji

if

. Kiedy stosowane jest tylko jedno wyrażenie warunkowe, można

je ująć w nawiasy lub nie. Jednakże, jeżeli tych wyrażeń warunkowych jest więcej niż
jedno, musisz ująć każde z nich w nawiasy. Na przykład:

if (X = 20) and (Y=50) then
ZrobCos;

Gdybyś zapomniał wstawić nawiasów, kompilator poinformowałby Cię o tym wyświe-
tlając odpowiedni komunikat.

Instrukcja warunkowa jest bardzo często spotykana w programach pisanych w Object
Pascalu. Nie jest ona wcale skomplikowana, więc nie będziesz miał z jej stosowaniem
prawdopodobnie żadnych kłopotów. Jedyne, o czym musisz pamiętać, to odpowiednia
liczba słów

begin

i

end

.

Wyrażenie if ... then ... else, wariant 1

Składnia

if wyrazenie_warunkowe then
instrukcja_wykonywana_gdy_true
else

instrukcja_wykonywana_gdy_false;

background image

68

Część I

68

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Wyrażenie warunkowe if ... then ... else, wariant 2

Składnia

if wyrazenie_warunkowe_1 then
begin
instrukcje_wykonywane_gdy_true;
end
else
begin
instrukcje_wykonywane_gdy_false;
end;

Pętle

Pętle (instrukcje iteracyjne) są drugim elementem istniejącym chyba we wszystkich ję-
zykach programowania. Mogą być one używane do działań na kolejnych elementach
tablicy, do wykonywania pewnych instrukcji określoną liczbę razy, do sekwencyjnego
odczytywania pliku dyskowego, itd. Liczba zastosowań pętli jest chyba nieograniczona.
Omówię tutaj pętle typu

for

,

while

i

repeat

. Wszystkie te typy mają pewne wspólne

elementy, a mianowicie:

υ

Punkt startu

υ

Blok instrukcji wykonywanych przy każdej iteracji („ciało pętli”)

υ

Punkt stopu

υ

Sprawdzenie warunku zakończenia działania pętli

υ

Możliwość użycia procedur

Break

i

Continue

Pętla jest elementem języka programowania służącym do iteracyjnego wy-
konywania określonych instrukcji aż do spełnienia warunku zakończenia
działania.

Punktem startu pętli jest słowo kluczowe

for

,

while

albo

repeat

. Ciało pętli stanowi

jedna lub wiele dowolnych instrukcji Object Pascala. Jeżeli instrukcji jest więcej niż
jedna, muszą one być (z wyjątkiem pętli

repeat

) objęte słowami

begin

i

end

. Punktem

stopu jest w przypadku pętli

for

i

while

zamykające ciało słowo

end

, natomiast

w przypadku pętli

repeat

punktem stopu jest słowo kluczowe

until

.

Pętle z reguły działają następująco: Następuje wejście do pętli, następnie sprawdzany
jest warunek zakończenia działania. Jeżeli warunek ten jest fałszywy, wykonywane są
instrukcje stanowiące ciało pętli. Po osiągnięciu punktu stopu następuje skok na począ-
tek i ponowne sprawdzenie warunku zakończenia działania. Jeżeli będzie miał wartość

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

69

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

69

False

, cały cykl się powtarza. W przeciwnym przypadku następuje skok do instrukcji

następnej za punktem stopu, czyli wyjście z pętli. Wyjątkiem jest pętla

repeat

, w której

sprawdzanie warunku zakończenia działania następuje dopiero po wykonaniu ciała pętli.

Znaczenie warunku zakończenia działania pętli można wyrazić na przykład następująco:
„Wykonuj to i to, dopóki X jest różne od 10” albo „Czytaj kolejne bajty z pliku dopóki
nie osiągniesz jego końca”.

Częstym błędem jest takie skonstruowanie warunku zakończenia działania
pętli, że nie może on nigdy osiągnąć wartości

True

. W rezultacie tego pro-

gram wpada w nieskończoną pętlę. Jedynym wyjściem jest wtedy zastoso-
wanie kombinacji klawiszy

Ctrl+Alt+Del

i „zabicie” tego programu (w

oknie „Zamknij program” lub w Menedżerze Zadań Windows NT zapętlo-
ny program oznaczony jest jako „nie odpowiada”).

W Delphi IDE zwykle uruchamia się programy klikając ikonę „Run” albo
naciskając klawisz F9. Sposobem na „zabicie” tak uruchomionego progra-
mu jest wybranie z menu opcji Run | Program Reset albo naciśnię-
cie kombinacji klawiszy Ctrl+F2. Jednak Windows 95 może zawiesić się
całkowicie po kilkukrotnym użyciu tej opcji (Windows NT jest w tym
przypadku o wiele bardziej odporne). Staraj się więc jej nie nadużywać.

Uzbrojeni w dopiero co zdobytą wiedzę możemy teraz przystąpić do dokładniejszego
zapoznawania się z poszczególnymi typami pętli.

Pętla for

Jest to najpopularniejszy typ pętli. Parametrami tej pętli są wartość początkowa i war-
tość końcowa zmiennej sterującej. Jeżeli wartość początkowa jest mniejsza od wartości
końcowej, używane jest słówko

to

. Jeżeli natomiast wartość początkowa jest większa

od końcowej, stosowane jest słówko

downto

.

Składnia

Pętla for, odliczanie do góry
for wartosc_poczatkowa to wartosc_koncowa do begin
instrukcje;
end;

W tej wersji blok instrukcji oznaczonych jako

instrukcje

wykonywany jest dopóty,

dopóki zmienna sterująca zainicjowana wartością

wartosc_poczatkowa

nie osiągnie

wartości

wartosc_koncowa

. Zmienna sterująca jest inkrementowana (jej wartość zwiększa

się o 1) w trakcie każdej iteracji.

background image

70

Część I

70

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Składnia

Pętla for, odliczanie do dołu
for wartosc_poczatkowa downto wartosc_koncowa do begin
instrukcje;
end;

Ta wersja pętli działa tak samo jak poprzednia z tą różnicą, że zmienna sterująca jest

dekrementowana.

Formalne zapisy zawsze są dość niejasne i trudne z początku do zrozumienia, w prze-

ciwieństwie do przykładów, których kilka przedstawiam poniżej.

Pierwszy z nich ilustruje użycie pętli

for

z odliczaniem do góry:

var
I : Integer;
begin
for I := 0 to 9 do begin
Memo1.Lines.Add('Iteracja nr ' + IntToStr(I));
end;
end;

Instrukcja dodająca linię tekstu do komponentu

Memo1

wykona się tutaj 10 razy. Zmienna

sterująca

I

przyjmuje kolejno wartości od 0 do 9.

Nazywanie zmiennej sterującej pętli for literą I jest tradycją wywodzącą
się jeszcze z Fortranu i jest często spotykane.

Oto następny przykład, który jest zmodyfikowaną wersją pierwszego:

var
I : Integer;
begin
for I := 9 downto 0 do begin
Memo1.Lines.Add('Iteracja nr ' + IntToStr(I));
end;
end;

W tym przypadku

I

osiąga kolejno wartości od 9 do 0. Słowo

downto

wskazuje na to, że

wartość zmiennej sterującej ma być zmniejszana o 1 przy każdym przebiegu pętli.

Stosowanie słów kluczowych begin i end obejmujących jedną instrukcję
(stanowiącą ciało pętli) nie jest wymagane.

Przykładowy program z pętlą for

Nic tak dobrze nie utrwala teorii jak praktyka. Napiszmy więc program, w którym za-
stosujemy pętlę

for

i komponent

Memo

(wspomniany już wcześniej w tym rozdziale).

Wykonaj następujące czynności:

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

71

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

71

1.

Utwórz nową aplikację (

File | New Application

).

2.

Umieść przycisk na formularzu.

3.

Znajdź komponent

Memo

na karcie „Standard” Palety Komponentów (powinien

znajdować się po lewej stronie komponentu

Button

) i umieść go na formularzu.

4.

Powiększ rozmiar umieszczonego na formularzu komponentu

Memo1

poprzez

przeciągnięcie czarnego prostokąta w jego prawym dolnym rogu.

5.

Kliknij podwójnie na przycisku. Otworzy się procedura obsługi

OnClick

tego

przycisku. Wpisz do niej:

procedure TForm1.Button1Click(Sender: TObject);
var
I : Integer;
begin

Memo1.Lines.Clear;

for I := 0 to 5 do
Memo1.Lines.Add('Iteracja nr: ' + IntToStr(I));

Memo1.Lines.Add('');

for I := 5 downto 0 do
Memo1.Lines.Add('Iteracja nr: ' + IntToStr(I));

end;

Uruchom teraz program. Po naciśnięciu przycisku zawartość komponentu

Memo1

po-

winna wyglądać jak na rysunku 2.1.

Rysunek 2.1.
Wynik działania
pętli for

Tak jak powiedziałem wcześniej, wartość zmiennej sterującej pętli

for

jest przy każ-

dym przebiegu zwiększana o 1. Nie ma niestety w Object Pascalu możliwości zmiany
tego kroku. Nie można na przykład odliczać od 0 do 100 z krokiem co 10. Aby uzyskać
taki efekt, należy użyć dodatkowej zmiennej:

background image

72

Część I

72

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

var
I : Integer;
X : Integer;
begin
X := 0;
Memo1.Lines.Clear;

for I := 0 to 9 do begin
Memo1.Lines.Add('Wartość zmiennej w bieżącej iteracji: ' + IntToStr(X));
Inc(X, 10);
end;
end;

Po uruchomieniu tak zmodyfikowanego programu na komponencie

Memo1

pokazałyby

się linie:

Wartość zmiennej w bieżącej iteracji: 0
Wartość zmiennej w bieżącej iteracji: 10
Wartość zmiennej w bieżącej iteracji: 20
Wartość zmiennej w bieżącej iteracji: 30
Wartość zmiennej w bieżącej iteracji: 40
Wartość zmiennej w bieżącej iteracji: 50
Wartość zmiennej w bieżącej iteracji: 60
Wartość zmiennej w bieżącej iteracji: 70
Wartość zmiennej w bieżącej iteracji: 80
Wartość zmiennej w bieżącej iteracji: 90

Zwróć uwagę na wywołanie procedury Inc. Funkcja ta dodaje do zmiennej
będącej jej parametrem określoną wartość – w tym przypadku 10. Gdy nie po-
da się wartości, następuje zwiększenie o 1, tak jak w poniższym przykła-
dzie:

Inc(X);

{znaczy to samo, co X := X + 1}

Analogicznie do procedury Inc (zwiększanie) działa jej bliźniaczka – Dec
(zmniejszanie):

Dec(X);

{X := X - 1}

Dec(X, 10);

{X := X – 10}

Funkcje Pred i Succ

Funkcja

Pred

(od ang. predecessor) zwraca poprzednik swojego argumentu. Na przykład,

Pred(10)

daje 9,

Pred(100)

daje 99 itd. Poniższe 3 pętle

for

są więc równoważne (celem

jest 10-krotne wywołanie procedury

JakasProcedura

):

var
X : Integer;
begin
X := 10;

for I := 0 to 9 do
JakasProcedura;

for I := 0 to X – 1 do

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

73

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

73

JakasProcedura;

for I := 0 to Pred(X) do
JakasProcedura;
end;

Funkcja

Succ

(od ang. successor) – analogicznie - zwraca następnik argumentu. Przydaje

się ona często przy odliczaniu wstecz:

for I := 100 downto Succ(X) do
JakasProcedura;

Pętla while

Pętla

while

tym różni się od pętli

for

, że posiada warunek zakończenia działania

sprawdzany na początku każdej iteracji. Pętla wykonuje się tak długo, dopóki warunek
ten pozostaje prawdziwy.

var
X : Integer;
begin
X := 0;
while X < 1000 do begin
X := JakiesObliczenia;
JakasInnaProcedura;
end;
...
end;

W tym przykładzie w pętli wywoływana jest funkcja

JakiesObliczenia

, która zwraca

pewną wartość przypisywaną zmiennej X. Dopóty, dopóki wartość ta jest mniejsza od
1000, pętla jest wykonywana. Jeżeli natomiast zmienna X będzie równa lub większa niż
1000, nastąpi opuszczenie pętli (skok do pierwszej instrukcji po niej następującej). Czę-
sto w pętli

while

do sprawdzania warunku zakończenia działania używa się zmiennej

typu

Boolean

, którą można ustawiać w ciele pętli:

var
Zakonczone: Boolean;
begin
Zakonczone := False;
while not Zakonczone do begin
JakasProcedura;
Zakonczone := JakasFunkcjaZwracajacaWartoscBoolean;
JakasInnaProcedura;
end;
end;

Zmienna

Zakonczone

musi kiedyś przyjąć wartość

True

, aby pętla mogła się zakończyć.

Stwórzmy teraz inną przykładową aplikację z użyciem pętli

while

. Otwórz nowy pro-

jekt i umieść na formularzu

Button

oraz

Memo

. Kliknij podwójnie przycisk i jego proce-

durę obsługi zdarzenia

OnClick

zmodyfikuj następująco:

procedure TForm1.Button1Click(Sender: TObject);
var

background image

74

Część I

74

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

I : Integer;
begin
I := 5;
Memo1.Lines.Clear;
while I > -1 do begin
Memo1.Lines.Add('Dzisiaj mam ' + IntToStr(I) + ' spraw do
załatwienia.');
Dec(I);
end;
Memo1.Lines.Add('Uff!');
end;

Po uruchomieniu programu i kliknięciu przycisku

Button1

w komponencie

Memo1

pojawi

się tekst:

Dzisiaj mam 5 spraw do załatwienia.
Dzisiaj mam 4 spraw do załatwienia.
Dzisiaj mam 3 spraw do załatwienia.
Dzisiaj mam 2 spraw do załatwienia.
Dzisiaj mam 1 spraw do załatwienia.
Dzisiaj mam 0 spraw do załatwienia.
Uff!

W programie tym zadeklarowałeś zmienną

I

i przypisałeś jej początkową wartość 5.

Następnym krokiem było wejście do pętli. Przy każdym przebiegu pętli następowało
dodanie jednej linii tekstu do komponentu

Memo1

i zmniejszenie o 1 wartości zmiennej

I

.

Gdy

I

osiągnęła wartość –1, nastąpiło wyjście z pętli i dodanie do

Memo1

ostatniej linii

tekstu.

Składnia

while wyrazenie_warunkowe do begin
Instrukcje;
end;

W pętli

while

blok instrukcji

Instrukcje

wykonywany jest tak długo, dopóki wyrażenie

warunkowe

wyrazenie_warunkowe

ma wartość

True

. Wartość wyrażenia warunkowego

musi być zainicjalizowana przed wejściem do pętli oraz określana w ciele pętli. Wyjście
z pętli następuje, gdy wyrażenie warunkowe sprawdzane na jej początku jest fałszywe.
Gdy w ciele pętli jest tylko jedna instrukcja, słowa kluczowe

begin

i

end

nie są wymagane.

Pętla repeat

Pętla

repeat

jest bardzo podobna do pętli

while

. Różnica między nimi jest niewielka,

ale jednak bardzo istotna. W pętli

while

warunek zakończenia działania sprawdzany

jest na początku (przed pierwszym wykonaniem ciała pętli), natomiast w pętli

repeat

warunek zakończenia działania sprawdzany jest na jej końcu. Oto poprzedni przykład,
w którym pętlę

while

zastąpiono pętlą

repeat

:

procedure TForm1.Button1Click(Sender: TObject);
var
I : Integer;

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

75

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

75

begin
I := 5;
Memo1.Clear;
repeat
Memo1.Lines.Add('Dzisiaj mam ' + IntToStr(I) + ' spraw do
∑ załatwienia.');
Dec(I);
until I = -1;
Memo1.Lines.Add('Uff!');
end;

Rezultat działania tego programu będzie taki sam, jak poprzednio. Zwróć uwagę, że nie
trzeba tu używać słów

begin

i

end

, ponieważ ich rolę spełniają w tej pętli słowa

repeat

i

until

.

Składnia

repeat
Instrukcje;
until wyrazenie_warunkowe;

W pętli tej blok kodu oznaczony jako Instrukcje wykonywany jest tak długo, dopóki
wyrażenie warunkowe jest fałszywe. Wartość wyrażenia warunkowego musi być zaini-
cjalizowana przed wejściem do pętli oraz określana w ciele pętli. Wyjście z pętli następuje,
gdy wyrażenie warunkowe sprawdzane na jej końcu jest prawdziwe.

W pętli

repeat

instrukcje stanowiące ciało pętli będą wykonane co naj-

mniej raz, niezależnie od wartości wyrażenia warunkowego. W pętli

while

wyrażenie warunkowe obliczane jest na początku, więc ciało pętli może
nigdy nie być wykonane.

Instrukcja goto

Instrukcja

goto

umożliwia skok wprost do umieszczonej w kodzie programu etykiety

zadeklarowanej uprzednio dyrektywą

Label

(nie mylić z komponentem

TLabel

– przyp.

red.) , a tym samym wykonanie pierwszej następującej po niej instrukcji. Ilustruje to
poniższy przykład:

procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
label
Petelka;
begin
Memo1.Clear;
I := 0;
Petelka:
Inc(I);
Memo1.Lines.Add(IntToStr(I));
if I < 5 then
goto Petelka;
end;

background image

76

Część I

76

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Nie jest tutaj konieczne użycie pary

begin

i

end

, ponieważ wykonywane będą po prostu

wszystkie linie kodu pomiędzy etykietą a instrukcją

goto

.

Stosowanie instrukcji

goto

w Object Pascalu jest uważane za zły zwyczaj.

Poza tym nie jest konieczne. Wszystko to, co można zrobić za pomocą in-
strukcji

goto

, można równie dobrze osiągnąć stosując pętle

while

albo

re-

peat

.

2

Składnia

label
nazwa_etykiety;

goto nazwa_etykiety;
...
nazwa_etykiety;

Po napotkaniu instrukcji

goto

następuje skok do miejsca programu oznaczonego etykietą.

2

Redakcja wydania polskiego nie podziela w pełni tego kategorycznego stwierdzenia. Fakt, iż użycie

instrukcji goto stwarza znakomitą okazję do zagmatwania programu nie oznacza jeszcze, iż każde

jej użycie czyni program zagmatwanym – ba, niekiedy program (paradoksalnie) zyskuje na czytelno-
ści. Tak się bowiem składa, że Object Pascal posiada np. znakomite mechanizmy natychmiastowego
„wyskoczenia” z pętli (break) lub procedury (exit), nie ma natomiast równoważnego mecha-
nizmu umożliwiającego wyskok z bloku begin…end – i wtedy użycie goto jest niezbędne, na

przykład:

X := 1; Y := 2;
BlokKompletny := FALSE;
Begin
...
if LiczbaBledow > 0
Then
Goto PozaBlok;
...
if BladFatalny
Then
Goto PozaBlok;
...
End;

BlokKompletny := TRUE;

PozaBlok:
If BlokKompletny Then
begin
X := X / 3; Y := Y + 1;
End
Else
Begin
X := 0; Y := 0;
End;

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

77

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

77

Procedury Continue i Break

Zanim zakończymy temat pętli, powinieneś jeszcze poznać dwie procedury, które czę-
sto stosowane są w połączeniu z nimi. Procedura

Continue

umieszczona gdziekolwiek

w ciele pętli powoduje natychmiastowy skok do punktu stopu. Przykład:

var
Zrobione : Boolean;
Wstrzymaj : Boolean;
begin
Zrobione := False;
while not Zrobione do begin
...
Wstrzymaj := SprawdzStan;
if Wstrzymaj then Continue;

{skok do punktu stopu petli}

{tutaj kod wykonywany, gdy Wstrzymaj = False}
end;
end;

Procedura

Break

jest używana do natychmiastowego i całkowitego zatrzymania pętli

(wyjścia z niej). Na przykład, szukasz jakiejś określonej liczby w tablicy liczb przeszukując
ją w pętli. W przypadku znalezienia tej liczby, można przerwać poszukiwania zapa-
miętując jednocześnie indeks tej liczby w tablicy:

var
Tablica

: array[0.99] of Integer;

Indeks

: Integer;

PoszukiwanaLiczba : Integer;
I

: Integer;

begin
WypelnijTablice;

{wypełnienie tablicy wartościami}

Indeks := -1;
PoszukiwanaLiczba := 50;
for I := to High(Tablica) do begin
if Tablica[I] = PoszukiwanaLiczba then begin
Indeks := I;
Break;
end;
end;
if Indeks <> -1 then
Label1.Caption := 'Poszukiwaną liczbę znaleziono pod indeksem '
∑+ IntToStr(Indeks)
else
Label1.Caption := 'Poszukiwanej liczby nie ma w tablicy.';
end;

Procedur

Continue

i

Break

używa się tylko wewnątrz pętli

for

,

repeat

albo

while

. Jeżeli

spróbujesz użyć tych procedur gdziekolwiek indziej, kompilator wypisze komunikat

BREAK or CONTINUE outside of loop

”.

background image

78

Część I

78

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Instrukcja case

Instrukcję

case

można traktować jak rozbudowaną instrukcję

if

. Pozwala ona na wy-

konanie jednego z wielu bloków kodu bazując na wyniku określonego wyrażenia, funkcji
czy zmiennej. Wynik ten musi być typu porządkowego (

Integer

,

Word

,

Byte

itd.), nie

może to być łańcuch ani liczba zmiennoprzecinkowa. Oto przykład:

case PrzekroczeniePredkosci of
0 : Mandat := 0;
5 : Mandat := 50
10 : Mandat := 75;
15 : Mandat := 100;
20,
25,
30 : Mandat := PrzekroczeniePredkosci * 20;
else begin
Mandat := MaksymalnyMandat;
end;
end;

Wyrażeniem, na podstawie którego następuje wykonanie określonego fragmentu kodu,
jest w tym przypadku zmienna

PrzekroczeniePredkosci

. Jeżeli przyjmie ona wartość 0,

wykonana zostanie instrukcja

Mandat := 0

, gdy przyjmie wartość 5, wykonana zostanie

instrukcja

Mandat := 50

itd. Instrukcja ostatnia przed

else

wykona się, gdy

Przekrocze-

niePredkosci

będzie równe 20 albo 25 albo 30. Jeżeli natomiast zmienna ta będzie miała

wartość, której nie ma na liście, wykona się instrukcja

Mandat := MaksymalnyMandat

.

Część

else

instrukcji

case

jest opcjonalna. Oto przykład instrukcji

case

, w której nie

ma słowa

else

:

case X of
10 : PierwszaProcedura;
20 : DrugaProcedura;
30 : TrzeciaProcedura;
end;

Składnia

case wyrazenie of
wartosc1 : instrukcje_1;
wartosc2 : instrukcje_2;
...
wartoscn : instrukcje_n;
else
instrukcje_w_innym_przypadku;
end;

Instrukcja

case

pozwala na wykonanie różnych fragmentów kodu w zależności od

wartości wyrażenia

wyrazenie

. Jeżeli

wyrazenie

będzie równe

wartosc1

, wykonane

będą

instrukcje_1

, jeżeli

wyrazenie

będzie równe

wartosc2

, wykonane będą

in-

strukcje_2

, itd. Jeżeli

wyrazenie

nie będzie miało żadnej z wymienionych wartości,

zostaną wykonane

instrukcje_w_innym_przypadku

. Część

else

jest opcjonalna.

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

79

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

79

Zakres widzialności

Termin „zakres widzialności” odnosi się do nazw zmiennych i określa, w jakich czę-
ściach programu można odwoływać się do danej zmiennej. Większość zmiennych są to
tzw. „zmienne lokalne” tzn. takie, do których odwoływać się można tylko w tym bloku
kodu, w którym zostały zadeklarowane. Spójrz na listing 2.1 (jest to kompletny kod
źródłowy modułu wygenerowanego przez Delphi, te elementy, które nie były jeszcze
omawiane, możesz zignorować).

Listing 2.1. SCOPEU.PAS

unit ScopeU;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

var
X : Integer;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;

procedure Test;
var
X : Integer;
begin
X := 300;
{ This X variable has a value of 300. }
Memo1.Lines.Add('Local Function X: ' + IntToStr(X));
end;

begin
X := 100;
Memo1.Lines.Clear;
{ Local X has a value of 100. }

background image

80

Część I

80

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Memo1.Lines.Add('Local X: ' + IntToStr(X));
{ Unit scope X has a value of 200. }
Memo1.Lines.Add('Global X: ' + IntToStr(ScopeU.X));
{ Call the Test proecedure. }
Test;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
{ Initialize the unit variable X. }
X := 200;
end;
end.

Pierwszą rzeczą, która się rzuca w oczy jest to, że zmienna X jest deklarowana w sumie
3 razy: w linii 27. w sekcji

implementation

, w linii 33. w metodzie

Button1Click

oraz

w linii 37. w procedurze lokalnej

Test

. Normalnie, jeżeli zadeklaruje się omyłkowo ja-

kąś zmienną więcej niż jeden raz, kompilator wyrzuca błąd

Identifier redeclared:

'X'

i kompilacja jest przerywana. Ten program jednak kompiluje się i uruchamia bez

żadnych problemów. Dlaczego? Ponieważ każda ze zmiennych X z listingu 2.1 ma inny
zakres widzialności.

Przyjrzyjmy się dokładniej listingowi 2.1. Deklaracja zmiennej X w linii 37. umieszczona
jest wewnątrz procedury

Test

i jest to zmienna lokalna tej procedury (wybiegam w tym

momencie trochę w przyszłość, ponieważ funkcje lokalne omówione będą dopiero
w rozdziale „Procedury i funkcje lokalne”). Zmienna X zadeklarowana w linii 37. wła-
ściwie nie istnieje poza procedurą

Test

. Podobnie, zmienna X zadeklarowana w linii 33. jest

lokalna dla procedury

Button1Click

i poza nią nie istnieje.

Spójrzmy teraz na zmienną

X

zadeklarowaną w sekcji

implementation

. Ta zmienna

widzialna jest w każdym miejscu modułu. Nasuwa się w tym momencie pytanie:

W procedurze

Button1Click

są w takim razie dwie zmienne

X

: jedna z linii 27. i druga

z linii 33, która jest używana, skoro obie są widzialne? Odpowiedź brzmi: ta z linii 33.

(zmienna lokalna procedury

Button1Click

). Druga, zmienna

X

widzialna w całym module,

jest w tym momencie przykryta. Można się do niej jednak odwołać podając kwalifikator

zakresu. Przykład takiego odwołania jest w linii 50:

Memo1.Lines.Add('Zmienna X widzialna w całym module: '
∑+ IntToStr(ScopeU.X));

Zapis

ScopeU.X

oznacza, że chodzi tu o zmienną

X

widzialną w całym module

ScopeU

, a nie

o zmienną lokalną o tej samej nazwie.

Jak już wcześniej wspominałem, deklarując zmienną w sekcji

implementation

, czyni

się ją widzialną w całym module. Jeżeli chcesz, żeby jakaś zmienna była widoczna

również w innych modułach projektu, musisz zadeklarować tę zmienną w sekcji

interface

(zmienna

Form1

na listingu 2.1 zadeklarowana jest w ten sposób). Do zmiennej takiej

można odwoływać się w innych modułach. Nazywane są one zmiennymi globalnymi.

Aby odwołać się do zmiennej zadeklarowanej w sekcji

interface

innego modułu

wystarczy jedynie dodać ten moduł do listy

uses

bieżącego modułu i można używać

nazwy tej zmiennej, jakby była ona zadeklarowana lokalnie (ewentualnie z użyciem

kwalifikatora zakresu, gdyby oprócz zmiennej globalnej istniałaby zmienna lokalna o tej

samej nazwie).

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

81

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

81

Zmienne deklarowane w sekcji

interface

nie są tak do końca zmiennymi

globalnymi. Prawdziwa zmienna globalna powinna być widoczna w całym
projekcie bez konieczności umieszczania deklarującego ją modułu na liście

uses

. W Delphi istnieje kilka prawdziwych zmiennych globalnych inicjali-

zowanych przez kompilator. Użytkownik nie może jednak sam tworzyć ta-
kich zmiennych.

Rekordy

Rekord jest zestawem powiązanych zwykle ze sobą danych „opakowanych” w jedną
całość. Powiedzmy, że chcesz przechowywać dane o nazwiskach i adresach osób. Wygod-
nie byłoby w tym przypadku wyodrębnić jakąś strukturę, w której dałoby się umieścić
wszystkie dane (imię, nazwisko, ulica, miasto). Rekordy są właśnie stworzone do takich
celów. Aby użyć rekordu, należy najpierw stworzyć nowy typ danej (rekord) o potrzeb-
nej strukturze, następnie należy zadeklarować zmienną typu „rekordowego”, do której
można już wpisywać dane. Rekord deklaruje się za pomocą słowa kluczowego

record

:

type
TKartaAdresowa = record
Imie : string;
Nazwisko : string;
Ulica : string;
Miasto : string;
KodPocztowy : Integer;
end;

Każdy element rekordu nazywany jest polem. Poszczególne pola muszą być deklarowa-
ne jak zmienne. W powyższym przykładzie w skład rekordu wchodzi 5 pól typu

string

oraz jedno pole typu

Integer

(kod pocztowy powinien być właściwie także typu

string

, ale dla celów edukacyjnych lepiej zadeklarować rekord o polach różnych typów).

Rekord jest zbiorem powiązanych ze sobą danych zgrupowanych w jednej
strukturze. Po zadeklarowaniu typu rekordowego trzeba zadeklarować
zmienną tego typu, aby móc umieszczać w niej dane. Składniki rekordu na-
zywane są polami.

Rekord z powyższego przykładu nadaje się dobrze do tego, o czym tu pi-
szę, lecz nie jest najlepszy, jeżeli chodzi o zapisywanie rekordów do pliku
dyskowego. Każdy rekord zapisywany w pliku musi mieć stałą długość w
bajtach. Ponieważ używane są tu długie łańcuchy, nie ma żadnej gwarancji,
że każdy rekord tego typu będzie miał taki sam rozmiar. Przy tworzeniu re-
kordów, które mają być zapisywane do pliku, lepiej użyć łańcuchów

shor-

tstring

lub nawet tablic znaków. Operacje na plikach omówię szczegóło-

wo w następnym rozdziale.

background image

82

Część I

82

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Teraz, kiedy rekord mamy już zadeklarowany, trzeba zadeklarować zmienną, aby móc
z tego rekordu korzystać:

var
Karta001 : TKartaAdresowa;

Powyższa deklaracja przydziela pamięć dla zmiennej

Karta001

typu

TKartaAdresowa

.

Przypisanie wartości polom tej zmiennej wygląda następująco:

Karta001.Imie

:= 'Jan';

Karta001.Nazwisko

:= 'Kowalski';

Karta001.Ulica

:= 'Klonowa';

Karta001.Miasto :=

'Białystok';

Karta001.KodPocztowy

:= 15113;

Jak widać, do poszczególnych pól można się odwoływać stosując notację kropkową
(kwalifikowaną) – po nazwie zmiennej następuje kropka i nazwa pola. Umożliwia to za-
równo wpisywanie, jak i odczyt danych:

Label1.Caption := Karta001.Nazwisko;

Składnia

nazwa = record
pole_1 : typ;
pole_2 : typ;
...
pole_n : typ;
end;

Słowo kluczowe

record

deklaruje zbiór pól (

pole_1

,

pole_2

, ...,

pole_n

) i nadaje mu

nazwę (

nazwa

).

Instrukcja with

Instrukcja

with

, aczkolwiek nie tylko ona, jest często stosowana w połączeniu z rekor-

dami. Przytoczę tutaj poprzedni przykład, w którym następowało wypełnienie rekordu

Karta001

wartościami:

Karta001.Imie

:= 'Jan';

Karta001.Nazwisko

:= 'Kowalski';

Karta001.Ulica

:= 'Klonowa';

Karta001.Miasto :=

'Białystok';

Karta001.KodPocztowy

:= 15113;

Słowo kluczowe

with

może być w tym przypadku użyte w celu uproszczenia zapisu:

with Karta001 do begin
Imie

:= 'Jan';

Nazwisko

:= 'Kowalski';

Ulica

:= 'Klonowa';

Miasto

:= 'Białystok';

KodPocztowy

:= 15113;

end;

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

83

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

83

Słowo

with

znaczy „Zrób z tym obiektem (

Karta001

) następującą rzecz…”. Dzięki

niemu nie trzeba stosować zapisu kwalifikowanego. Wszystko pomiędzy słowami

begin

i

end

odnosi się do obiektu

Karta001

. Oszczędza to sporo pisania, oprócz tego kod staje

się znacznie czytelniejszy.

Tablice rekordów

Podobnie jak zmienne typu

Integer

,

Char

czy

Word

, rekordy można także grupować

w tablice. Przy tym deklarowanie i używanie tablic rekordów nie jest tak bardzo skom-

plikowane:

var
TablicaKart : array[0..9] of TKartaAdresowa;
begin
TablicaKart[0].Imie

:= 'Jan';

TablicaKart[0].Nazwisko

:= 'Kowalski';

TablicaKart[0].Ulica

:= 'Klonowa';

TablicaKart[0].Miasto

:= 'Białystok';

TablicaKart[0].KodPocztowy

:= 15425;

TablicaKart[1].Imie

:= 'Roman';

TablicaKart[1].Nazwisko

:= 'Kaleta';

TablicaKart[1].Ulica

:= 'Storczykowa';

TablicaKart[1].Miasto

:= 'Sopot';

TablicaKart[1].KodPocztowy

:= 81855;

Label1.Caption

:= TablicaKart[0].Nazwisko;

...
end;

Pliki dołączane

Pliki dołączane są to pliki tekstowe zawierające kod źródłowy, które w czasie kompilacji

traktowane są przez kompilator jak część pliku, do którego zostały dołączone. Zwykle

umieszcza się w plikach dołączanych deklaracje stałych albo dyrektywy kompilatora,

które mają być użyte w wielu plikach projektu lub wielu projektów, i których po prostu nie

opłaca się przepisywać za każdym razem. Pliki dołączane mają zwyczajowo rozszerzenie

.INC

. Na listingu 2.2 przedstawiony jest przykładowy plik dołączany:

Listing 2.2. TEST.INC

const
DomyslnaSzerokosc = 500;
DomyslnaWysokosc

= 300;

type
KartaAdresowa = record
Imie : string;
Nazwisko : string;
Ulica : string;
Miasto : string;
KodPocztowy : Integer;
end;

background image

84

Część I

84

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Aby utworzyć plik dołączany, trzeba po prostu otworzyć nowy plik tekstowy i zapisać
go z rozszerzeniem

INC

. Najpierw wybierz opcję

File | New

z menu. Następnie kliknij

podwójnie ikonę „Text”. W Edytorze Kodu otworzy się nowy, pusty plik tekstowy.
Wpisz kod, który chcesz umieścić w pliku dołączanym i wybierz z menu

File | Save

As

. Podaj nazwę pliku z rozszerzeniem

.INC

(nie zapomnij o tym, gdyż standardowo

pliki tekstowe zapisywane są z rozszerzeniem

.TXT

).

Dołączanie pliku

.INC

do pliku głównego polega na wpisaniu w pliku głównym w miejscu

dołączenia dyrektywy kompilatora

$I

:

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls;

{$I TEST.INC}
...

Rezultat jest taki, jakby plik

.INC

wklejono w tym miejscu do pliku głównego. Oczywiście

kod w pliku dołączanym musi być składniowo poprawny, inaczej przy kompilacji wy-
stąpią błędy.

Funkcje, procedury i metody

Funkcje i procedury to wydzielone bloki kodu wykonujące jakieś określone zadania.
Programy pisze się z reguły po to, żeby przy ich pomocy rozwiązać jakiś skomplikowany
i rozbudowany problem (np. wspomaganie sprzedaży w sklepie). Aby ułatwić sobie
rozwiązanie tego problemu, dzieli się go na mniejsze problemy cząstkowe (np. wyko-
nanie dziennego zestawienia sprzedaży). Każdy taki problem cząstkowy rozwiązuje
określona procedura albo funkcja. Problemy mogą być najróżniejsze. Na przykład mogą
być funkcje, które pobierają dwie liczby, wykonują na nich jakieś skomplikowane ope-
racje matematyczne i zwracają wynik – albo funkcje, które przetwarzają łańcuchy.
Można tych funkcji używać (wywoływać je) w dowolnym miejscu programu.

Funkcje i procedury bardziej ogólnie nazywa się podprogramami. Podprogramy są bardzo
ważną częścią każdego języka programowania – Object Pascal nie jest tu wyjątkiem.
Najprostszy rodzaj podprogramu nie pobiera żadnych danych wejściowych (parametrów)
oraz nie zwraca żadnego wyniku. Inne podprogramy mogą wymagać jednego lub więcej
parametrów i mogą też zwracać jakieś wyniki. Reguły nazewnictwa funkcji i procedur
są takie same jak dla zmiennych.

Funkcja jest to wydzielony blok kodu, który wykonuje określoną czynność i
zwraca wynik.

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

85

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

85

Parametr jest wartością przekazywaną do funkcji albo procedury, który
modyfikuje lub określa zakres jej działania.

Rysunek 2.2.
Budowa funkcji

Procedura jest to wydzielony blok kodu, który wykonuje określoną czyn-
ność, lecz nie zwraca wyniku.

Rysunek 2.3.
Budowa procedury

Metoda jest to procedura lub funkcja, która jest składnikiem klasy.

Jak widać z powyższych definicji, jedyną różnicą między funkcją a procedurą jest to,
że funkcja zwraca jakiś wynik, a procedura nie.

Napiszmy teraz przykładowy program, który będzie wykorzystywał funkcję:

1.

Utwórz nową aplikację.

2.

Umieść na formularzu po jednym komponencie

Label

i

Button

.

background image

86

Część I

86

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

3.

Kliknij podwójnie na umieszczonym właśnie przycisku, żeby utworzyć dla

niego procedurę obsługi zdarzenia

OnClick

.

4.

Używając klawisza ze strzałką skierowaną do góry przesuń kursor w Edytorze

Kodu powyżej utworzonej przed momentem procedury.

5.

Wpisz do tekstu programu następującą funkcję:

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer;
begin
Result := Liczba1 * Liczba2;
end;

Plik źródłowy modułu w Edytorze Kodu powinien teraz wyglądać jak na rysunku 2.4.

Rysunek 2.4.
Edytor Kodu
z wyświetloną
funkcją Mnozenie

6.

Przesuń kursor z powrotem do procedury

TForm1.Button1Click

i zmodyfikuj

ją tak, żeby zawierała następujący kod:

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;
begin
X := Mnozenie(10, 20);
Label1.Caption := IntToStr(X);
end;

Uruchom teraz program i naciśnij przycisk. Etykieta powinna teraz zawierać liczbę 200.

Program działa w następujący sposób: Po naciśnięciu przycisku wywoływana jest procedura

obsługi zdarzenia

OnClick

tego przycisku. Ta procedura z kolei wywołuje funkcję

Mnozenie

przekazując do niej dwa parametry – liczby 10 i 20. Wynik zwrócony przez funkcję

Mnozenie

zapamiętywany jest w zmiennej X, która z kolei wyświetlana jest na ekranie.

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

87

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

87

Przykład ten ilustruje stosowanie samodzielnych funkcji w programie Del-
phi. Normalnie, uczyniłbym tę funkcję składnikiem klasy formularza, jed-
nak ponieważ nie omawiałem jeszcze klas, nie chcę teraz za bardzo kom-
plikować przykładu.

Mogłeś analizując ten przykład pomyśleć: „No dobrze, ale skąd funkcja ma wiedzieć,
którą zmienną ma zwrócić jako swój wynik?” Przyjrzyjmy się jeszcze raz funkcji

Mnozenie

:

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer;
begin
Result := Liczba1 * Liczba2;
end;

Każda funkcja w Object Pascalu ma predefiniowaną zmienną lokalną o nazwie

Result

.

Używana jest ona właśnie do przechowywania wyniku zwracanego przez tę funkcję.
Wystarczy więc przypisać zmiennej

Result

wartość, którą funkcja ma zwrócić jako

wynik.

Jest oprócz tego drugi sposób przypisywania wartości wynikowi funkcji.
Zamiast zmiennej

Result

używa się po prostu nazwy funkcji:

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer;

begin

Mnozenie := Liczba1 * liczba2;

end;

Wersję tę często spotyka się w starszych wersjach Pascala i w programach
przeniesionych do Delphi z Turbo Pascala (jednego z poprzedników Delphi).

Funkcję

Mnozenie

można wywoływać na kilka sposobów. Jako parametry można prze-

kazywać do niej zmienne, wartości podane wprost lub nawet wyniki wywołań innych
funkcji. Na przykład:

X := Mnozenie(2, 5); {przekazywanie wartości podanych wprost}
X := Mnozenie(A, B); {przekazywanie zmiennych}
Label1.Caption := IntToStr(Mnozenie(X, Y));
{wynik funkcji użyty jako parametr innej funkcji}
Mnozenie(X, Y);

{zignorowanie wyniku funkcji}

W ostatniej linii, przy wywołaniu funkcji

Mnozenie

, wartość przez nią zwracana jest

ignorowana. Nie ma to w tym przypadku większego sensu, jednak pomijanie wyniku
funkcji jest często stosowaną praktyką w programowaniu. Spotyka się wiele funkcji,
które po wykonaniu określonej akcji zwracają jako wynik status tego wywołania (np.
informację, czy akcja się powiodła). Jeżeli ta informacja nie jest Ci do niczego potrzeb-
na, możesz ją po prostu zignorować.

background image

88

Część I

88

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Dodajmy teraz do naszego programu przykładowego procedurę:

1.

Kliknij podwójnie na przycisku umieszczonym na formularzu. W Edytorze
Kodu wyświetlona będzie procedura

TForm1.Button1Click

.

2.

Przesuń kursor do góry o kilka linii tak, aby znajdował się on między procedurami

Mnozenie

i

TForm1.Button1Click

. Wpisz następujący kod:

procedure Powitanie;

begin
MessageDlg('Witaj!', mtInformation, [mbOk], 0);
end;

3.

Dodaj linię kodu na końcu procedury obsługi zdarzenia

OnClick

komponentu

Button

tak, aby wyglądała ona następująco:

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;
begin
X := Mnozenie(10, 20);
Label1.Caption := IntToStr(X);
Powitanie;
end;

Teraz uruchom program ponownie. Tym razem, oprócz wyniku mnożenia wyświetlone-
go na etykiecie, pokaże się okienko informacyjne. Wyświetlenie okienka jest skutkiem
wywołania procedury

Powitanie

. Wywołanie to jest bardzo proste, ponieważ procedura

ta nie wymaga żadnych parametrów. Ważne jest tu zrozumienie tego, że kod umieszczony
w procedurze

Powitanie

wykonywany jest tylko wtedy, gdy wprost wywoła się tę pro-

cedurę.

Za każdym razem, kiedy zajdzie potrzeba powtórzenia jakiejś partii kodu
kilka lub więcej razy, rozważ umieszczenie jej w podprogramie. Będziesz
mógł wtedy wywoływać po prostu ten podprogram.

Podprogramy mogą (i często to robią) wywoływać inne podprogramy. Mogą one nawet
wywoływać same siebie. Wywoływanie samych siebie przez podprogramy nazywane
jest rekurencją i stosowane jest raczej w uzasadnionych przypadkach przez doświad-
czonych programistów.

Rekurencją nazywa się wywoływanie przez procedurę lub funkcję samych
siebie.

Deklaracja i definicja

Funkcje i procedury często posiadają deklarację, zawsze natomiast posiadają definicję.

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

89

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

89

Deklaracja jest pojedynczą instrukcją, która opisuje nazwę i parametry (je-
żeli występują) podprogramu. W przypadku funkcji deklaracja opisuje
również typ zwracanego przez nią wyniku.

Definicja procedury albo funkcji zawiera właściwą treść tej procedury albo
funkcji i umieszczona jest w sekcji

implementation

modułu.

Oto trzy główne przypadki, kiedy konieczne jest deklarowanie funkcji albo procedury:

υ

Gdy funkcja albo procedura ma być używana w innych modułach.

υ

Gdy definicja tej funkcji albo procedury znajduje się poniżej miejsca w pliku
źródłowym, w którym dana funkcja albo procedura jest wywoływana.

υ

Gdy funkcja albo procedura jest składnikiem klasy.

Do tej pory w tej książce nie używałem deklaracji funkcji i procedur, jedynie definicje.
Nie wystąpiła dotąd taka potrzeba – definicje te zawsze poprzedzały wywołanie. Deklaracja
funkcji

Mnozenie

wyglądałaby następująco:

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer;

Deklaracje funkcji i procedur umieszczane są w sekcji

interface

. Umożliwia do wy-

woływanie ich także w innych modułach. Są one publiczne. Jeżeli nie chcesz, żeby jakaś
funkcja lub procedura była publiczna, nie umieszczaj jej deklaracji w sekcji

interface

.

Zamiast tego umieść jej definicję w sekcji

implementation

na samym początku tak, żeby

była widoczna w jak największej części modułu. Mimo, że do tej pory nie stosowałem
deklaracji, mógłbym to robić w następujący sposób:

unit Unit1;

interface

...

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer; {deklaracja}

implementation

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;
begin
X := Mnozenie(10, 20);
end;

function Mnozenie(Liczba1, Liczba2 : Integer) : Integer;
begin
Result := Liczba1 * Liczba2;
end;

end.

background image

90

Część I

90

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

W tym przypadku deklaracja funkcji

Mnozenie

jest konieczna, ponieważ jej definicja

jest poniżej procedury

Button1Click

, w której następuje jej wywołanie.

Jeżeli zadeklarujesz funkcję i zapomnisz ją potem zdefiniować, kompilator
wypisze komunikat o błędzie

Unsatisfied forward or external

declaration: 'Mnozenie'

.

Parametry przekazywane przez stałą, przez wartość
i przez referencję

Istnieją trzy sposoby przekazywania parametrów do procedur i funkcji (tak naprawdę więcej
niż trzy, ale tutaj tylko te będę omawiał): przez stałą, przez wartość i przez referencję.

Parametry przekazywane przez wartość

Wszystkie parametry, których używałeś do tej pory pracując z tą książką, były to parametry
przekazywane przez wartość. Parametry takie można porównać do zmiennych lokal-
nych w procedurze lub funkcji – można je modyfikować, lecz zmienna globalna o tej
samej nazwie pozostanie niezmieniona. Tak samo modyfikacja parametru przekazanego
do funkcji przez wartość nie zmienia oryginalnej zmiennej. Stwórzmy nową funkcję,
która będzie ilustrowała to zagadnienie. Nazwiemy ją

MnozenieKwadratow

. Będzie ona

podnosić do kwadratu dwie przekazane do niej liczby i mnożyć te kwadraty:

function MnozenieKwadratow(Liczba1, Liczba2 : Integer) : Integer;
begin
Liczba1 := Liczba1 * Liczba1;
Liczba2 := Liczba2 * Liczba2;
Result := Liczba1 * Liczba2;
end;

Wywołajmy teraz tę funkcję w następujący sposób:

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;
Y : Integer;
Z : Integer;
begin
X := 2;
Y := 3;
Z := MnozenieKwadratow(X, Y);
Label1.Caption := 'X = ' + IntToStr(X) + 'Y = ' + IntToStr(Y) + 'Z = '
∑ + IntToStr(Z);
end;

Do funkcji

MnozenieKwadratow

przekazywane są wartości dwóch zmiennych (

X

i

Y

). Są

one modyfikowane wewnątrz funkcji (podnoszone do kwadratu). Oryginalne zmienne
jednak pozostają niezmienione, ponieważ do funkcji przekazywane są ich kopie.

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

91

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

91

Parametry przekazywane przez stałą

Innym sposobem na przekazywanie danych wejściowych do funkcji jest ich przekazanie
przez stała. Wartości tych parametrów nie mogą być zmieniane wewnątrz funkcji. Oto
przykład:

procedure PowiedzCos(const S : string);
begin
S := S + 'Test';
ShowMessage(S);
end;

To jest jeden z kilku przykładów kodu w tej książce, przy próbie kompilacji którego
wystąpi błąd. Odnosić się on będzie do pierwszej linii procedury i będzie brzmiał

Left

side cannot be assigned to

. Błąd ten będzie generowany, ponieważ słowo

const

znajdujące się przed parametrem oznacza, że nie może on być modyfikowany w ciele
procedury. Jeżeli chcesz zabezpieczyć jakieś parametry przekazywane do procedury lub
funkcji przed modyfikacją, to jest właśnie sposób na to.

3

Parametry przekazywane przez referencję

Przy przekazywaniu parametrów przez referencję

4

, kompilator nie robi ich kopii ani

w żaden inny sposób nie zabezpiecza tych parametrów przed modyfikacją wewnątrz
procedury. Referencja jest to po prostu odwołanie do jakiejś zmiennej. Znaczy to, że
wszelkie modyfikacje wykonywane na parametrach są de facto modyfikacjami wyko-
nywanymi na oryginalnych zmiennych. Poniżej przedstawiony jest przykład takiego
przekazania:

procedure DoKwadratu(var Liczba: Integer);
begin
Liczba := Liczba * Liczba;
end;

procedure TForm.Button1Click(Sender: TObject);
var
X : Integer;
begin
X := 20;
DoKwadratu(X);
Label1.Caption := IntToStr(X);

{X równe jest teraz 400}

end;

3

Dociekliwy Czytelnik mógłby zapytać w tym miejscu, czym właściwie różni się przekazywanie

parametru przez wartość od przekazywania przez stałą? Obydwa te sposoby uniemożliwiają zmianę
wartości przekazanego parametru – co osiągane jest w dwojaki sposób: przy przekazywaniu przez
wartość tworzona jest ad hoc kopia robocza parametru, na której wykonywane są wszelkie modyfi-
kacje tego ostatniego, zaś przy przekazywaniu przez stałą kompilator zabrania dokonywania jakich-
kolwiek modyfikacji parametru, eliminując konieczność tworzenia owej kopii; z tego też względu
przekazanie przez stałą jest efektywniejsze zarówno pamięciowo (oszczędza się pamięć, nie tworząc
kopii) jak i czasowo (wykonanie kopii zajmuje bowiem pewną ilość czasu). (przyp. red.)

4

Przekazywanie parametru przez referencję nazywane bywa również przekazaniem „przez adres” lub

„przez zmienną” (przyp. red.).

background image

92

Część I

92

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Słówko

var

umieszczone przy parametrze oznacza, że jest on przekazywany przez refe-

rencję.

Wiele słów kluczowych w Object Pascalu ma kilka znaczeń. Słowo

var

na

przykład oznacza, że dany parametr przekazywany jest przez referencję.
Rozpoczyna też ono sekcję deklaracji zmiennych. Kompilator właściwie
interpretuje je za każdym razem wnioskując z kontekstu, w jakim się dane
słowo znajduje.

W procedurze

DoKwadratu

zmieniana jest wartość parametru

Liczba

. Tym samym wartość

zmiennej

X

, która jest przekazana do tej procedury, przed wywołaniem

DoKwadratu

wynosząca 20, po tym wywołaniu jest już inna (400).

Ponieważ parametr procedury

DoKwadratu

jest przekazywany przez referencję, musisz

w wywołaniu tej procedury użyć zmiennej takiego samego typu, jak parametr. Nie możesz
na przykład napisać:

DoKwadratu(30);

{Błąd przy kompilacji!}

Nie możesz też przekazać do tej procedury zmiennej innego typu niż typ parametru:

var
X : Word;
begin
X := 20;
DoKwadratu(X);

{Błąd przy kompilacji!}

Komunikat kompilatora wygenerowany przy próbie kompilacji powyższego kodu będzie
brzmiał

Types of actual and formal var parameters must be identical

.

Formalnie funkcja może zwracać tylko jedną wartość. Parametry przeka-
zywane przez referencję to sposób na obejście tego ograniczenia. Jeżeli
funkcja może je modyfikować (może ich być dowolnie dużo), można
uznać, że może zwracać w ten sposób wiele wartości.

Funkcje i procedury lokalne

Funkcje i procedury lokalne zawierają się w innych funkcjach lub procedurach. Na
przykład:

procedure TForm1.Button1Click(Sender: TObject);
var
X : Integer;

{procedura lokalna:}
procedure Test;
begin
Memo1.Lines.Add('Procedura lokalna, X = ' + IntToStr(X));
end;

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

93

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

93

begin
X := 100;
Memo1.Lines.Clear;
Memo1.Lines.Add('Procedura główna, X = ' + IntToStr(X));
Test;
end;

Procedura

Test

zawarta jest w sekcji

var

procedury

Button1Click

. Procedury takie nazy-

wają się procedurami lokalnymi podprogramu, w którym są zawarte. Mogą być one
wywołane tylko z poziomu zawierającego je podprogramu, nie są widoczne nigdzie indziej.

Ważną cechą charakteryzującą funkcje i procedury lokalne jest to, że widoczne są w niej
zmienne lokalne otaczającego je podprogramu. W powyższym przykładzie, zmienna

X

zadeklarowana jako zmienna lokalna procedury

Button1Click

, widoczna jest w procedurze

Button1Click

oraz w procedurze Test. Po uruchomieniu tego programu w komponen-

cie

Memo

widoczny będzie tekst:

Procedura główna, X = 100
Procedura lokalna, X = 100

Przeciążanie funkcji i procedur

Począwszy od wersji czwartej Delphi, Object Pascal pozwala na deklarowanie dwóch
lub więcej funkcji i procedur (metod) o tych samych nazwach, lecz o różnych parametrach
(w tym samym zakresie widzialności).

Przeciążanie metod jest to deklarowanie dwóch lub więcej funkcji albo pro-
cedur o tych samych nazwach, ale o różniących się listach parametrów.

Metody o tych samych nazwach nazywa się metodami przeciążonymi.

Przedstawiałem wcześniej przykładowy program, który zawierał funkcję o nazwie

Mnozenie

. Funkcja ta pobierała dwie liczby typu

Integer

i zwracała ich iloczyn. Co

jednak byłoby, gdyby trzeba było mnożyć także liczby typu

Double

albo

Word

? W po-

przednich wersjach Delphi konieczne było napisanie kilku funkcji o odpowiednich pa-

rametrach:

{deklaracje w programie napisanym w Delphi 1, 2 albo 3}
function MnozenieInt(Liczba1, Liczba2 : Integer) : Integer;
function MnozenieDouble(Liczba1, Liczba2 : Double) : Double;
function MnozenieWord(Liczba1, Liczba2 : Word) : Word;

Znacznie prostszym rozwiązaniem byłoby stworzenie jakiejś jednej uniwersalnej funkcji

Mnozenie

, która wiedziałaby, kiedy mnożyć liczby

Integer

, kiedy

Double

a kiedy

Word

.

W Delphi 4 jest to możliwe – właśnie dzięki przeciążaniu. Oto, jak deklaracje takiej

funkcji wyglądają w Delphi 4:

{deklaracje w programie napisanym w Delphi 4}
function Mnozenie(Liczba1, Liczba2 : Integer) : Integer; overload;
function Mnozenie(Liczba1, Liczba2 : Double) : Double; overload;
function Mnozenie(Liczba1, Liczba2 : Word) : Word; overload;

background image

94

Część I

94

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Nadal trzeba napisać oddzielne definicje dla każdej z wersji, ale używając tych funkcji

można już posługiwać się jedną nazwą. Kompilator troszczy się o wywołanie odpo-

wiedniej wersji w zależności od parametrów wywołania. Na przykład:

var
X, Y, Z : Double;
begin
X := 1.5;
Y := 10.5;
Z := Mnozenie(X, Y);
end;

Kompilator widząc, że do funkcji przekazywane są liczby typu

Double

wywołuje funkcję

Mnozenie

, która mnoży liczby typu

Double

. Analogicznie, jeżeli parametrami są liczby

typu

Integer

, kompilator wywołuje funkcję mnożącą liczby typu

Integer

.

Przeciążane funkcje rozróżniane są między sobą tylko i wyłącznie na pod-
stawie typu lub liczby parametrów, nie na podstawie typu wyniku. Nie
można deklarować dwóch funkcji o tych samych nazwach, takich samych
parametrach, różniących się jedynie typem wyniku:

function Funkcja01 : Integer; overload;
function Funkcja01 : Word; overload;

Przy próbie kompilacji programu z dwiema powyższymi liniami wystąpi błąd

Declaration of 'Funkcja01' differs from previous decla-
ration.

Parametry domyślne procedur i funkcji

Procedura lub funkcja może posiadać parametry domyślne, tzn. takie, które
w przypadku braku odpowiednich parametrów przy wywołaniu zastępują
je, przekazując przy tym określoną wartość.

Przykład funkcji posiadającej parametr domyślny przedstawiony jest poniżej:

{Deklaracja procedury}
{Parametr 'NajpierwWyczysc' ma domyślną wartość False}
procedure Przerysuj(NajpierwWyczysc : Boolean = False);
[Definicja procedury}
procedure Przerysuj(NajpierwWyczysc : Boolean);
begin
if NajpierwWyczysc then begin
{instrukcje czyszczące ekran}
end;
{instrukcje rysujące na nowo}
end;

Można tę funkcję wywoływać z parametrem lub bez parametru. Gdy wywołuje się ją

z parametrem, zachowuje się ona tak, jak zwyczajna funkcja. Gdy natomiast nie poda się

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

95

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

95

parametru podczas wywołania, funkcja przyjmie, że ten parametr podano i że ma on

wartość

False

. Dwie następujące linie kodu działają więc identycznie:

Przerysuj;
Przerysuj(False);

Deklarując funkcję można łączyć parametry domyślne ze zwykłymi:

{deklaracja}
function GrajPlikWave(Nazwa : string; WPetli : Boolean = False;
LiczbaPowtorzen : Integer = 10) : Integer;

[wywołania funkcji GrajPlikWave}
R := GrajPlikWave('chime.wav');

{pojedyncze odtworzenie}

R := GrajPlikWave('ding.wav', True);

{odtworzenie 10 razy}

R := GrajPlikWave('bell.wave', True, 5);

{odtworzenie 5 razy}

Parametry domyślne mogą zaoszczędzić czasem dużo pisania przy tworzeniu programu.
Jeżeli na przykład napisałeś funkcję, która w 99 % wywołań ma te same parametry,
możesz je uczynić domyślnymi. Jeżeli trzeba podać inne parametry – wystarczy je po
prostu wpisać.

Jeżeli w deklaracji funkcji występują jakieś parametry domyślne, muszą wy-
stąpić na końcu listy parametrów. Poniższa deklaracja nie jest prawidłowa:

procedure MojaProcedura(X : Integer; Y : Integer = 10; Z :
Integer);

Aby ta funkcja mogła się prawidłowo kompilować, należy parametr do-
myślny

Y

przesunąć na koniec listy:

procedure MojaProcedura(X : Integer; Z : Integer; Y :
Integer = 10);

Podsumowanie

Poznałeś w tym rozdziale podstawowe zagadnienia Object Pascala. Było to konieczne,
żeby móc w ogóle rozpocząć pisanie programów w Delphi. Na początku rozdziału zaj-
mowaliśmy się różnymi typami pętli, następnie omawiałem instrukcję

case

i jej stosowanie.

Następnym zagadnieniem był zakres widzialności zmiennych, potem omawiałem rekordy.
Ukoronowaniem rozdziału były funkcje i procedury.

Warsztat

Warsztat składa się z pytań kontrolnych oraz ćwiczeń utrwalających i pogłębiających
zdobytą wiedzę. W razie trudności lub wątpliwości, odpowiedzi do tych pytań zamiesz-
czone są w Dodatku A, „Quiz – odpowiedzi”.

background image

96

Część I

96

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

Pytania i odpowiedzi

υ

Jak głęboko można zagnieżdżać instrukcje

if

?

Formalnego ograniczenia nie ma. Zbyt skomplikowane konstrukcje jednak stają
się praktycznie nieczytelne i niemodyfikowalne.

υ

Czy pętle będą automatycznie kończyć swoje działanie, jeżeli coś pójdzie
nie tak?

Nie. Jeżeli program wpadnie w nieskończoną pętlę, jedynym sposobem na jej
przerwanie będzie zakończenie tego programu przez użytkownika z poziomu
Menadżera Zadań Windows lub poprzez wybranie opcji

Run | Program reset

z poziomu Delphi IDE.

υ

Czy w każdej instrukcji

case

musi być słowo

else

?

Nie, sekcja

else

jest opcjonalna.

υ

Czy w programie może istnieć więcej niż jedna zmienna o tej samej nazwie?

Tak, jeżeli będą one w różnych zakresach widzialności. Na przykład, można
zadeklarować zmienną globalną

X

i zmienną lokalną o tej samej nazwie.

υ

Jakie są korzyści z przeciążania procedur i funkcji?

Przeciążanie funkcji i procedur umożliwia deklarowanie kilku funkcji lub proce-
dur o tej samej nazwie, które wykonują te same operacje na parametrach różnych
typów. Na przykład można zadeklarować funkcję

RysujFigure

, której parametrem

raz może być odcinek, raz trójkąt, a raz koło. Unika się w ten sposób deklarowania
dużej liczby funkcji o różnych nazwach, przez co upraszcza się programowanie.

υ

Czy można używać typu rekordowego bez deklarowania zmiennych tego
typu?

Nie. Konieczne jest zadeklarowanie odpowiednich zmiennych, bez których
korzystanie z typów rekordowych nie jest możliwe.

Quiz

1.

Które instrukcje są wykonywane, jeżeli wyrażenie warunkowe w instrukcji

if

ma wartość

True

?

2.

Ile wyników może zwrócić funkcja?

3.

Jaka (oprócz składniowej) jest różnica między pętlą

while

i pętlą

repeat

?

4.

Jak działają procedury

Break

i

Continue

?

background image

Rozdzia³ 2.

Pascal bardziej zaawansowany

97

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc

97

5.

Co to jest zmienna globalna?

6.

Czy rekord może zawierać w sobie dane różnych typów (

Char

,

Integer

,

Word

itd.)?

7.

Jak można odwoływać się do pól rekordu?

8.

Ile może być w programie funkcji i procedur?

9.

Czy funkcja może wywołać inną funkcję lub procedurę?

10.

Czy rekordy można umieszczać w tablicach?

Ćwiczenia

1.

Napisz procedurę o nazwie

Test2

, która zmienia właściwość

Caption

kompo-

nentu

Label

. Umieść na formularzu przycisk, po naciśnięciu którego nastąpi

wywołanie procedury

Test2

.

2.

Dodaj do programu z ćwiczenia 1 procedurę

Test1

, która wywołuje procedurę

Test2

. Zmień procedurę obsługi zdarzenia

OnClick

komponentu

Button

tak,

żeby wywoływała ona procedurę

Test1

zamiast

Test2

.

3.

Napisz program wyświetlający w komponencie

Memo

20 razy tekst „Będę od

dzisiaj słuchał się mamy”.

4.

Stwórz rekord zawierający następujące dane o pracownikach: imię, nazwisko,
adres, data zatrudnienia oraz pole zawierające informację, czy dany pracownik
jest ubezpieczony.

background image

98

Część I

98

C:\WINDOWS\Pulpit\Szymon\Delphi 4 dla każdego\02.doc


Wyszukiwarka

Podobne podstrony:
Antropomotoryka Cwiczenia 02 id Nieznany
02 2QMAPTGVE5AGVK2QM43SM7VNCVHJ Nieznany
lo orm2 07 02 kp2 Nieznany
02 2F47ILFT5JEZPY2XIPPKNQGZJ2GD Nieznany (2)
03 rozdzial 02 6kylu3jjthukhcr6 Nieznany (2)
02 rozdzial 02 HW2MVOKVETQBVU24 Nieznany
03 rozdzial 02 tsah3llvybcbrfik Nieznany (2)
Egzamin Michlowicz 10 02 2012 i Nieznany
713[05] Z2 02 Przygotowywanie z Nieznany (2)
Organizacja i zarzadzanie 02 id Nieznany
Materialy do wykladu 5 (02 11 2 Nieznany
Fizykoterapia Cwiczenia 02 id 1 Nieznany
Podstawy automatyki 08 02 2015 Nieznany
polityka informacyjna 4 02 2014 Nieznany
Neurofizjologia Cwiczenia 02 id Nieznany
Egzaminy szkolenia 08 02 2012 i Nieznany
1 Sieci komputerowe 23 02 2013 Nieznany
Antropomotoryka Cwiczenia 02 id Nieznany

więcej podobnych podstron