wstep wmp, WSTĘP


Informatyka Stosowana - I rok semestr II

Wstęp i metody programowania - materiały

1. Wprowadzenie do programowania

    1. Podstawowe definicje

    1. Charakterystyka języka Pascal

    1. Metodologia programowania

    1. Ogólna struktura programu w języku Pascal

    1. Programowanie Obiektowe - wstęp

Literatura

  1. Abolrous Sam, "Pascal Podstawy programowania", Mikom

  2. Borland TP7 "Language Guide"

  3. Borland TP7 "Programmer's Reference"

  4. Borland TP7 "User's Guide"

  5. Jankowski B., "Programowanie w praktyce", Mikom

  6. Jarża R., Turbo Pascal. Szkoła programowania, Wydawnictwo Robomatic,
    Wrocław, 1996.

  7. Kernighan B., Plauger P., "Narzędzia programistyczne w Pascalu", WNT

  8. Koleśnik K., Wstęp do programowania z przykładami w Turbo Pascalu, Wydawnictwo Helion, Gliwice, 1999.

  9. Majczak Adam, Pascal od podstaw, Translator

  10. Marciniak A., "Object Pascal - język programowania w środowisku Borland Delphi 2.0",  Nakom

  11. Marciniak A., "Turbo Pascal 7.0 z elementami programowania cz.1, cz.2",
    Nakom

  12. Marciniak A., "Turbo Pascal 7.0" ,WNT

  13. Neil J. Rubenking, Understending and Programming in Object-Oriented-Pascal, PC Magazine, February 27, 1990, p. 263.

  14. Porebski W., "PASCAL - Wprowadzenie do programowania, Help

  15. Sielicki A., Laboratorium programowania w języku Pascal, Oficyna Wydawnicza Politechniki Wrocławskiej, Wrocław, 1994.

  16. Walczak Krzysztof, Walczak Struzińska Anna "Programowanie w języku Turbo 
    Pascal 7.0",
    Warszawa

  17. Wirth N., "Algorytmy + Struktury danych = Programy" ,WNT

  18. Ryszard K.Kott - Programowanie w języku Pascal - WNT 1988


1. Wprowadzenie do programowania

1.1. Podstawowe definicje

Problem - zadanie do rozwiązania.

Specyfikacja zadania - określenie danych wejściowych oraz wyników, które
powinny być uzyskane, a także warunków jakie
powinny one spełniać; może zawierać również
związki pomiędzy danymi a wynikami; definiuje
abstrakcyjny model rzeczywistego problemu.

Algorytm jest skończonym ciągiem czynności, które prowadzą do
rozwiązania zadania lub osiągnięcia określonego celu.

Komputer - urządzenie elektroniczne służące do automatycznego

przetwarzania danych według zadanego algorytmu.

Algorytm - sposób przetwarzania danych wejściowych na dane wyjściowe

(wyniki) w skończonej liczbie kroków.

Algorytm definiuje:

Program komputerowy - algorytm zapisany w odpowiednim języku

programowania zrozumiałym przez komputer (np. w języku

maszynowym procesora - ciąg liczb stanowiących rozkazy

i dane dla procesora).

Język maszynowy jest trudno przyswajalny przez człowieka, gdyż składa się z liczb repre­zen­­tujących instrukcje procesora (programy maszynowe są przechowywane w pamięci komputera w kodzie binarnym). W praktyce algorytmy są zapisywane za pomocą instrukcji języków programowania wyższego poziomu, które udostępniają podstawowe elementy programo­wania strukturalnego (np. Pascal, C, Java, Fortran, Cobol, Modula).

Kod źródłowy - kod programu zapisany w języku algorytmicznym, który jest

czytelny dla programisty (np. Pascal, C).

Przed wykonaniem program źródłowy należy przetłumaczyć na postać zrozumiałą dla komputera czyli na kod wynikowy.

Kod wynikowy - kod pośredni w języku maszynowym, który jest zrozumiały
dla komputera; ciąg rozkazów i danych procesora,

zapisanych w pamięci komputera w kodzie binarnym.

Kod wynikowy jest przekształcany przez program linkera do postaci
wykonywalnej.

Linker - program łączący kody wynikowe odpowiednich modułów programu

w kod wykonywalny, który może być wielokrotnie uruchamiany
w komputerze.

W praktyce linker łączy w jeden plik wykonywalny następujące elementy:

Kod wykonywalny - zawiera liczby, które są pobierane z pamięci komputera

przez procesor i interpretowane jako rozkazy

podlegające wykonaniu lub jako dane stanowiące

argumenty rozkazów.

