PODSTAWY PROGRAMOWANIA

Podobne dokumenty
Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Typy klasowe (klasy) 1. Programowanie obiektowe. 2. Założenia paradygmatu obiektowego:

Język programowania PASCAL

PODSTAWY PROGRAMOWANIA

Język programowania DELPHI / Andrzej Marciniak. Poznań, Spis treści

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Delphi Laboratorium 3

Zapis programu z wykorzystaniem modułu (Podstawy Delphi 2.1, 2.2, 2.3 str11 )

Wykład 5: Klasy cz. 3

Podstawy Programowania semestr drugi. Wykład czternasty

Wykład 8: klasy cz. 4

PARADYGMATY PROGRAMOWANIA Wykład 4

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

PODSTAWY PROGRAMOWANIA

PODSTAWY PROGRAMOWANIA

Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Szablony klas, zastosowanie szablonów w programach

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Ada-95. Dariusz Wawrzyniak

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

TEMAT : KLASY DZIEDZICZENIE

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Wprowadzenie do programowania w języku C

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Tworzenie własnych komponentów

Wstęp do programowania. Różne różności

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Klasy abstrakcyjne i interfejsy

Podstawy programowania. Wykład PASCAL. Wstęp do programowania obiektowego. dr Artur Bartoszewski - Podstawy programowania, sem.

ZASADY PROGRAMOWANIA KOMPUTERÓW

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Programowanie obiektowe

Wstęp do programowania

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Lekcja 6: Pascal. Procedura i funkcja

Programowanie, część I

Do czego służą klasy?

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Podstawy programowania w języku C++

Programowanie obiektowe - 1.

Pascal - wprowadzenie

Podstawy programowania

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

Podstawy programowania skrót z wykładów:

KLASY cz.1. Dorota Pylak

Procedury i funkcje - powtórzenie i uzupełnienia. Przykład funkcji potęgowanie przy wykładniku naturalnym

Instrukcje podsumowanie. Proste: - przypisania - wejścia-wyjścia (read, readln, write, writeln) - pusta - po prostu ; (średnik) Strukturalne:

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja, - liczby losowe

Wykład 9: Polimorfizm i klasy wirtualne

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Dziedziczenie jednobazowe, poliformizm

Programowanie w Turbo Pascal

.NET Klasy, obiekty. ciąg dalszy

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

Programowanie, część I

Wykład 1: Wskaźniki i zmienne dynamiczne

Definicje klas i obiektów. Tomasz Borzyszkowski

Wykład 4: Klasy i Metody

Algorytmy i struktury danych

10. Programowanie obiektowe w PHP5

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Programowanie w języku C++

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja cz. 1

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Do czego służą klasy?

Programowanie strukturalne i obiektowe : podręcznik do nauki zawodu technik informatyk / Adam Majczak. Gliwice, cop

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Programowanie obiektowe

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Kurs WWW. Paweł Rajba.

Materiały do zajęć VII

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy PRAWA PRZYJACIÓŁ KLASY. Dostęp z zewnątrz: Dostęp z wewnątrz:

Podstawy Programowania

Język ludzki kod maszynowy

Podstawy Programowania 2

Abstrakcyjny typ danych

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

20. Pascal i łączenie podprogramów Pascala z programem napisanym w C

typ zakres sposob zapamietania shortint integer bajty (z bitem znaku) longint byte word

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Podstawy algorytmiki i programowania - wykład 4 C-struktury

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm POLIMORFIZM

Transkrypt:

PODSTAWY PROGRAMOWANIA Andrzej Marciniak Prezentacja multimedialna przygotowana za pomocą systemu Corel Presentations X3 Copyright 2003-2017 by Andrzej Marciniak PP-8(1 z 78)

Na poprzednim wykładzie... # instrukcje (cd.) instrukcje strukturalne (iteracyjne, wiążąca, obsługi warunków i stanów wyjątkowych) instrukcja asemblerowa # funkcje i procedury definicje funkcji i procedur rodzaje parametrów PP-8(2 z 78)

Na tym wykładzie... # funkcje i procedury (cd.) przeciążanie funkcji i procedur przykłady definicji funkcji i procedur wywołanie funkcji i procedury konwencje wywoływania funkcji i procedur oraz dyrektywa inline funkcje i procedury anonimowe funkcje i procedury asemblerowe podprogramy zewnętrzne # przetwarzanie obiektów definicje metod konstruktory i destruktory metody statyczne, wirtualne, dynamiczne i abstrakcyjne przeciążanie metod PP-8(3 z 78)

Przeciążanie funkcji i procedur W obrębie tego samego zakresu ważności identyfikatorów można zdefiniować więcej niż jedną funkcję i (lub) procedurę o takiej samej nazwie. Wielokrotne definiowanie funkcji i procedur o takich samych nazwach nazywa się przeciążaniem (ang. overloading). W definicjach funkcji i procedur przeciążanych jest konieczne wyspecyfikowanie dyrektywy języka overload. PP-8(4 z 78)