Translator - realizuje przekształcenie programu z postaci źródłowej

na postać wynikową.

Rodzaje translatorów:

Kompilator - program przetwarzający kod źródłowy na kod wynikowy

(kod pośredni w języku maszynowym, który jest zrozumiały
dla komputera).

Interpretator - realizuje translację instrukcji naprzemiennie z ich

wykonywaniem; przy zastosowaniu interpretatora każde

wykonanie programu jest związane z jego ponowną

translacją (np. Basic, SQL).

Plik - wydzielony fragment pamięci (najczęściej dyskowej)

posiadający nazwę.

Z punktu widzenia języków programowania plik jest ciągiem danych
o odpowiedniej strukturze (w najprostszym przypadku ciągiem bajtów).

Każdy plik posiada rozmiar określony w bajtach.

1 Bajt [B] = 1 znak, 1 KB = 1024 B, 1MB = 1024 KB, 1 GB = 1024 MB.

Etapy rozwiązywania problemów z wykorzystaniem komputera

Rozwiązywanie problemów z wykorzystaniem komputerów składa się z następujących etapów:

Etapy programowania

  1. Utworzenie za pomocą edytora tekstu pliku źródłowego zawierającego algorytm zapisany w wybranym języku programowania, np. program.pas (program w języku Pascal), program.cpp (program w języku C++).

  1. Kompilacja programu za pomocą kompilatora i utworzenie pliku wynikowego (obiektowego), np. program.obj.

  1. Połączenie za pomocą linkera kodu wynikowego programu, kodów wynikowych funkcji bibliotecznych oraz kodu startowego w jeden plik wykonywalny, np. program.exe.

0x08 graphic
0x08 graphic
DANE Programy (algorytmy) WYNIKI

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

System operacyjny komputera - zbiór programów sterujących pracą
urządzeń wchodzących w skład systemu
komputerowego i nadzorujących
wykonywanie programów użytkowników.

Oprogramowanie użytkowe - programy uruchamiane pod kontrolą systemu

operacyjnego.

Podczas projektowania algorytmów należy pamiętać, aby opracowywane algorytmy posiadały niską złożoność obliczeniową.

Czasowa złożoność obliczeniowa - określa liczbę elementarnych kroków obliczeniowych (tzw. operacji elementarnych, np. porównań, sumowań, itp.).

Pamięciowa złożoność obliczeniowa - określa rozmiar pamięci niezbędnej do wykonania programu.

W praktyce złożoność obliczeniową określa się za pomocą funkcji ograniczających z góry ponoszony nakład obliczeniowy, np. O(n), O(nlogn).

Algorytmy efektywne - posiadają wielomianową lub logarytmiczną złożoność obliczeniową.

Przetwarzanie sekwencyjne - wykonywanie instrukcji programów kolejno jedna za drugą.

Przetwarzanie współbieżne - wykonywanie instrukcji programów równocześnie na tym samym procesorze (z podziałem czasu procesora).

Przetwarzanie równoległe - wykonywanie instrukcji programów równocześnie na różnych procesorach.

1.2. Charakterystyka języka Pascal

Geneza języka

Język algorytmiczny wysokiego poziomu i ogólnego przeznaczenia. Został opracowany w 1968 roku przez Niklausa Wirtha na uniwersytecie w Zurychu. Wzorem dla powstania języka Pascal był język Algol 60. Pierwszy kompilator Pascala wzorcowego powstał w 1970 roku.

Język Pascal jest ukierunkowany na programowanie strukturalne. Ze względu na łatwość opanowania i niewystępowanie zbędnych elementów został powszechnie przyjęty do nauki programowania oraz jako język publikacyjny. Umożliwia tworzenie programów czytelnych, efektywnych i bezbłędnych.

Podstawowe elementy języka

Język Pascal jest wyposażony w podstawowe konstrukcje sterujące wykorzystywane w programowaniu strukturalnym:

Ponadto, w języku Pascal występują wskaźniki, które służą do przechowy­wania adresów oraz wykonywania różnych operacji na łańcuchach i blokach pamięci.

W języku Pascal możliwe są dwa sposoby przekazywania argumentów do procedur i funkcji:

Procedury i funkcje można wywoływać rekurencyjnie. Zmienne lokalne procedur i funkcji są „automatyczne”, tzn. tworzone na nowo przy każdym jej wywołaniu. Definicje procedur i funkcji mogą być zagnieżdżone, a ponadto mogą być zawarte w modułach (units) zapisanych w różnych plikach i kompilowane osobno.

W języku Pascal dane przechowywane są w zmiennych i stałych. Zmienne w języku Pascal można podzielić na:

W języku Pascal możliwe są konwersje typów danych (tzw. rzutowanie zmiennych i wskaźników). Język ten dostarcza narzędzi wejścia i wyjścia umożliwiających automatyczny dostęp do plików, np. za pomocą READ (czytaj) lub WRITE (pisz). Są to w przypadku języka Pascal mechanizmy wbudowane, które są dostępne w każdym programie bez konieczności dołączania dodatkowych bibliotek.

Zalety języka Pascal

Wady języka Pascal

Znaczną część wymienionych wad eliminują współczesne implementacje Pascala. Rozszerzają one Pascal wzorcowy o możliwość programowania obiektowego, programowania w trybie rzeczywistym i wirtualnym z ochroną dostępu oraz programowania pod Windows.

Do najpopularniejszych pakietów umożliwiających programowanie w języku Pascal w środowisku MS Windows należą: system Borland Pascal 7.0 opracowany w 1992 roku przez firmę Borland oraz jego następca system Delphi wprowadzony na rynek w 1995 roku. Oba systemy udostępniają zinte­growane środowiska programowania IDE (ang. Integrated Developement Environment), które łączą w jedną całość podstawowe narzędzia umożliwi­ające tworzenie i uruchamianie programów: kompilator, linker, edytor i program uruchomieniowy (debugger). Ponadto IDE zawierają rozbudowane systemy pomocy kontekstowej, które udostępniają użytkownikowi obszernych informacji na temat samego środowiska oraz języka programowania.

1.3. Metodologia programowania

Punktem wyjścia dla każdego programu jest algorytm umożliwiający rozwiązanie określonego zadania. Algorytm można przedstawić na wiele różnych sposobów:

Proste algorytmy mogą zostać opisane bezpośrednio w języku programo­wania. W dalszej części przedstawiono przykłady tworzenia programów umożliwiających rozwiązanie określonych zadań.

Problem 1. Znaleźć minimum spośród dwóch liczb całkowitych a i b. Wyprowadzić wartość minimum. Jeśli liczby są równe to wyprowadzić odpowiedni komunikat.

Opis słowny algorytmu

Po wczytaniu danych wejściowych a i b porównać wprowadzone liczby.
Jeśli a < b, to min = a. Wyprowadzić wynik. Jeśli a >= b, to sprawdzić
czy b < a. Jeśli tak, to min = b. Wyprowadzić wynik. W przeciwnym przypadku min = a = b. Wyprowadzić wynik.

Opis algorytmu za pomocą listy kroków

Krok 1. Wprowadź dwie liczby całkowite a i b. Przejdź do kroku 2.

Krok 2. Jeśli a < b, to podstaw min = a, wyprowadź wynik min = a.

Przejdź do kroku 5. W przeciwnym przypadku przejdź do kroku 3.

Krok 3. Sprawdź, czy b < a? Jeśli tak, to podstaw min = b, wyprowadź wynik

min = b. Przejdź do kroku 5. W przeciwnym przypadku przejdź

do kroku 4.

Krok 4. Podstaw min = a, wyprowadź wynik min = a = b. Przejdź do kroku 5.

Krok 5. Zakończ program.

Postać graficzna algorytmu (sieć działań)

W sieciach działań (schematach blokowych) definiujących algorytmy są wykorzystywane następujące bloki (skrzynki).

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
Tak

0x08 graphic

0x08 graphic

0x08 graphic

w1 w2 ... wi ... wn

0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic

Opisując algorytmy za pomocą sieci działań należy pamiętać, aby:

Schemat blokowy algorytmu wyznaczania min(a,b)

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
Tak

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

Nie

0x08 graphic
0x08 graphic
Tak

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

Nie

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

Implementacja algorytmu w postaci programu w języku Pascal

{ Obliczanie min(a,b) }

uses crt;

{ zmienne globalne do przechowywania danych }

Var a, b, min: integer;

begin { poczatek programu }

writeln('Wprowadz dane');

readln(a); readln(b);

if (a<b) then

begin min:=a; writeln('Min = a = ', a); end

else

if (b<a) then

begin min:=b; writeln('Min = b = ', b); end

else

begin min:=a; writeln('Min = a = b = ', a); end;

end. { koniec programu }

Implementacja algorytmu w postaci programu w języku C++

#include <stdio.h>

#include <conio.h>

int a, b, min; //zmienne globalne

//do przechowywania danych

// Obliczanie min(a,b)

void main(void) // glowna (startowa) funkcja programu