Przeciążanie funkcji i procedur Jeśli dwie lub więcej funkcji i (lub) procedur przeciążonych ma taką samą nazwę, to powstaje pytanie: w jaki sposób następuje identyfikacja odpowiedniej funkcji i (lub) procedury w chwili wywołania? Odpowiedzią na to pytanie jest reguła, że takie funkcje i procedury muszą różnić się liczbą lub typami parametrów. W chwili wywołania funkcji lub procedury przeciążonej właśnie po liczbie lub typach argumentów następuje odpowiednia identyfikacja.pp-8(5 z 78)

Przeciążanie funkcji i procedur Przykład Załóżmy, że zdefiniowano dwie funkcje przeciążone: function suma (a, b, c : Real) : Real; overload; begin Result:=a+b+c end; function suma (a, b, c : Integer) : Integer; overload; begin Result:=a+b+c end; W instrukcji x:=suma(1, 2, 3); zostanie wywołana druga funkcja suma, a w instrukcji z:=suma(1, 2, 3.0); pierwsza (pierwsze dwa argumenty zostaną zamienione na typ Real). PP-8(6 z 78)

Przykłady definicji funkcji i procedur Iloczyn macierzy A i B, gdzie dim A = m n i dim B = n p, jest macierzą C, przy czym dim C = m p. Procedura znajdująca macierz C może mieć następującą postać: procedure ilm (const m, n, p : Integer; const a : matrix1; const b : matrix2; out c : matrix3); var i, j, k : Integer; s : Extended; begin for i:=1 to m do for k:=1 to p do begin s:=0; for j:=1 to n do s:=s+a[i,j]*b[j,k]; c[i,k]:=s end end; PP-8(7 z 78)

Przykłady definicji funkcji i procedur Dodawanie dwóch liczb zespolonych można zrealizować za pomocą funkcji function addcomplex (const a, b : complex) : complex; begin with Result do begin re:=a.re+b.re; im:=a.im+b.im end end; gdzie complex oznacza typ zdefiniowany następująco: type complex = record re, im : Extended end; PP-8(8 z 78)

Przykłady definicji funkcji i procedur Za pomocą funkcji function porownaj (var zmienna1, zmienna2; const rozmiar : Cardinal) : Boolean; type bajty = array [0..Maxint 1] of Byte; var i : Cardinal; begin i:=0; while (i<rozmiar) and (bajty(zmienna1)[i]=bajty(zmienna2)[i]) do i:=i+1; porownaj:=i=rozmiar end; można porównać wartości dowolnych dwu zmiennych o dowolnym rozmiarze. Typy argumentów odpowiadające parametrom nie są tu PP-8(9 z 78) istotne, gdyż zmienne te są porównywane bajt po bajcie.

Za pomocą procedury Przykłady definicji funkcji i procedur procedure zerowanie (var a : array of Extended); var i : Integer; begin for i:=0 to High(a) do a[i]:=0 end; można wszystkim elementom różnych tablic o elementach rzeczywistych (typu Extended) przypisać wartość 0. PP-8(10 z 78)

Przykłady definicji funkcji i procedur Za pomocą następującej procedury: procedure wypelnienie_tablicy (var a : array of Extended; const wartosc : Extended = 0); var i : Integer; begin for i:=0 to High(a) do a[i]:=wartosc end; można przypisywać wszystkim elementom tablic (niekoniecznie jednowymiarowych) albo domyślną wartość 0, albo wartość podaną w wywołaniu procedury. Jedynym wymaganiem jest, aby elementy tablic były typu Extended. PP-8(11 z 78)

Przykłady definicji funkcji i procedur Parametry o domyślnej wartości określone w definicji typu proceduralnego są nadrzędne w stosunku do takich parametrów podanych dla aktualnej funkcji lub procedury. PP-8(12 z 78)

Przykłady definicji funkcji i procedur Załóżmy, że zdefiniowano typ proceduralny type typ_proc = procedure (var x : Real; const i : Integer = 0); oraz procedurę o nagłówku procedure alfa (var z : Real; const k : Integer = 1); Po zadeklarowaniu zmiennych: var proc : typ_proc; y : Real; wykonanie następujących instrukcji: proc:=alfa; y:=1.123; proc (y); spowoduje wywołanie procedury alfa dla pierwszego argumentu o wartości 1.123 i drugiego argumentu równego 0. PP-8(13 z 78)

Wywołanie funkcji Wywołanie funkcji może nastąpić za pomocą podania nazwy funkcji jako argumentu dowolnego wyrażenia. Jeśli funkcja zawiera parametry, to przy wywołaniu bezpośrednio za nazwą funkcji podaje się w nawiasach listę argumentów, przy czym poszczególne argumenty oddziela się przecinkami. Liczba argumentów musi być przy tym zgodna z liczbą parametrów formalnych, a typ każdego argumentu musi być zgodny (w określonym sensie) z typem odpowiadającego mu parametru formalnego. PP-8(14 z 78)

Wywołanie funkcji W przypadku parametrów o domyślnej wartości możliwe jest opuszczenie odpowiadających im argumentów. Jeśli jednak takich parametrów jest kilka i domyślną wartość przyjmuje się dla któregoś z nich, to opuszczając odpowiadający mu argument należy także opuścić wszystkie argumenty odpowiadające następnym parametrom domyślnym. Oznacza to, że dla funkcji o nagłówku np. function funkcja (a : Extended = 1.5; b : Integer = 0; c : Integer = 1) : Boolean; nie jest dozwolone wywołanie postaci funkcja (,, 0) Możliwe są wywołania: funkcja ( ) oraz funkcja PP-8(15 z 78)

Wywołanie funkcji Dla funkcji o nagłówku function suma_tablicy (const tablica : array of Shortint) : Longint; (z tablicowym parametrem otwartym) można zastosować wywołanie postaci suma_tablicy([m+2, 123, n]) Zapis [m+2, 123, n] nazywa się konstruktorem tablicy otwartej. Odpowiada on utworzeniu tymczasowej zmiennej typu tablicowego (nazwijmy ją tab_tymcz) o trzech elementach i przypisaniu im wartości: tab_tymcz[0]:=m+2; tab_tymcz[1]:=123; tab_tymcz[2]:=n; a następnie wywołaniu funkcji dla tej zmiennej, tj. suma_tablicy(tab_tymcz); PP-8(16 z 78)

Wywołanie funkcji W języku Delphi można definiować funkcje rekurencyjne. W części operacyjnej takiej funkcji następuje wywołanie tej samej funkcji. Jest to analogia do znanego w matematyce rekurencyjnego definiowania pewnych wzorów. PP-8(17 z 78)

Przykłady Wywołanie funkcji Definicja funkcji obliczającej n! może mieć postać: function silnia (const n : Byte) : Integer; begin if n=0 then silnia:=1 else silnia:=n*silnia(n 1) {*} end; Zastosowanie zmiennej lokalnej Result (niejawnie deklarowanej w każdej funkcji) zamiast identyfikatora funkcji (silnia) w instrukcji oznaczonej gwiazdką byłoby błędne. Użycie zmiennej Result nie powoduje bowiem wywołania funkcji. PP-8(18 z 78)

Przykłady Zastosowanie w podanej funkcji instrukcji try...except w celu zabezpieczenia przed przekroczeniem zakresu liczb typu Integer, tj. zdefiniowanie funkcji następująco: Wywołanie funkcji {$Q+} function silnia (const n : Byte) : Integer; begin if n=0 then silnia:=1 else try silnia:=n*silnia(n 1) except on EIntOverflow do begin ShowMessage ( Argument + wywołania funkcji jest za duży + obliczenie silni nie jest + możliwe ); raise end end end; nie jest właściwe, gdyż z uwagi na rekurencyjne wywoływania warunek EIntOverflow mógłby PP-8(19 z 78) powstać wiele razy.

Przykłady Zabezpieczenia przed wystąpieniem warunku EIntOverflow należy wykonać poza funkcją, na przykład tak, jak we fragmencie programu obok. Wywołanie funkcji... try s:=silnia(n) except on EIntOverflow do ShowMessage ( Argument + wywołania funkcji jest + za duży + obliczenie silni nie jest + możliwe ) end;... PP-8(20 z 78)

Wywołanie funkcji W języku Delphi funkcja może być wywoływana w taki sam sposób, jak procedura za pomocą instrukcji wywołania funkcji postaci nazwa-funkcji lub nazwa-funkcji (lista-parametrów-aktualnych) Wywołania te powodują wykonanie instrukcji stanowiących część operacyjną funkcji, ale obliczona wartość funkcji jest bez znaczenia. PP-8(21 z 78)

Wywołanie procedury Do wywołania procedury służy instrukcja wywołania procedury postaci nazwa-procedury lub nazwa-procedury (lista-parametrów-aktualnych) PP-8(22 z 78)

Wywołanie procedury Wywołanie procedury (lub funkcji) o parametrach przekazywanych przez zmienną dla argumentów o identycznych identyfikatorach może doprowadzić do błędnego wykonania takiej procedury (funkcji). Przykład Rozważmy następującą definicję procedury: procedure divcplx (var a, b, c : complex); var divn : Extended; begin divn:=sqr(b.re)+sqr(b.im); c.re:=(a.re*b.re+a.im*b.im)/divn; c.im:=(a.im*b.re a.re*b.im)/divn end; Wszystkie parametry są tu przekazywane przez zmienną. PP-8(23 z 78)

Wywołanie procedury Wywołanie procedury (lub funkcji) o parametrach przekazywanych przez zmienną dla argumentów o identycznych identyfikatorach może doprowadzić do błędnego wykonania takiej procedury (funkcji). Przykład Wywołanie tej procedury postaci divcplx (z, s, z); spowoduje wykonanie procedury dla argumentów z, s i z (będących zmiennymi), które zastąpią parametry odpowiednio a, b i c. Instrukcje procedury będą więc interpretowane jak następujące instrukcje: divn:=sqr(s.re)+sqr(s.im); z.re:=(z.re*s.re+z.im*s.im)/divn; z.im:=(z.im*s.re z.re*s.im)/divn; PP-8(24 z 78)

Przykład Wywołanie procedury divn:=sqr(s.re)+sqr(s.im); z.re:=(z.re*s.re+z.im*s.im)/divn; z.im:=(z.im*s.re z.re*s.im)/divn; Na skutek wykonania drugiej instrukcji przypisania, wartość zmiennej z.re w wyrażeniu występującym w trzeciej instrukcji przypisania, będzie różna od pierwotnej wartości pierwszego argumentu procedury, co w efekcie spowoduje błędne obliczenie wartości z.im. Taka sytuacja nie wystąpi przy wywołaniu procedury dla argumentów (zmiennych) o różnych identyfikatorach. PP-8(25 z 78)