{

printf("Wprowadz dane \n");

scanf("%d", &a); scanf("%d", &b);

if (a<b) { min=a; printf("\nMin = a = %d \n", a); }

else

if (b<a) { min=b; printf("\nMin = b = %d \n", b); }

else { min=a; printf("\nMin = a = b = %d \n", a); }

} // koniec programu

Problem 2. Znaleźć minimum spośród n wczytanych liczb a0, a1, ... , an-1. Wyprowadzić wartość minimum.

Opis słowny algorytmu

Po wczytaniu danych wejściowych ai, dla i=0, ... , n-1, przyjąć min = a0. Jeśli są jeszcze elementy do sprawdzenia (0<n-1), to sprawdzić czy ai < min, dla i=1? Jeśli tak, to podstawić min = ai. Powtórzyć sprawdzenie dla i=2, ... , n-1. Wyprowadzić wynik.

Opis algorytmu za pomocą listy kroków

Krok 1. Wczytaj dane a0, ..., an-1.

Krok 2. Podstaw min = a0 oraz i = 1.

Krok 3. Jeśli i > n-1 (nie ma więcej elementów), to przejdź do kroku 6.

Krok 4. Jeśli ai < min, to podstaw min = ai.

Krok 5. Podstaw i = i + 1. Przejdź do kroku 3.

Krok 6. Wyprowadź wartość min.

Krok 7. Zakończ program.

Schemat blokowy algorytmu znajdowania min(a0, ..., an-1)

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
Nie Tak

0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

Implementacja algorytmu w postaci programu w języku Pascal

uses crt; {moduł zawierający procedurę clrscr}

{ Obliczanie min(a[0],a[1], ... ,a[n-1]) }

const ROZ = 10; { stala - maksymalny rozmiar tablicy}

{definicja typu tablicy}

type ttab = array[1..ROZ] of integer;

Var

{a - zmienna tablicowa typu ttab - rezerwacja pamieci}

{min - zmienna przechowujaca wartosc minimum}

a: ttab;

min: integer;

n,i: integer; {zmienne pomocnicze}

{n < ROZ liczba wprowadzanych (losowanych) elementow}

{i zmienna pomocnicza indeksujaca kroki petli}

Begin {poczatek programu}

clrscr; { wyczysc ekran }

randomize; { inicjuj generator liczb losowych }

writeln('Wprowadz liczbe elementow 0 < n <= ', ROZ);

readln(n);

if (0<n) and (n<=ROZ) then { czy n < = ROZ ? }

begin

for i:=1 to n do

begin {losowanie danych z zakresu od 0 do 99 }

a[i]:= random(100); writeln('a[', i, '] = ', a[i]);

end;

i:=1; { wart. pocz. i }

min:= a[1]; { wartosc pocz. minimum }

i:=i+1;

while (i<=n) do

begin

if (a[i] < min) then min:= a[i];

i:= i+1;

end;

writeln; { przejscie do nowej linii }

writeln('Wartosc minimum = ', min);

end

else

begin

writeln; writeln('Wartosc n wykracza poza zakres !');

writeln('Uruchom ponownie program !');

end;

readln; { czekaj na enter }

End. { koniec programu }

Przykładowe wyniki:

Wprowadz liczbe elementow 0 < n <= 10

5

a[1] = 93

a[2] = 1

a[3] = 93

a[4] = 73

a[5] = 6

Wartosc minimum = 1

Implementacja algorytmu w postaci programu w języku C++

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

// Obliczanie min(a[0],a[1], ... ,a[n-1])

// Zmienne globalne

const ROZ = 10; // stała określająca

// maksymalny rozmiar tablicy

int a[ROZ]; //tablica - zawsze od 0, tj. a[0],...,a[ROZ-1]

int min; //wartosc minimum

void main(void) //glowna (startowa) funkcja programu;

// void - bezparametrowa

{ // Zmienne lokalne funkcji main()

int n; //liczba n < ROZ wprowadzanych

//(losowanych) elementów

int i; //zmienna pomocnicza indeksująca kroki pętli

clrscr(); // wyczyść ekran

randomize(); // inicjuj generator liczb losowych

printf("Wprowadź liczbę elementów 0 < n <= %d \n", ROZ);

scanf("%d", &n);

if (0<n && n<=ROZ) { // czy n nie przekracza ROZ?

for (i=0; i<n; i++) {

a[i] = random(100); // losowanie danych

printf("a[%d] = %d \n", i, a[i]); }

i=0; // wart. pocz. i

min = a[0]; // wart. pocz. minimum

i=i+1;

while ( !(i>n-1) ) {

if (a[i] < min) min = a[i];

i++; // i = i+1

}

printf ("\n Wartosc minimum = %d \n", min);

} else

{ printf("\nWartosc n wykracza poza zakres !\n");

printf("Uruchom ponownie program\n");

}

getch(); //czekaj na enter

}