Wywołanie procedury Niewłaściwe użycie parametrów przekazywanych przez wartość może także doprowadzić do nieoczekiwanych wyników. PP-8(26 z 78)

Wywołanie procedury Przykład W wyniku wykonania następującego programu tekstowego: program programam; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; var x : Integer; procedure val_param (z : Integer); begin z:=z+1; Writeln (z) end; begin x:=1; val_param (x); Writeln (x); Readln end. na ekranie otrzymamy napisy: 2 1 PP-8(27 z 78)

Konwencje wywoływania funkcji i procedur W języku Delphi występuje pięć dyrektyw (register, pascal, cdecl, stdcall i safecall), za pomocą których ustala się sposób przekazywania parametrów w funkcjach, procedurach i metodach. Ustalenia te, zwane konwencjami wywołania, dotyczą: # kolejności przekazywania parametrów, # automatycznego usuwania parametrów ze stosu, # używania rejestrów przez parametry, # obsługi warunków błędów i stanów wyjątkowych. PP-8(28 z 78)

Konwencje wywoływania funkcji i procedur register dyrektywa domyślna (nie wymaga określania); parametry są przekazywane od strony lewej do prawej, a więc w kolejności ich wyspecyfikowania; przy przekazywaniu parametrów zostanie wykorzystanych od jednego do trzech rejestrów procesora (EAX, EDX oraz ECX); po wykonaniu funkcji lub procedury wszystkie parametry zostaną automatycznie usunięte ze stosu pascal jw., ale rejestry procesora nie będą używane PP-8(29 z 78)

Konwencje wywoływania funkcji i procedur stdcall przekazywanie parametrów od strony prawej do lewej i brak używania w tym procesie rejestrów procesora; po zakończeniu wykonywania funkcji lub procedury parametry zostaną usunięte ze stosu cdecl jw., ale usunięcie parametrów ze stosu musi być zabezpieczone w miejscu wywołania danej funkcji lub procedury (po jej wykonaniu i przekazaniu z niej sterowania); zaprogramowanie odpowiednich instrukcji (zwykle w asemblerze) jest zadaniem programisty. safecall dotyczy wyłącznie metod łącz dualnych (pomijamy) PP-8(30 z 78)

Konwencje wywoływania funkcji i procedur Domyślna konwencja wywoływania (register) jest najbardziej efektywna, gdyż wskutek wykorzystywania rejestrów procesora często nie potrzeba umieszczać parametrów w stosie (dzieje się tak zawsze, gdy liczba parametrów nie przekracza trzech). Konwencje określone dyrektywami pascal i cdecl stosuje się zwykle przy wywoływaniu funkcji i procedur z bibliotek łączonych dynamicznie napisanych w językach C, C++ lub innych. W przypadku wywoływania funkcji środowiska Windows stosuje się konwencję określoną dyrektywą stdcall. PP-8(31 z 78)

Dyrektywa inline Dyrektywa inline podana w nagłówku funkcji, procedury lub metody powoduje wprowadzenie przez kompilator kodu wewnętrznego w miejscu wywołania (zamiast utworzenia w tym miejscu odwołania do miejsca zapisu funkcji procedury lub metody w kodzie wynikowym programu). Zastosowanie dyrektyw jest ograniczone, m.in.: - nie może być użyta dla konstruktorów, destruktorów, metod wirtualnych i metod obsługujących wiadomości (będzie dalej), - nie jest dozwolone jej stosowanie w funkjcach, procedurach i metodach z parametrami otwartymi i w zapowiedziach definicji (łącznie z dyrektywą forward). PP-8(32 z 78)

anonimowe anonimowe to fragmenty kodu programowego, które mogą być przypisane zmiennym lub użyte jako parametry. Definicja typu procedury anonimowej: type identyfikator-typu = reference to procedure [(lista-parametrów)]; Definicja typu funkcji anonimowej: type identyfikator-typu = reference to function [(lista-parametrów)] : typ-wartości-funkcji; PP-8(33 z 78)

anonimowe Definicje funkcji i procedur anonimowych nie mają nazw i nie występują samodzielnie (są zwykle przypisywane zmiennym typów funkcji i procedur anonimowych). Definicja procedury anonimowej: procedure [(lista-parametrów-formalnych)] część-opisowa begin ciąg-instrukcji end; Uwaga: Na końcu nagłówka brak średnika. PP-8(34 z 78)

anonimowe Definicja funkcji anonimowej: function [(lista-parametrów-formalnych)] : typ-wyniku część-opisowa begin ciąg-instrukcji end; Uwaga: Na końcu nagłówka brak średnika. PP-8(35 z 78)

Przykłady 1) Po definicji typów: anonimowe type fun_anonim = reference to function (const a : Byte) : Word; proc_anonim = reference to procedure (var x : Extended); i zadeklarowaniu zmiennych: var funkcja : fun_anonim; procedura : proc_anonim; Zmiennym tym mogą być przypisane odpowiednio funkcja i procedura anonimowa (z parametrami), np.: PP-8(36 z 78)

Przykłady 1) anonimowe funkcja:= function (const a : Byte) : Word var b : Word; begin b:=10000; Result:=a+2*b end; procedura:= procedure (var x : Extended) begin x:=x-1.2345 end; Jeśli następnie w programie tekstowym zostaną wykonane instrukcje: PP-8(37 z 78)

Przykłady 1) anonimowe Writeln (funkcja(100)); z:=1.2346; procedura (z); Writeln (z); gdzie z oznacza zmienną typu Extended, to na ekranie ukażą się napisy: 2010 1.00000000000000E-0004 PP-8(38 z 78)

Przykłady anonimowe 2) Niech typ fun_anonim i zmienna funkcja będą zdefiniowane tak, jak w poprzednim przykładzie. Zdefiniujmy ponadto procedurę: procedure moja_procedura (parametr : fun_anonim); begin Writeln ( wynik =, parametr(10)+10) end; parametr typu funkcji anonimowej Wywołanie tej procedury (w programie tekstowym) postaci moja_procedura (funkcja); spowoduje pojawienie się napisu wynik = 20020 argument typu funkcji anonimowej PP-8(39 z 78)

Przykłady anonimowe 2) Taki sam napis uzyskamy, gdy procedurę wywołamy następująco: moja_procedura (function (const a : Byte) : Word var b : Word; begin b:=10000; Result:=a+2*b end;); definicja metody anonimowej jako argumentu wywołania procedury PP-8(40 z 78)

asemblerowe Jeżeli cała treść procedury lub funkcji paskalowej jest napisana w asemblerze, to zamiast zastosowania instrukcji złożonej, wewnątrz której znajduje się instrukcja asemblerowa, można posłużyć się dyrektywą języka assembler, napisaną w nagłówku funkcji lub procedury, a treść ograniczyć do instrukcji asemblerowej. Zastosowanie dyrektywy języka assembler powoduje wykonanie przez kompilator optymalizacji kodu wynikowego. PP-8(41 z 78)

Przykład asemblerowe function iloczyn (x, y : Shortint) : Smallint; begin Result:=Smallint(x)*y end; W postaci funkcji asemblerowej: function iloczyn (x, y : Shortint) : Smallint; assembler; asm MOV AL,x IMUL y MOV @Result,AX end; PP-8(42 z 78)

Podprogramy zewnętrzne Język Delphi umożliwia korzystanie w programie z podprogramów zewnętrznych (procedur i funkcji) napisanych w asemblerze i zapisanych w zbiorach.obj (ang. Intel relocatable object files). W celu dołączenia procedury lub funkcji zewnętrznej należy ją zadeklarować poprzez podanie jej nagłówka zakończonego dyrektywą języka external. Ponadto należy kompilatorowi wskazać, za pomocą dyrektywy $L ($LINK), nazwę zbioru.obj zawierającego daną procedurę lub funkcję. Dołączone procedury lub funkcje zewnętrzne wywołuje się w taki sam sposób, jak zwykłe procedury i funkcje. PP-8(43 z 78)

Podprogramy zewnętrzne Przykład Zbiór AM.OBJ, znajdujący się w bieżącym skorowidzu, zawiera funkcję i procedurę o nazwach odpowiednio AFUN i APROC. program program24; {$APPTYPE CONSOLE} {$R *.res}... var k : Integer; y : Double; znak : Char; {$LINK AM} procedure aproc (n : Integer; var x : Double); external; function afun : Char; external; begin... aproc (k, y);... znak:=afun;... end. PP-8(44 z 78)

Przetwarzanie obiektów Obiektem nazywa się rodzaj danych będący połączeniem danych i działającego na nich kodu programowego. Do opisu obiektów służą w języku Delphi typy klasowe. Zmienne typów klasowych (nazywane też zmiennymi obiektowymi lub krótko obiektami) nie zawierają obiektu, ale są wskaźnikami do bloków pamięci, które zostały przydzielone obiektom (za pomocą specjalnych metod, tzw. konstruktorów). PP-8(45 z 78)

Przetwarzanie obiektów Definicje metod W ogólności metody określają czynności wykonywane na obiekcie i za ich pomocą następuje dostęp do pól danych obiektu. Metoda jest to procedura lub funkcja, której deklaracja (nie definicja!) występuje w definicji typu klasowego. Definicja metody występuje poza definicją odnośnego typu klasowego i po niej (w przypadku modułu w jego części implementacyjnej). PP-8(46 z 78)

Przetwarzanie obiektów Definicje metod W nagłówku definicji metody jej nazwa jest kwalifikowana. Kwalifikacja ta wskazuje na typ klasowy, którego dana metoda dotyczy i ma postać identyfikator-typu-klasowego.nazwa-metody Nagłówek definicji metody może (ale nie musi) zawierać powtórzenia listy parametrów formalnych z jej deklaracji w obrębie typu klasowego. Jeśli jednak taka lista występuje, to musi ona specyfikować parametry w tej samej kolejności, o takich samych nazwach i typach, a w przypadku metodyfunkcji jej typ wartości musi być identyczny z typem podanym w deklaracji. PP-8(47 z 78)