1.4. Ogólna struktura programu w języku Pascal

Najprostszy program nie wykonuje żadnego zadania, a jedynie zawiera informacje o miejscu rozpoczęcia głównej procedury programu i miejscu jej zakończenia.

Przykład 1. Najprostszy program.

0x08 graphic

BEGIN

{ komentarz - najprostszy program w języku Pascal }

END.

Przykład 2. Wyprowadzenie napisu na ekran i zatrzymanie programu

w oczekiwaniu na Enter.

0x08 graphic

Begin {poczatek programu}

writeln('To jest tekst!');

readln; { czekaj na enter }

End. { koniec programu }

Przykład 3. Obliczanie sumy dwóch liczb całkowitych a i b.

Schemat blokowy

0x08 graphic

Program w języku Pascal

uses crt; { modul definiujacy procedure clrscr }

{ obliczanie sumy liczb całkowitych}

Var a, b: integer; { zmienne calkowite od -32768.. 32767 }

suma: longint; { suma - zmienna calkowita o wiekszym }

{ zakresie od -2147483648..2147483647 }

Begin {poczatek programu}

clrscr; { czyszczenie ekranu }

write('Podaj liczbe calkowita a = '); readln(a);

write('Podaj liczbe calkowita b = '); readln(b);

suma:=a+b;

writeln('Suma liczb = ', suma);

readln; { czekaj na enter }

End. { koniec programu }

Ogólna struktura programu w języku Pascal

program nazwa_programu; {Nagłówek programu - opcjonalny}

{ SEKCJA DEKLARACJI }

uses lista_nazw_modułów ;

const sekwencja_definicji_stałych ; {Definicje stałych}

type sekwencja_definicji_typów ; {Definicje typów}

label lista_etykiet ; {Deklaracja etykiet}

var sekwencja_deklaracji_zmiennych ; {Deklaracje zmiennych}

{Definicje_składowych_procedury_1 - kod procedury}

procedure nazwa_procedury_1 ; {Definicje procedur}

{Definicje_składowych_procedury_2 - kod procedury}

procedure nazwa_procedury_2 ( lista_parametrów ) ;

. . .

function nazwa_funkcji_1 : typ_wartosci ; {Definicje funkcji}

{Definicje_składowych_funkcji_1 - kod funkcji}

{Definicja_składowych_funkcji_2 - kod funkcji}

function nazwa_funkcji_2( lista_parametrów ) : typ_wartości ;

. . .

{ SEKCJA INSTRUKCJI }

begin

instrukcja_1 ;

instrukcja_2 ;

. . .

instrukcja_N ;

end .

1.5. Programowanie Obiektowe - Wstęp

Turbo Pascal w wersji 5.5 i wyższych dopuszcza struktury typu obiekt (ang. object), które podobnie jak rekordy składają się z pól danych oraz z dodatkowych pól zawierających zgłoszenia tzw. metod, a więc funkcji i procedur operujących na tych danych. Taki sposób mieszania danych nosi nazwę enkapsulacji.

Pola metod w deklaracjach object są podobne do deklaracji forward funkcji czy procedur. Część implementacyjna, a więc opis metod, pojawia się w następnej kolejności, już po ich zgłoszeniu i poza deklaracją obiektu.

Nazwa obiektu kwalifikuje nazwę metody (podobnie jak nazwa pola rekordu jest na zewnątrz kwalifikowana nazwą zmiennej określonego typu rekordowego wraz z kropką i nazwą wewnętrznej pola. Np. a.x→ rekord a; pole x).

Jako przykład podam krótki program (Neil J. Rubenking), który wyświetla standardowe powitanie Hello na ekranie terminala.

TYPE

message = OBJECT

words : string;

CONSTRUCTOR Init(is : String);

PROCEDURE Say;

END;

CONSTRUCTOR Message.Init(is : String);

BEGIN self.words := iS; END;

PROCEDURE Message.Say;

BEGIN Write(self.words); END;

VAR H: message;

BEGIN

H.Init('OO Hello');

H.Say

END.

Program ten deklaruje obiekt message, który składa się z pola danych o nazwie words oraz dwóch metod: InitSay. Metoda Init zwana constructor jest specjalną metodą, która inicjuje dane typu message. Musi ona być wywołana przed użyciem obiektu. W programie Hello wywołanie to odbywa się przez

H.Init('OO Hello');

Dopiero po tym, łańcuch 'OO Hello' jest dostępny dla metody Say, która drukuje go. Dzieje się to w linii

H.Say;

Rozszerzymy teraz program Hello tak, by pokazać bardzo podstawowe mechanizmy programowania obiektowego.

Załóżmy, że chcemy teraz wypisąć łńcuch 'OOP Hello' w dowolnym, ale określonym przez współrzędne, miejscu ekranu. W przypadku starego stylu programowania musieli byśmy napisać nowy program. W OOP (OOP - Object Oriented Pascal - Pascal Obiektowo Zorientowany) można w prosty sposób rozszerzać istniejące programy w dowolnym kierunku.

Dziedziczenie

Następny fragment programu (Hello2.pas) jest biblioteką Turbo Pascala. Rozpoczyna go identyczna jak poprzednio deklaracja obiektu message. W następnej części zdefiniowany jest obiekt o nazwie placeMessage, którego zmiennymi są wielkości zawierające współrzędne położenia napisu na ekranie. W następnej kolejności zdefiniowano obiekt colorMessage, w którym dodatkowo zadeklarowany został kolor tekstu napisu. Wszystkie wprowadzone obiekty dotyczą napisu, lecz każdy z nich różni się od poprzedniego jakąś dodatkową cechą czy możliwością, które opisują własności napisu, a to jego położenie, a to kolor, itd.

UNIT Hello2;

(* Turbo Pascal 5.5 version *)

INTERFACE

USES Crt;

TYPE

message = OBJECT

words : String;

CONSTRUCTOR Init(is : String);

PROCEDURE Say; virtual;

END;

placeMessage = OBJECT(message)

X, Y : Byte;

CONSTRUCTOR InitPM(is : String; iX, iY : Byte);

PROCEDURE Say; virtual;

END;

colorMessage = OBJECT(placemessage)

color, SaveColor : Byte;

CONSTRUCTOR InitCM(iS : String; iX, iY, iColor : Byte);

PROCEDURE Say; virtual;

END;

MsPt = ^Message;

PMpt = ^PlaceMessage;

CMpt = ^ColorMessage;

MsgList = ^MsgNode;

MsgNode = RECORD

data : MsPt;

next : MsgList;

END;

List = OBJECT

Nodes : MsgList;

CONSTRUCTOR Init;

PROCEDURE Add(MP : MsPt);

PROCEDURE Show;

END;

IMPLEMENTATION

CONSTRUCTOR Message.Init(iS : String);

BEGIN self.words := iS; END;

PROCEDURE Message.Say;

BEGIN Write(self.words); END;

CONSTRUCTOR

PlaceMessage.InitPM(iS : String; iX, iY : Byte);

BEGIN

Message.Init(iS);

self.X := iX;

self.Y := iY;

END;

PROCEDURE PlaceMessage.Say;

BEGIN

GotoXY(self.X, self.Y);

Message.Say;

END;

CONSTRUCTOR

ColorMessage.InitCM(iS : String; iX, iY, iColor : Byte);

BEGIN

PlaceMessage.InitPM(iS, iX, iY);

self.Color := iColor;

END;

PROCEDURE ColorMessage.Say;

BEGIN

self.SaveColor := TextAttr;

TextAttr := self.Color;

PlaceMessage.Say;

TextAttr := self.SaveColor;

END;

CONSTRUCTOR List.Init;

BEGIN self.Nodes := NIL; END;

PROCEDURE List.Add(MP : MsPt);

VAR P : MsgList;

BEGIN

New(P);

P^.data := MP;

P^.next := self.nodes;

self.nodes := P;

END;

PROCEDURE List.Show;

VAR P : MsgList;

BEGIN

P := self.nodes;

WHILE P <> NIL DO

BEGIN

P^.data^.say;

P := P^.next;

END;

END;

END.

Po słowie OBJECT, w przypadku obiektu placeMessage, umieszczone zostało w nawiasie słowo message i podobnie, po zgłoszeniu obiektu colorMessage umieszczono słowo placeMessage. Oznacza to, że zmienne typu placeMessage są wciąż zmiennymi message, tzn. dziedziczą wszystkie ich własności, a więc pola danych i metody. Podobnie pochodne zmienne typu colorMessage przejmą po swoich przodkach, w tym wypadku po obiektach messageplaceMessage. Dodatkowo, zmienne te mają jeszcze inne, swoje, własności. Mamy tu taką sytuację, że typy pochodne, a więc spadkobiercy, dziedziczą po swoich przodkach pewne cechy. Nazywa się je również typami potomnymi. Typy potomne mają na ogół dodatkowe własności, inne niż ich przodkowie.