Przykład Przetwarzanie obiektów Definicje metod type polozenie = class x, y : Integer; procedure poczatek (nowe_x, nowe_y : Integer); end;... procedure polozenie.poczatek (nowe_x, nowe_y : Integer); begin x:=nowe_x; y:=nowe_y end; To można opuścić! PP-8(48 z 78)

Przykład Przetwarzanie obiektów Definicje metod type polozenie = class x, y : Integer; procedure poczatek (nowe_x, nowe_y : Integer); end;... procedure polozenie.poczatek; begin x:=nowe_x; y:=nowe_y end; PP-8(49 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Do przydzielania pamięci obiektom (i tym samym do ich utworzenia) służą konstruktory, a do zwalniania pamięci zajętej przez obiekty destruktory. Ponieważ każdy typ klasowy jest potomkiem predefiniowanego typu klasowego TObject, którego definicja zawiera konstruktor Create i destruktor Destroy, więc z uwagi na dziedziczenie konstruktory i destruktory są elementami każdego typu klasowego. Niezależnie od dziedziczonych konstruktorów i destruktorów programista może w definicji typu klasowego określić własne konstruktory i (lub) destruktory danego typu (ich liczba nie musi być ograniczona do jednego konstruktora i jednego destruktora). PP-8(50 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Poza specjalnym przeznaczeniem (do przydziału i zwalniania pamięci dla obiektów), konstruktory i destruktory są takimi samymi metodami, jak inne metody typu klasowego, a więc mają cechy dziedziczności i pokrywania. Deklaracje i definicje konstruktorów i destruktorów różnią się od deklaracji i definicji zwykłych metod występowaniem w ich nagłówkach słów kluczowych odpowiednio constructor i destructor (zamiast procedure lub function). PP-8(51 z 78)

Przetwarzanie obiektów Konstruktory i destruktory W celu utworzenia nowego obiektu konstruktor musi być wywołany jako odwołanie do klasy (!), a więc odpowiednia instrukcja powinna mieć postać zmienna-obiektowa:=typ-klasowy.nazwa-konstruktora przy czym zmienna obiektowa oznacza zmienną typu klasowego, a po nazwie konstruktora może jeszcze wystąpić lista argumentów (o ile konstruktor został zdefiniowany z listą parametrów). PP-8(52 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Za pomocą wywołania o podanej postaci następuje: # przydzielenie obiektowi bloku pamięci w stosie, # wyzerowanie przydzielonej pamięci, tj. przypisanie wartości 0 wszystkim polom o porządkowym typie wartości, adresu pustego (nil) wszystkim polom o wartościach typów wskaźnikowych i klasowych oraz łańcucha pustego wszystkim polom o wartościach typów łańcuchowych, # przypisanie podanej zmiennej obiektowej odwołania do obiektu (typem wartości tego odwołania jest typ klasowy wyspecyfikowany w podanej konstrukcji). PP-8(53 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Gdy konstruktor zostanie wywołany jako odwołanie do obiektu, a więc tak, jak zwykła metoda, tj. za pomocą instrukcji postaci zmienna-obiektowa.nazwa-konstruktora jego działanie jest analogiczne do zwykłej metody, tzn. zostaną wykonane operacje określone w treści konstruktora, ale w pamięci nie zostanie utworzony żaden nowy obiekt, ani też nie zostanie przez konstruktor przekazana żadna wartość określająca odwołanie do obiektu. PP-8(54 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Na ogół wywołanie konstruktora w postaci odwołania do obiektu występuje tylko w celu wykonania konstruktora z typu nadrzędnego (dziedziczonego) i wówczas zamiast podanej instrukcji stosuje się instrukcję dziedziczenia: lub inherited nazwa-konstruktora inherited nazwa-konstruktora (lista-parametrów-aktualnych) Nazwa konstruktora oznacza tu nazwę konstruktora nadrzędnego typu klasowego, a druga postać instrukcji dziedziczenia konstruktora dotyczy PP-8(55 z 78) przypadku, gdy konstruktor ten ma listę parametrów.

Przetwarzanie obiektów Konstruktory i destruktory Przykład Rozważmy następującą definicję typu klasowego: type druk = class autor, tytul : string; rok_wydania, numer_katalogowy : Word; private... public constructor Inicjuj (aut, tyt : string; rok : Word);... end; Konstruktory zawsze deklaruje się w sekcji public, gdyż powinny one być ogólnie dostępne. PP-8(56 z 78)

Przykład Przetwarzanie obiektów Konstruktory i destruktory Definicja konstruktora Inicjuj typu druk może mieć postać constructor druk.inicjuj; begin inherited Create; autor:=aut; tytul:=tyt; rok_wydania:=rok; numer_katalogowy:=0 end; Pierwszą instrukcją jest wywołanie konstruktora typu nadrzędnego (typem tym jest domyślnie typ standardowy TObject). Instrukcja taka powinna być zawsze pierwszą instrukcją każdego definiowanego konstruktora. PP-8(57 z 78)

Przykład Przetwarzanie obiektów Konstruktory i destruktory Jeśli zadeklarujemy zmienną: var moj_druk : druk; to w celu zainicjowania rozważanego obiektu należy wykonać instrukcję moj_druk:=druk.inicjuj( A. Marciniak, Język programowania Delphi, 2012); Oczywiście argumenty są tu przykładowe. PP-8(58 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Jeśli konstruktor w typie potomnym ma zmienić wartości pewnych pól (lub własności) ustalonych w konstruktorze typu nadrzędnego, to należy zadeklarować go z dyrektywą języka override, np. constructor Create (wlasciciel : TComponent); override; Jeżeli podczas wykonywania konstruktora wystąpi błąd, następuje automatyczne wywołanie destruktora Destroy (jest on zdefiniowany w pierwotnym typie klasowym TObject i tym samym dziedziczony we wszystkich typach klasowych). Destruktor ten usuwa z pamięci konstruowany (niedokończony) obiekt. PP-8(59 z 78)

Przetwarzanie obiektów Konstruktory i destruktory Destruktor jest specjalną metodą, która służy do destrukcji obiektu, tj. do zwolnienia zajętej przez niego pamięci. Zwolnienie tej pamięci jest ostatnią czynnością wykonywaną przez destruktor wcześniej zostaną wykonane instrukcje podane w jego definicji. Instrukcjami tymi są zazwyczaj zwolnienia pamięci wewnętrznych obiektów i zasobów przydzielonych obiektowi. Tak, jak w przypadku konstruktora, pierwszą instrukcją jest wywołanie konstruktora nadrzędnego typu klasowego, ostatnią instrukcją destruktora powinno być wywołanie destruktora PP-8(60 z 78) tego typu.

Przetwarzanie obiektów Konstruktory i destruktory Dla obiektów predefiniowanych typów klasowych bezpośrednie wywoływanie destruktora Destroy nie jest zalecane należy raczej posługiwać się metodą Free (zdefiniowaną w standardowym typie klasowym TObject). Jej zaletą jest uprzednie sprawdzenie, czy zwalniany obiekt nie jest określony przez adres pusty (nil): procedure TObject.Free; begin if Self<>nil then Destroy end; PP-8(61 z 78)

Przykład Przetwarzanie obiektów Konstruktory i destruktory Deklaracja destruktora w typie ksztalt pokrywającego destruktor z typu nadrzędnego (w sekcji public): destructor Destroy; override; Definicja destruktora: destructor ksztalt.destroy; begin pioro.free; pedzel.free; inherited Destroy end; wywołanie destruktora typu nadrzędnego PP-8(62 z 78)

Przetwarzanie obiektów Metody statyczne W typie potomnym można określić metodę o takiej samej nazwie. Powoduje to, że podczas wykonywania programu jednocześnie mogą być dostępne dwie (lub większa liczba) metod o takich samych identyfikatorach. Dla zwykłych metod, które domyślnie są metodami statycznymi, o tym która metoda ma być wykonana, decyduje zadeklarowany typ klasowy zmiennej obiektowej (zmiennej typu klasowego) użytej w wywołaniu metody. PP-8(63 z 78)

Przetwarzanie obiektów Metody statyczne Przykład Załóżmy, że zdefiniowano dwa typy klasowe: type druk = class procedure do_katalogu;... end; ksiazka = class (druk) procedure do_katalogu;... end; W obu definicjach występuje metoda o takiej samej nazwie. PP-8(64 z 78)

Przetwarzanie obiektów Metody statyczne Przykład Zadeklarujmy zmienne obiektowe obu typów: var moj_druk : druk; moja_ksiazka : ksiazka; i rozważmy następujące instrukcje: moj_druk:=druk.create; moj_druk.do_katalogu; moj_druk.free; moj_druk:=ksiazka.create; moj_druk.do_katalogu; moj_druk.free; wywołanie metody do_katalogu typu druk wywołanie metody do_katalogu typu druk PP-8(65 z 78)

Przetwarzanie obiektów Metody statyczne Przykład Zadeklarujmy zmienne obiektowe obu typów: var moj_druk : druk; moja_ksiazka : ksiazka; i rozważmy następujące instrukcje: moja_ksiazka:=ksiazka.create; moja_ksiazka.do_katalogu; wywołanie metody do_katalogu typu ksiazka moja_ksiazka.free; Z podanego przykładu wynika, że przy wywoływaniu metod statycznych ważny jest typ klasowy podany w deklaracji zmiennej obiektowej, a nie typ wyspecyfikowany w instrukcji tworzącej obiekt w pamięci. PP-8(66 z 78)

Przetwarzanie obiektów Metody wirtualne Metodę nazywamy metodą wirtualną, jeśli jej deklaracja w typie klasowym zawiera dodatkowo dyrektywę języka virtual. Metody, które w typach potomnych pokrywają metodę wirtualną, powinny być zadeklarowane z dyrektywą języka override (metody takie też są metodami wirtualnymi). Jeśli metoda wirtualna ma parametry, to odpowiadająca jej metoda pokrywająca musi mieć tę samą liczbę parametrów, wyspecyfikowanych w takiej samej kolejności, a typy parametrów muszą być identyczne z typami parametrów metody wirtualnej. PP-8(67 z 78)

Przetwarzanie obiektów Metody wirtualne Pominięcie dyrektywy override w deklaracji metody o takiej samej nazwie w typie potomnym powoduje, że będzie ona zwykłą metodą statyczną, która przesłoni metodę z typu nadrzędnego. W przypadku metod wirtualnych o identycznych identyfikatorach o tym, która metoda ma być wykonana, decyduje aktualny (a nie deklarowany) typ zmiennej obiektowej. PP-8(68 z 78)

Przetwarzanie obiektów Metody wirtualne Przykład Niech w typie klasowym druk metoda do_katalogu będzie zadeklarowana jako wirtualna: type druk = class procedure do_katalogu; virtual;... end; PP-8(69 z 78)

Przetwarzanie obiektów Metody wirtualne Przykład Zdefiniujmy ponadto dwa potomne typy klasowe z metodami pokrywającymi metodę do_katalogu: type ksiazka = class (druk) procedure do_katalogu; override;... end; czasopismo = class (druk) procedure do_katalogu; override;... end; PP-8(70 z 78)

Przetwarzanie obiektów Metody wirtualne Przykład Zadeklarujmy zmienną moj_druk typu druk: var moj_druk : druk; Rozważmy następujące instrukcje: moj_druk:=ksiazka.create; moj_druk.do_katalogu; wywołanie metody do_katalogu typu ksiazka moj_druk.free; moj_druk:=czasopismo.create; moj_druk.do_katalogu; wywołanie metody do_katalogu typu czasopismo moj_druk.free; O tym, która metoda zostanie wywołana, decyduje aktualny PP-8(71 z 78) typ zmiennej moj_druk.

Przetwarzanie obiektów Metody wirtualne Metody wirtualne służą przede wszystkim do wywoływania metod o takich samych nazwach, które zwykle wykonują inne czynności i które są zadeklarowane w kolejnych typach potomnych. Jeśli w typie potomnym dla metody wirtualnej z typu nadrzędnego pominiemy dyrektywę override, to będzie ona uważana za zwykłą metodę statyczną przesłaniającą odpowiednią metodę typu nadrzędnego. W takim przypadku kompilator wygeneruje jednak ostrzeżenie o przesłonięciu metody wirtualnej zadeklarowanej w typie nadrzędnym. Jeśli przesłonięcie metody wirtualnej z typu nadrzędnego jest zamierzone, to w celu wyeliminowania ostrzeżenia kompilatora należy metodę przesłaniającą zadeklarować z dyrektywą języka reintroduce. PP-8(72 z 78)

Przetwarzanie obiektów Metody dynamiczne Metody dynamiczne deklaruje się za pomocą dyrektywy języka dynamic. Semantycznie są one identyczne z metodami wirtualnymi, a różnią się od nich tylko szybkością wywołań podczas wykonywania programu. Dla metod wirtualnych kompilator generuje kod wynikowy, który jest optymalny z punktu widzenia szybkości wywoływania metod, a dla metod dynamicznych optymalny z uwagi na rozmiar kodu. PP-8(73 z 78)

Przetwarzanie obiektów Metody abstrakcyjne Metoda abstrakcyjna jest to metoda wirtualna lub dynamiczna, której definicja nie jest podana dla klasy, w której została zadeklarowana. W deklaracji takiej metody oprócz dyrektywy virtual lub dynamic należy wyspecyfikować dyrektywę języka abstract. W metodzie pokrywającej metodę abstrakcyjną nie jest dozwolone odwołanie się do niej za pomocą instrukcji inherited. Próba wywołania metody abstrakcyjnej zakończy się wygenerowaniem warunku błędu. PP-8(74 z 78)

Przetwarzanie obiektów Przeciążanie metod Zastosowanie dyrektywy overload w deklaracji metody oznacza jej redeklarację. Jeśli redeklarowana metoda ma przy tym inne parametry niż występujące w typie nadrzędnym, oznacza to tzw. przeciążenie metody nadrzędnej bez jej przesłonięcia. W takim przypadku jest możliwe wywołanie zarówno metody przodka, jak i metody przeciążonej. O tym, która metoda zostanie wywołana, decyduje zgodność argumentów w wywołaniu metody z jej parametrami. PP-8(75 z 78)

Przetwarzanie obiektów Przeciążanie metod Przykład. Rozważmy definicje: type alfa = class... procedure metoda (a : Real); overload; virtual; end; beta = class (alfa)... procedure metoda (znak : Char); reintroduce; overload; end; Jeśli utworzymy obiekt obiekt typu beta, to instrukcja obiekt.metoda (1.123456); spowoduje wywołanie metody metoda z typu alfa, a instrukcja obiekt.metoda ( A ); PP-8(76 z 78) wywoła metodę metoda zadeklarowaną w typie beta.

Przetwarzanie obiektów Metody klasowe Metoda klasowa jest to specjalna metoda, która służy do przetwarzania klas (dokładniej: dotyczy zmiennych typu odwołania do klasy), a nie obiektów (ściślej: zmiennych typu klasowego). Deklaracja (w typie klasowym) i definicja (poza definicją typu klasowego) metody rozpoczyna się od słowa kluczowego class. PP-8(77 z 78)

Nareszcie koniec!!!... tak, koniec, ale tylko na dzisiaj! PP-8(78 z 78)