Przedyskutujmy to dokładnie na przykładzie placeMessage. W porównaniu z messsage, placeMessage jest typem, który rezerwuje dwa pola (dodatkowo do pola words), w których przechowywane będą współrzędne x, y położenia napisu na ekranie. Zmieniona również została metoda constructor, która teraz nosi nazwę InitPM i może inicjować zmienne typu placeMessage. Inna jest też metoda Say. Wypisuje ona łańcuch na ekran w miejscu określonym przez x, y.

Metody, które można zmieniać w typach potomnych opatruje się słowem virtual (wirtualna). Tak jest z metodą Say w obiekcie message.

Nie można zmieniać nagłówka metody wirtualnej w typie potomnym.

Metoda placeMessage.InitPm ustawia własne pola x, y. Na początku woła ona dziedziczoną metodę message.Init w celu inicjacji pola words, a następnie ustawia x, y. Metoda placeMessage.Say po przemieszczeniu kursora do miejsca ekranu (x, y) (zostały one dodatkowo opatrzone słowem Self; patrz dalej) wywołuje metodę swojego przodka message.Say aby wypisać tam dany łańcuch. Obiekt placeMessage jest przodkiem obiektu colorMessage i potomkiem pierwotnego obiektu message.

Następne deklaracje w jednostce Hello2 ustalają wskazy do różnych obiektów w zadanej hierarchii oraz definiują listę połączoną wskazów do oryginalnego typu message. Ta lista staje się polem danych w obiekcie List, którego metody, dodają (Add) oraz pokazują (Show) komunikaty (messages).

W OO Pascalu typy potomne są w bardzo szczególny sposób zgodne z ich przodkami. Polega to na tym, że

Wskaz do zmiennej typu przodka może wskazywać zmienne wszystkich typów potomnych.

Procedura, której parametr formalny opatrzony słowem VAR jest procedurą (funkcją) przyjmie jako argument aktualny zmienną dowolnego typu potomnego (też procedurę). Obiekt zachowuje przy tym swoją indywidualność, a wywoływane metody wirtualne będą właściwymi dla niego metodami.

W przykładzie Hello2 parametrami aktualnymi procedury List.Add mogą być zmienne dowolnego z trzech zadeklarowanych typów: message, placeMessage, colorMessage.

Polimorfizm

Metoda List.Show bierze kolejne elementy listy i wywołuje ich metody Say. Nie zwraca przy tym uwagi na szczegóły dotyczące obiektu. P^.data^ jest obiektem, którego typ nie nie jest znany aż do chwili wywołania. Mamy tu doczynienia z tzw. obiektem polimorficznym, o potencjalnie różnych własnościach. Jeśli kompilator napotyka na zwykłą procedyrę statyczną wówczas może od razu odwołać się do konkretnego adresu. Jest to metoda tzw. wczesnego kojarzenia, lub związania (early binding). W przypadku metod wirtualnych obiektu polimorficznego, kompilator nie może z góry określić adresu. W czasie wykonywania się programu wybierana jest właściwa metoda, zależna od szczególnego typu zmiennej obiektowej. Takie kojarzenie wywołań nosi nazwę późnego.

Przykład

Program UseHello, pokazany na następnym diagramie, ilustruje zadziwiające własności obiektów polimorficznych.

PROGRAM UseHello;

(* 5.5 *)

USES Crt, hello2;

TYPE

MMpt = ^MovingMessage;

MovingMessage = OBJECT(ColorMessage)

width : Byte;

CONSTRUCTOR InitMM(iS : String; iX, iY, iColor, iWid : Byte);

PROCEDURE Say; virtual;

END;

CONSTRUCTOR

MovingMessage.InitMM(iS : String; iX, iY, iColor, iWid : Byte);

BEGIN

ColorMessage.InitCM(iS, iX, iY, iColor);

self.width := iWid;

END;

PROCEDURE MovingMessage.Say;

VAR marquee : String;

P : Byte;

BEGIN

FillChar(marquee, SizeOf(marquee), ' ');

marquee[0] := chr(self.width);

P := 1;

self.SaveColor := TextAttr;

TextAttr := self.color;

REPEAT

GotoXY(self.X, self.Y);

Write(marquee);

MOVE(marquee[2], marquee[1], pred(self.width));

marquee[self.width] := self.words[P];

P := succ(P MOD length(self.words));

sound(20); Delay(60); NoSound;

delay(75);

UNTIL KeyPressed;

TextAttr := self.SaveColor;

END;

VAR

TheList : List;

BEGIN

ClrScr;

TheList.Init;

TheList.Add(new(MMpt, InitMM(' O O P ! ', 9,16,1C,60))); TheList.Add(new(CMpt, InitCM(Hello in living color! , 20,10,4E)));

TheList.Add(new(PMpt, InitPM('Hello from down under ',1,25)));

TheList.Add(new(MsPt, Init('Hello, World! ')));

TheList.Show;

END.

Program UseHello korzysta wprost z biblioteki Hello2,. Deklaruje on dodatkowy typ, obiekt movingMessage, który jest rozszerzeniem obiektu colorMessage. Obiekt ten nie istniał w bibliotece Hello2 w momencie jej kompilacji, a więc w chwili tworzenia modułu Hello2.tpu. Mimo to, metody List.Add oraz List.Show radzą sobie ze zmiennymi nowego typu! Ma tu miejsce zgodność typów potomnych z ich przodkami.

Zwróćmy uwagę na użycie procedury New. Jeśli chcemy umieściś w pamięci komputera zmienną dynamiczną z jej metodami wirtualnymi to procedurę New wywołujemy z parametrami, którymi są nazwa obiektu i konstruktor tego obiektu. Np.

New(MojObiekt, Init(1, 2, 3);)

Po drugie, można używać New z argumentem typu pointer tak jakby była to funkcja, zwracająca wskaz do zmiennej danego typu. Można więc tworzyć wskazy i przekazywać je jako parametry bez potrzeby tworzenia i inicjowania zmiennych tymczasowych.

Podsumowanie

Program Hello ilustruje cztery podstawowe własności programowania obiektowego, którymi są:

Z a d a n i e 1.  Napisz program Pomocnik, który na podstawie zadanego numeru wyświetla linię tekstu dowolnej długości. Taki program może zarządzać bazą, która zawiera te linie tekstu (może je więc dodawać, usuwać, wypisać). Wykorzystaj OOP.

Parametr Self

Załóżmy, że w programie występuje definicja typu rekordowego (Marciniak)

type nowe_xy=record

x, y: integer;

kolor: byte;

end;

oraz definicja typu obiektowego

type xy=object

x, y: integer;

procedure wspolrzedne(punkt: nowe_xy)

end;

Zadaniem metody współrzędna jest przypisanie wartości pól x, y rekordu nowe_xy polom x, y obiektu xy. W celu uniknięcia konfliktu identyfikatorów definicja metody powinna być następująca:

procedura xy.wspolrzedne(punkt: nowe_xy);

begin

with punkt do begin

Self.x:=x;

Self.y:=y

end

end;

Wystąpił tu parametr Self, wskazujący na to, że xy z lewej strony instrukcji przypisania; są to własne pola x i y obiektu (nie pola rekordu xy), w którym znajduje się metoda.

Zaznaczyć należy, że jeśli nie używa się instrukcji wiążącej with to parametr Self nie jest konieczny.

procedure xy.wspolrzedne(punkt: nowe_xy);

begin

x:=punkt.x;

y:=punkt.y;

end;

Kod

wynikowy

z bibliotek

Kod

startowy

Kod

wykonywalny

programu

Kod

wynikowy

programu

Kod

źródłowy programu

Łączenie

Kompilacja

START

Wprowadź

Wyprowadź

Operacja

Warunek

?

Zmienna =

Wyrażenie =

Nazwa funkcji

Zadania

Nr

Strona

| Nr

STOP

START

Wprowadź a = ?

Wyprowadź b = ?

a < b

min = a

Pisz

min = a

b < a

min = b

Pisz

min = b

min = a

Pisz

min = a = b

STOP

START

Wprowadź n = ?

i = 0

Wprowadź ai = ?

i = i+1

i > n-1

i = 0

min = a0

i = i+1

i > n-1

Pisz min

STOP

ai < min

min = ai

0x01 graphic

Nie

Nie

Tak

Tak

0x01 graphic

0x01 graphic

0x01 graphic

Nie

Nr (Symbol)

lub



Wyszukiwarka

Podobne podstrony:
SI wstep
Zajęcie1 Wstęp
Wstęp do psychopatologii zaburzenia osobowosci materiały
układ naczyniowy wstep
ZMPST Wstep
Dekalog 0 wstęp
1 WSTEP kineza i fizykot (2)
01 AiPP Wstep
wstęp neg
Wyklad I Problemy etyczne Wstep
ochrona srodowiska wstep
Tajemnica ludzkiej psychiki wstep do psychologii
PS 1 Psychologia społeczna wstep

więcej podobnych podstron