background image

KURS 

PASCALA 

WSTĘ

 

Od autora

 

        Chciałbym wszystkim przypomnieć, Ŝe język Turbo Pascal (okrojony Borland Pascal 7.0) jest bardzo 
popularnym językiem programowania, przeznaczonym dla szrokiego kręgu odbiorców, przede wszystkim dla 
nieprofesjonalistów. Język Turbo Pascal, wbrew pozorom, nie jest wcale taki trudny do opanowania, moŜna się 
go stosunkowo szybko nauczyć. Najczęściej jest on preferowany w szkołach średnich (uczą się go nawet 
studenci), stosowany jako "przedsmak" do języków jeszcze bardziej skomplikowanych tj. C/C++ czy Assebler.

 

        Kurs ten został napisany w duŜej mierze na podstawie ksiąŜki Andrzeja Marciniaka pt. "Turbo Pascal 7.0 z 
elementami programowania", z ksiąŜki zaczerpnięte zostały poszczególne definicje elementów języka.

 

LEKCJA 1 

Słowa kluczowe i dyrektywy języka

 

        W wersji 7.0 języka Turbo Pascal słowem kluczowym nazywamy kaŜdy z 49. następujacych wyrazów 
języka angielskiego:

 

 

and

 

file

 

nil

 

shr

 

array

 

for

 

not

 

string

 

asm

 

function

 

object

 

then

 

begin

 

goto

 

of

 

to

 

case

 

if

 

or

 

type

 

const

 

implementation

 

packed

 

unit

 

constructor

 

in

 

procedure

 

until

 

destructor

 

inherited

 

program

 

uses

 

div

 

inline

 

record

 

var

 

do

 

interface

 

repeat

 

while

 

downto

 

label

 

set

 

with

 

else

 

mod

 

shl

 

xor

 

end

 

 

 

 

 

 

 

 

background image

Słowa kluczowe są integralną częścią języka TP i są zastrzeŜone, tzn. nie mogą być zdefiniowane przez 
programistę.

 

        Oprócz słów kluczowych w wersji 7.0 Pascal-a występują dyrektywy języka. Dyrektywą jest kaŜdy z 10. 
następujących wyrazów:

 

absolute

 

far

 

near

 

public

 

assembler

 

forward

 

private

 

virtual

 

external

 

interrupt

 

 

 

 

 

 

W odróŜnieniu od słów kluczowych, dyrektywy języka nie są zastrzeŜone - podane wyrazy mogą więc być 
identyfikatorami zdefinowanymi przez programistę, co jednak nie jest zalecane. Penym wyjątkiem są dyrektywy 
private i public, które w obiektach (ale tylko w nich) są słowami zastrzeŜonymi.

  

LEKCJA 2 

Jak wygląda program w Pascalu ?

 

        Podstawowych pojęć jakimi się operuje programując w TP jest wprawdzie niewiele i nie są one trudne do 
zrozumienia, ale niewiedząc "z czym je jeść" nie mamy co zabierać się do programowania - wszystkie te pojęcia 
składają się na szkielet programu. Oto lista tych pojęć:

 

Struktura programu 
Deklaracja modułów 
Etykiety 
Stałe 
Typy danych 
Zmienne 
Procedury i funkcje

 

  

        Program napisany w TP 7.0 składa się z nagłówka programu (PROGRAM), deklaracji modułów, bloku i 
znaku . (kropka). W nagłówku programu podaje się zwykle jego nazwę. Za pomocą deklaracji modułów określa 
się moduły standardowe i moduły uŜytkownika. Blok składa się z opisu danych i części wykonawczej, a kropka 
kończy tekst programu. Dopuszcza się moŜliwość opuszczenia nagłówka (jest on pomijany przez kompilator), 
deklaracji modułów i opisu danych, a wiersz programu nie moŜe zawierać więcej niŜ 127 znaków. Oto szkielet 
programu paskalowego:

 

   

PROGRAM Nazwa_Programu; {Nagłóewk programu} 
USES {Deklaracja modułów} 
{Początek części opisowej} 
LABEL 
CONST 
TYPE 
VAR 
PROCEDURE 
FUNCTION 
{Koniec części opisowej} 
BEGIN 

background image

{Część wykonawcza programu} 
END.

  

  

  

        Deklaracja modułów (USES) jest klauzurą pozwalającą nam zdefiniować dowolną ilość modłów w 
naszym programie, np. 
 
   USES CRT,DOS; 
 
PowyŜsza deklaracja definiuje dla naszego programu dwa standardowe moduły DOS i CRT.

 

  

        Etykiety (LABEL) deklarujemy zaraz po deklaracji modułów klauzurą USES, powodują one skok do 
określonej części programu - wywołujemy je słowem kluczowym GOTO, np.

 

   

LABEL skok_1,skok_2; 
   ... 
BEGIN 
  GOTO skok_1; 
     ... 
     ...{Jakieś funkcje czy procedury.} 
     ... 
  skok_1: Writeln('Skok do etykiety skok_1'); 
  skok_2: Writeln('Skok do etykiety skok_2'); 
END. 

  

PowyŜszy przykład obrazuje skok do etykiety skok_1. Podczas tej operacji omijane są wszelkie procedury i 
funkcje znajdujące się w wykropkowanych miejscach.

 

  

        Stałe (CONST) deklarujemy po deklaracji etykiet (LABEL), gdy zadeklarujemy jakąś stałą to w dalszej 
części programu nie moŜemy przypisać jej juŜ innej wartości niŜ wartość początkowa. Zmiennym nie musimy 
przypisywać konkretnego typu danych, lecz w niektórych, bardziej złnoŜoych programach jest to wskazane, np.

 

   

CONST MaxWysokosc = 100; 
       MaxPredkosc = 10;  
lub 
 
CONST MaxWysokosc : Typ = Wartosc; 
       MaxPredkosc : Typ = Wartosc; 

  

W drugim przykładzie Typ oznacza dowolny typ danych, wtedy wartość stałej przypisujemy zgodnie z typem.

  

background image

 
        Typy (TYPE) deklarujemy po deklaracji stałych (CONST). KaŜdą zmienną w programie naleŜy 
zadeklarować tzn. określić jej nazwę oraz wartości, które moŜe ona przyjmować. Zbiór wartości zmiennej 
nazywa się typem zmiennej. Typy dzielimy na standardowe (predefiniowane, nie wymagające opisu) i 
niestandardowe (wprowadzane ręcznie przez programistę). O typach będzie jeszcze mowa w następnych 
lekcjach, więc podam tu tylko przykłady, np.

 

   

TYPE Dzien = (pon, wt, sr, czw, pt, sob, nie); 
     Numer = Integer; 

 
        

Zmienne (VAR) deklarujemy po deklaracji typów (TYPE). Jak juŜ wspomniałem, wszystkie zmienne 

uŜywane w programie powinny być zadeklarowane. Deklaracje zmiennych składają się ze słowa kluczowego 
VAR, po którym następuje wykaz deklaracji. KaŜdą zadeklarowaną zmienną (wartość zmiennej) moŜemy w 
głebi programu dowolnie definiować (przypisywać jej inne wartości), np.

 

   

VAR Wynik = Byte; 
... 
BEGIN 
   Wynik:=0; {Wartość początkowa} 
   ... 
   Wynik:=10; {Wartość przypisana później} 
END. 

        P

rocedurę (PROCEDURE) lub funkcję (FUNCTION) deklarujemy po deklaracji zmiennych (VAR). 

Są to wyodrębnione części programu, stanowiące pewną całość, posiadające jednoznaczną nazwę i ustalony 
sposób wymiany informacji z pozostałymi częściami programu. Procedury i funkcje są stosowane do wykonania 
czynności, które mogą być wykorzystane w róŜnych programach lub do wykonania czynności wielokrotnie 
powtarzanych przez dany program. RóŜnica pomiędzy procedurą a funkcją polega na sposobie przekazywania 
wartości. Zadaniem procedury jest wykonanie pewnej sekwencji czynności, polegających zwykle na obliczaniu 
jedej lub wielu wartości. Natomiast zadaniem funkcji jest obliczenie jedej wartości (typu prostego lub 
wskaźnikowego). Odmienne są teŜ sposoby wywołania procedur i funkcji, np.

 

   

Definicja procedury: 
 
PROCEDURE Nazwa_Procedury(lista_parametrów); 
...Część_opisowa 
BEGIN 
...Ciąg_instrukcji 
END; 
 
W definicji procedury listę parametrów moŜemy pominąć. 
 
Definicja funkcji: 
 
FUNCTION Nazwa_Funkcji(lista_parametrów): Typ_wyniku; 
...Część_opisowa 
BEGIN 
...Ciąg_instrukcji 
END; 

background image

  

W obu przypadkach lista parametrów zawiera deklarację parametrów, przy czym poszczególne deklaracje 
oddziela się średnikami. W przypadku funkcji w ciągu instrukcji musi wystąpić co najmniej jedna instrukcja 
przypisania w postaci:

 

   

Nazwa_Funkcji:=WyraŜenie

  

powodująca przypisanie wartości pod nazwę funkcji, przy czym co najmniej jedna z tych instrukcji musi być 
wykonana po wywołaniu funkcji. Typ wyniku funkcji jest określony za pomocą identyfikatora typu.

 

 

LEKCJA 3 

 

Typy danych i ich krótki opis

 

        Co to jest mniej więcej "typ" pisałem w poprzednim dziale, a w niniejszym opiszę dość dokładnie 
poszczególne typy wraz ze sposobami ich definicji w programie.

 

Podział typów danych:

 

   

 Typy proste

 

 Typy porządkowe

 

 Typ wyliczeniowy 
 Typy całkowite 
 Typy logiczne 
 Typ znakowy 
 Typy okrojone

 

 Typy rzeczywiste

 

 Typy łańcuchowe 
 Typy strukturalne

 

 Typy tablicowe 
 Typ rekordowy 
 Typ zbiorowy 
 Typ plikowy

 

 Typy wskaźnikowe 
 Typy proceduralne 
 Typ obiektowy

 

  

        Typy proste są podstawowymi typami języka Turbo Pascal i za ich pomocą określa się bardziej złoŜone 
struktury danych. Wszystkie typy proste składają się ze skończonego i uporządkowanego zbioru wartości. Dzięki 
temu na wartościach tych typów moŜemy m.in. wykonywać operacje porównań. Typy proste dzielimy na typy 
porządkowe i typy rzeczywiste.

 

  

        Typami porządkowymi nazywamy wszystkie typy proste z wyjątkiem typów rzeczywistych. WyróŜnienie 
to jest spowodowane faktem, Ŝe typy rzeczywiste często nie mogą występować w kontekście dozwolonym dla 

background image

innych typów prostych. Dla wartości kaŜdego typu porządkowego są określone wartości poprzednie i następne (z 
wyjątkiem wartości krańcowych). Do typów porządkowych zaliczamy: typ wyliczeniowy, typy całkowite, 
logiczne, typ znakowy i typy okrojone.

 

  

        Typ wyliczeniowy stosuje się zwykle dla zbiorów o niewielkiej liczbie elementów, na których nie 
wykonuje się operacji arytmetycznych. Definicja jednego typu wyliczeniowego jest następująca: 
 
   TYPE identyfikator_typu = (lista_identyfikatorów); 
 
Elementy typu wyliczeniowego są uporządkowane zgodnie z kolejnością ich wyliczenia w definicji typu i 
posiadają liczby porządkowe odpowiednio 0,1,2 itd.

 

   

Przyklady: 
 
TYPE Uczniowie = (Antek, Franek, Zenek);  
     {Antek ma 0, Franek ma 1, a Zenek 2} 
     P_roku = (wiosna, lato, jesien, zima); 

  

        

Typy całkowite są w języku TP predefiniowane i nie wymagają opisu w programie. Wszystkie typy 

całkowite są podzbiorami zbioru liczb całkowitych. Wśród typów całkowitych wyróŜniamy:

 

   

 ShortInt, przedział od -128 do 127 
 Byte, przedział od 0 do 255 
 Integer, przedział od -32768 do 32767 
 Word, przedział od 0 do 65535 
 LongInt, przedział od -2147483648 do 2147483647

  

  

   

Przyklad: 
 
Przypuśćmy, Ŝe zdefiniowaliśmy nowy typ: 
 
   TYPE Liczba = Integer; 
 
W takim razie poniŜsza deklaracja 
 
   VAR i,j: Liczba; 
 
jest równowaŜna deklaracji 
 
   VAR i,j: Integer

  

background image

        

Standardowymi typami logicznymi są typy BooleanByteBoolWordBool i LongBool. Wartości typów 

logicznych są oznaczone za pomocą dwu predefiniowanych literałów (stałych): True i False, oznaczających 
odpowiednio wartości logiczne fałsz i prawda, przy czym w sensie uporządkowania stała False poprzedza stałą 
True. Liczbami porządkowymi elementów typu Boolean są tylko 0 (False) i 1 (True). Elemanty pozostałych 
typów logicznych mogą posiadać inne (wyŜsze) liczby porządkowe.

 

  

        Do oznaczenia typu znakowego słuŜy predefiniowany identyfikator Char. Elementami typu znakowego są 
znaki ASCII, z których kaŜdy jest pamiętany w jednym bajcie pamięci.

 

  

        Typy okrojone słuŜą do ograniczania zakresów wartości dowolnego z dotychczas opisanych typów 
porządkowych. Definicja jednego typu okrojonego ma postać 
 
   TYPE identyfikator_typu = stała .. stała; 
 
Pierwsza stała podaje ograniczenie dolne i nie moŜe być większa od drugiej - ograniczenia górnego. Stałe te 
muszą być tego samego typu porządkowego.

  

   

Przyklad: 
 
   TYPE Litery = 'A' .. 'Z'; 

  

        

Do typów prostych naleŜą takŜe standardowe typy rzeczywiste, które jednak nie są typami porządkowymi. 

KaŜdy z dostępnych typów rzeczywistych jest dyskretnym i skończonym podzbiorem zbioru liczb 
rzeczywistych. Dostępnych jest pięć standardowych typów rzeczywistych o następujących predefiniowanych 
identyfikatorach:

 

   

 Real, elementy zajmują po 6 bajtów pamięci 
 Single, typ o pojedyńczej długości (4 bajty pamięci) 
 Double, typ o podwójnej długości (8 bajtów pamięci) 
 Extended, typ o rozszerzonej długości (10 bajtów pamięci) 
 Comp, elementy to liczby całkowite z przedziału od -2

63

+1 do 2

63

-1

 

  

        Typy łańcuchowe słuŜą do reprezentowania ciągu znaków, w tym niewidocznego znaku spacji. 
Elementami typu łańcuchowego są łańcuchy o długości od 0 do długości podanej w definicji typu 
łańcuchowego. Typ ten definiuje się następująco: 
 
   TYPE identyfikator_typu = String[rozmiar]; 
 
lub 
 
   TYPE identyfikator_typu = String
 
gdzie rozmiar jest liczbą typu Byte. Brak wyspecyfikowania rozmiaru powoduje domyślne przyjęcie długości 
255 znaków (warość maksymalna).

  

background image

   

Przykład: 
 
   TYPE Nazwisko = String[20]; 

        

Typy stukturalne stosuje się do opisu obiektów złoŜonych, przy czym dany obiekt moŜemy opisać na 

kilka róznych sposobów. KaŜdy z typów strukturalnych definiowany jest przez podanie typów składowych i 
metody strukturalizacji, która zarazem określa sposób dostępu do elementów składowych. W ogólności definicja 
pojedyńczego typu strukturalnego ma postać: 
 
   TYPE Identyikator_typu = Opis_typu_strukturalnego; 
 
przy czym opis typu strukturalnego moŜe być opisem typu tablicowego, rekordowego, zbiorowego lub 
plikowego.

 

        Typ tablicowy, a konkretnie tablica składa się z ustalonej liczby elementów tego samego typu, zwanego 
typem składowym, który moŜe być zarówno typem prostym lub łańcuchowym, jak i typem strukturalnym. Za 
pomocą tablic są reprezentowane regularne układy danych, np. wektory i macierze. Dostęp do poszczególnych 
elementów tablic uzyskuje się za pomocą indeksowania. Indeksem moŜe być dowolne wyraŜenie, którego 
wartość jest zgodna w sensie przypisania z typem indeksowym. Dopuszczalny zakres indeksów jest podany w 
definicji typu tablicowego. Definicja pojedynczego typu tablicowego ma postać: 
 
   TYPE Identyfikator_typu = array[typy_indeksowe] of typ_składowy; 
 
gdzie typy indeksowe są opisami typu porządkowego (z wyjątkiem typu LongInt), przy czym poszczególne 
opisy oddziela się przecinkami. Typ składowy oznacza dowolny typ.

  

   

   

Przykłady: 
 
   TYPE Macierz = array[1..20,1..30] of Real
        Tablica = array[Boolean,1..20,znak] of Char

  

        

Typem rekordowym, a dokładniej rekordem nazywamy złoŜoną strukturę danych, której składowe, 

zwane polami, mogą mieć rózne charakterystyki (naleŜeć do róŜnych typów). Poszczególne pola mogą być same 
strukturami złoŜonymi, przy czym liczba pól rekordu jest ustalona. Definicja typu rekordowego określa typ i 
identyfikator dla kaŜdego pola. Definicja ta rozpoczyna się słowem kluczowym record, po którym podaje się 
deklarację kaŜdego pola, a kończy słowem kluczowym end. Poszczególne deklaracje pól oddziela się 
ś

rednikami. Ostatnia deklaracja moŜe być wariantowa (case .. of). Definicja pojedynczego typu rekordowego ma 

postać:

 

   

TYPE Identyfikator_typu = record 
                              Lista_deklaracji_pól 
                          end

  

gdzie kaŜda z deklaracji pól ma postać:

 

background image

   

lista_nazw_pól : opis_typu; 

  

a ostatnia deklaracja moŜe mieć postać (deklaracja wariantowa):

 

   

case deklaracja_pola_wyróŜnikowego of wykaz_wariantów; 

  

lub

 

   

case identyfikator_typu_porządkowego of wykaz_wariantów; 

  

przy czym deklaracja pola wyróŜnikowego wygląda następująco:

 

   

identyfikator_pola_wyróŜnikowego : 
              identyfikator_typu_porządkowego; 

  

lub

 

   

lista_etykiet_wyboru : (lista_deklaracji_pól); 

  

Przykłady rekordów:

 

   

TYPE Data = record 
                rok : Integer; 
                miesiac : 1 .. 12; 
                dzien : 1 .. 31; 
            end
 
TYPE Rejestry = record 
                  case Integer of 
                     1: (AX, BX, CX, DX : Word); 
                     2: (AL, AH, BL, BH, CL, CH, 
                         DL, DH : Byte); 

background image

                  end
                end

  

       

 Typ zbiorowy jest zbiorem potęgowym danego typu porządkowego, tzn. jest zbiorem wszystkich 

podzbiorów tego typu, w tym zbioru pustego. Liczba elementów typu zbiorowego nie moŜe przekraczać 256 
(przedział od 0 do 255). Definicja pojedynczego typu zbiorowego ma postać:

 

   

TYPE Identyfikator_typu = set of typy_porządkowy; 

  

Przykład:

 

   

TYPE Klasy = set of (LO_1d, LO_2d, LO_3d,LO_4d); 

  

ementami typu Klasy moŜe być dowolny podzbiór zbioru podanych nazw klas, m.in.: 
 
[ LO_1d, LO_2d ] - podzbiór dwuelementowy 
[ LO_3d ] - podzbiór jednoelementowy 
[ ] - zbiór pusty 
[ LO_1d, LO_2d, LO_3d, LO_4d ] - podzbór czteroelementowy

 

 
        Typy plikowe są ściśle powiązane z plikami. Plik jest ciągiem elementów tego samego typu, tyle Ŝe liczba 
jego składowych jest zmienna. Jest ona uzaleŜniona od przebiegu wykonywania programu, a w szczególności od 
skojarzenia pliku z fizycznym zbiorem danych. Od tablicy plik róŜni się ponadto metodą dostępu do 
poszczególnych elementów. Definicja pojedynczego typu plikowego ma postać:

 

   

TYPE Identyfikator_typu = file of opis_typu_elementów_pliku; 

  

lub

 

   

TYPE Identyfikator_typu = file

  

JeŜeli w definicji typu plikowego pominięto słowo kluczowe of i opis typu jego elementów, to przyjmuje się, Ŝe 
dany typ plikowy jest niezdefiniowany. Niezdefiniowane pliki są stosowane głównie w celu dostępu do 
fizycznych zbiorów dyskowych zgodnie z ich wewnętrznym formatem. W Pascalu istnieje predefiniowany plik 
tekstowy o nazwie Text (standardowy typ plikowy).

 

background image

Przykłady:

 

   

TYPE Dane = file of Integer
     Zbior = file
     Wyniki = Text

  

        

Typy wskaźnikowe. Zmienne dotychczas omówionych typów, tj. typów prostych i strukturalnych, 

charakteryzują się tym, Ŝe istnieją przez cały czas wykonywania tej części , w której są zadeklarowane. Są to 
tzw. zmienne statyczne. W języku Turbo Pascal występują teŜ zmienne dynamiczne reprezentujące obiekty, dla 
których pamięć jest przydzielana i zwalniana na okreśolne Ŝądanie. Zmienne te nie posiadają identyfikatorów, a 
odwołanie do nich następuje za pomocą wskaźnika. Wartościami wskaźników są elementy typu wskaźnikowego, 
które określają adresy pamięci zmiennych dynamicznych. Zastosowanie w programie zmiennych dynamicznych 
pociąga za sobą konieczność zdefiniowania odpowiednich typów wskaźnikowych. Definicja pojedynczego typu 
wskaźnikowego ma postać:

 

   

TYPE Identyfikator_typu = ^Identyfikator_typu_bazowego; 

  

Poprzyjmy to przykładem:

 

   

TYPE wskaznik = ^zapis; 
     zapis = record 
                 Tekst: String[80]; 
                 Liczba: Integer
             end

  

Definicja ta wiąŜe typ wskaznik ze zbiorem wskazań danych typu zapis. Jeśli wprowadzimy teraz deklarację:

 

   

VAR adres : wskaznik; 

  

to zmiennej wskaŜnikowej adres będą mogły być w programie przypisywane adresy pamięci danych typu zapis. 
 
W Pascalu występują dwa predefiniowane typy wskaźnikowe są to typy Pointer (zmienne tego typu są zgodne z 
dowolnym innym typem wskaźnikowym) i PChar (reprezentuje wskaźnik do łańcuchów zakończonych znakiem 
pustym). 
 
Jednym ze słów kluczowych jest słowo nil, które oznacza stałą typu wskaźnikowego nie określającą Ŝadnego 
adresu (nil wskazuje na adres pusty).

 

  

background image

        Procedury i funkcje mogą być traktowane nie tylko jako części programu wykonywane na skutek 
wywołania, ale takŜe jako elementy, które mogą być przypisywane do zmiennych i przekazywane do innych 
funkcji lub procedur jako parametry. Zmienne tego rodzaju powinny być typu proceduralnego Definicja 
pojedynczego typu proceduralnego moŜe mieć jedną z następujących postaci:

 

   

TYPE Nazwa = procedure

  

lub

 

   

TYPE Nazwa = procedure(lista_parametrów); 

  

lub

 

   

TYPE Nazwa = function: typ_wartości_funkcji; 

  

lub

 

   

TYPE Nazwa = function(lista_parametrów): 
                       typ_wartości_funkcji; 

  

Przykłady: 

   

TYPE Procedura = procedure
     Proc = procedure(x,y: Byte); 
     Funkcja = function(x,y: Byte): Boolean

  

       

 Typ obiektowy. Obiektem w Pascalu nazywa się złoŜoną strukturę danych o ustalonej liczbie elementów 

składowych, z których kaŜdy moŜe być polem lub metodą (m.in. procedurą lub funkcją), tj. elementem 
opisującym operację wykonywaną na danym obiekcie. W definicji typu obiektowego, podobnie jak w definicji 
typu rekordowego, dla kaŜdego pola specyfikuje się jego typ i identyfikator. Opis metody składa się z nagłówka 
procedury, funkcji, konstruktora lub destruktora, przy czym definicja pojedynczego typu obiektowego moŜe 
zawierać opisy wielu metod. Opis typu obiektowego rozpoczyna się od słowa kluczowego object, a kończy 
słowem kluczowym end. Definicja pojedynczego typu obiektowego ma postać:

 

background image

   

TYPE Identyfikator_typu = object dziedzictwo 
                             Lista_deklaracji_pól 
                             Lista_deklaracji_metod 
                          end

  

lub

 

   

TYPE Identyfikator_typu = object dziedzictwo 
                             Lista_deklaracji_pól 
                             Lista_deklaracji_metod 
                             Sekcje_list 
                          end

  

przy czym elementy wyszczególnione pomiędzy słowami object i end są opcjonalne, a kaŜda z sekcji list moŜe 
mieć jedną z poniŜszych postaci:

 

   

private 
   Lista_deklaracji_pól 
   Lista_deklaracji_metod 

  

lub

 

   

public 
   Lista_deklaracji_pól 
   Lista_deklaracji_metod 

  

przy czym w sekcjach tych oba elementy są takŜe opcjonalne. 
 
Dziedzictwo oznacza ujęty w nawiasy okrągłe identyfikator innego, zdefiniowanego wcześniej, typu 
obiektowego. Jeśli w definicji typu obiektowego wystąpi ten element, oznacza to, Ŝe dany typ obiektowy 
zawiera (dziedziczy) wszystkie elementy podane w definicji typu obiektowego o wyspecyfikowanej nazwie. 
 
KaŜda z deklaracji pól ma postać:

 

   

Lista_nazw_pól : opis_typu; 

background image

  

a kaŜda deklaracja metody jest następująca:

 

   

nagłowek_metody; 

  

lub

 

   

nagłowek_metody; virtual

  

gdzie nagłowek metody oznacza nagłowek funkcji, procedurey, konstruktora lub destruktora. Słowo kluczowe 
virtual określa daną metodę jako wirtualną (?).Definicję poszczególnych metod podaje się poza definicją typu 
obiectowego. KaŜda definicja metody zawiera w nagłówku nazwę funkcji, procedurey, konstruktora lub 
destruktora, poprzedzoną kropką i nazwą odnośnego typu obiektowego. 
 
Jeśli definicja typu obiektowego zawiera dyrektywę private, oznacza to, Ŝe zakres waŜności pól i (lub) metod 
podanych po tej dyrektywie jest ograniczony do modułu (lub programu), który zawiera definicję danego typu 
obiektowego. Tego typu pola i metody nazywami polami i metodami prywatnymi. UŜycie po sekcji z dyrektywą 
private dyrektywy public powoduje anulowanie ograniczenia zakresu waŜności dla dalszych pól i (lub) metod.

 

Przykłady:

 

   

TYPE punkt = object 
                X, Y:Integer
             end
TYPE piksel = object (punkt) 
                Kolor:Byte
              end

  

Typ obiektowy piksel zawiera elementy typu obiektowego punkt.

 

   

TYPE odcinek = object 
                    X, Y:Byte
                    procedure zaznacz(dx, dy: Byte); 
               end

  

Dla powyŜszego typu konieczne jest podanie w dalszej części programu definicji procedury zaznacz:

 

background image

   

procedure odcinek.zaznacz(dx, dy: Byte); 
begin 
   ... Jakieś_instrukcje 
end
 

LEKCJA 4 

 

Instrukcje

 

        Czynności wykonywane na danych są opisywane za pomocą instrukcji. Instrukcjie języka Turbo Pascal 
dzielą się na instrukcje proste, tj. takie, które nie zawierają jako składowych innych instrukcji, oraz instrukcje 
strukturalne, zbudowane na podstawie pewnego schematu strukturalizacji kilku instrukcji.

 

Oto pełen podział instrukcji:

 

 Instrukcje proste

 

 Instrukcje przypisania 
 Instrukcje skoku 
 Instrukcje puste 
 Instrukcje wywołania procedury 
 Instrukcje inline

 

 Instrukcje strukturalne

 

 Instrukcje złoŜone 
 Instrukcje warukowe

 

 Instrukcje if .. then ("jeśli") 
 Instrukcje case .. of (wyboru)

 

 Instrukcje iteracyjne

 

 Instrukcje for .. do ("dla") 
 Instrukcje while .. do ("dopóki") 
 Instrukcje repeat .. until ("powtarzaj")

 

 Instrukcje wiąŜące 
 Instrukcje asemblerowe

 

        Co nazywamy instrukcją prostą wytłumaczyłem po krótce juŜ na wstępie. Teraz przypomne tylko na jakie 
składowe dzielimy te instrukcje. Więc do instrukcji prostych zaliczamy: instrukcje przypisania, instrukcje skoku, 
instrukcje puste, instrukcje wywołania procedury, instrukcje inline.

 

  

        Instrukcja przypisania słuŜy do przypisania zmiennej nowej wartości. Ogólna jej postać jest następująca:

 

   

Odwołanie_do_zmiennej:=wyraŜenie; 
 
lub 
 
Nazwa_funkcji:=wyraŜenie; 

  

background image

Dla kaŜdego przypisania wartość wyraŜenia musi być zgodna w sensie przypisania z typem zmiennej. 
 
Przykłady:

 

   

a:=1; 
tekst:="Kurs Pascala"; 
x:=x+1 
warunek:=a=b; 

  

        

Instrukcja skoku jest jedyną instrukcją, której stosowanie nie jest zalecane. Jej stosowanie zmniejsza 

przejrzystość programu, utrudnia jego optymalizację...(moŜna by pisać i pisać...). Instrukcja ta moŜe być zawsze 
zastąpiona instrukcjami "dopóki" lub "powtarzaj". Ogólna jej postać jest następująca:

 

   

GOTO etykieta; 

  

Powoduje to przekazanie sterowania do instrukcji programu poprzedzonej podaną etykietą.

 

Przykład:

 

   

PROGRAM Etykiety; 
LABEL et; 
... 
BEGIN 
   ... 
   GOTO et; 
   ... 
   x := a+2; 
   ... 
END. 

  

        

Zapisanie instrukcji pustej nie wymaga uŜycia Ŝadnego symbolu języka i nie powoduje ona wykonania 

Ŝ

adnych czynności. Instrukcję tą stosuje się w tych kontekstach, w których jest wymagane uŜycie instrukcji, ale 

chce się uniknąć wykonania jakiejkolwiek czynności, lub w celu ułatwienia opracowania programu.

 

 
        Instrukcja wywołania procedury jak sama nazwa wskazuje słuŜy do wywoływania w programie 
procedur. Ogólna postać wywołania jest następująca:

 

   

Nazwa_Procedury; 
 
lub 

background image

 
Nazwa_Procedury(lista_parametrów); 

  

Przykład:

 

Jeśli w części opisowej programu zadeklarujemy następującą procedurę:

 

   

PROCEDURE(X,Y:Byte;Tekst:String[10]); 
BEGIN 
   ... 
END; 

  

To aby tą procedurę wywołać to w części wykonawczej programu piszemy:

 

   

PROCEDURE(10,10,"Kurs Pascala"); 

  

        

Do dołączania w programie lub module paskalowym krótkich podprogramów lub instrukcji napisanych w 

kodzie maszynowym (zgroza!) słuŜy dyrektywa i instrukcja inline.. Jej postać jest następująca:

 

   

INLINE (lista_elementów_inline); 

  

Nie będę się więcej rozpisywać na ten temat gdyŜ instrukcja ta bez znajomości Assemblera jest bezuŜyteczna - w 
końcu to kurs dla początkujących, a oni raczej Assemblera nie znają.

 

Przykład:

 

   

INLINE ($CD/$12/$89/$46/$04); 

  

        

Co nazywamy instrukcją strukturalną wytłumaczyłem po krótce juŜ na wstępie. Teraz przypomne tylko 

na jakie składowe dzielimy te instrukcje. Więc do instrukcji strukturalnych zaliczamy: instrukcje złoŜone, 
instrukcje warunkowe, instrukcje iteracyjne, instrukcje wiąŜące, instrukcje asemblerowe.

 

        Instrukcja złoŜona jest ciągiem instrukcji poprzedzonym słowem kluczowym begin i zakończonym 
słowem kluczowym end. Instrukcje wchodzące w skład instrukcji złoŜonej wykonywane są sekwencyjnie. 
Struktura tej instrukcji jest następująca:

 

background image

   

BEGIN 
   Instrukcja_1; 
   Instrukcja_2; 
   ... 
   Instrukcja_n 
END 

  

Przykład:

 

   

BEGIN 
   a:=1; 
   b:=a+4; 
   c:=a-b; 
   GOTO Franek; 
END 

  

  

     

   Instrukcje warunkowe uzaleŜniają wykonywanie innych instrukcji od spełnienia określonego warunku. 

W Pascalu istnieją dwie instrukcje warunkowe: instrukcje if .. then ("jeśli"), instrukcje case .. of (wyboru).

 

        Instrukcja "jeśli" uzaleŜnia wykonywanie innej lub innych instrukcji od spełnienia lub niespełnienia 
podanego warunku. Ogólna jej postać jest następująca:

 

   

IF wyraŜenie THEN instrukcja 
 
lub 
 
IF wyraŜenie THEN instrukcja 
 
ELSE instrukcja 
 
 

  

Przy czym wartością wyraŜenia powinna być wartość logiczna True lub False. Instrukcja występująca po słowie 
kluczowym then lub else moŜe być dowolną instrukcją prostą lub strukturalną. Jeśli wartością 
wyspecyfikowanego wyraŜenia jest True, to zostanie wykonana instrukcja podana po słowie then. W 
przeciwnym przypadku wykonana będzie następna instrukcja po instrukcji "jeśli" (gdy brak else) lub instrukcja 
podana po słowie else.

 

Przykład:

 

   

background image

IF X=Y THEN A:=0 
ELSE A:=1; 

  

  

       

 W programowaniu często mamy do czynienia z sytuacją, gdy wykonanie róŜnych operacji jest uzaleŜnione 

od wartości pewnej zmiennej. Pomocna moŜe się tu okazać instrukcja wyboru, której ogólna postać jest 
następująca:

 

   

CASE wyraŜenie OF 
   sekwencja_instrukcji_wyboru 
END 
 
lub 
 
CASE wyraŜenie OF 
   sekwencja_instrukcji_wyboru 
   ELSE instrukcja 
END 

  

gdzie wartość wyraŜenia musi być typu porządkowego. Sekwencja instrukcji wyboru składa się z instrukcji, przy 
czym kaŜda z nich poprzedzona jest jedną lub kilkoma stałymi, zwanymi stałymi wyboru, które od instrukcji 
oddzielone są dwukropkiem. Poszczególne stałe wyboru oddzielamy przecinkami.

 

Przykład:

 

   

CASE znak OF 
   '+' : BEGIN 
           d:=d+1; 
           z:=z-1; 
         END
   '-' : BEGIN 
           d:=d-1; 
           z:=z+1; 
         END
END

  

        

Instrukcje iteracyjne słuŜą do organizowania cykli programowych, tj. wielokrotnego wykonywania 

pewnych sekwencji instrukcji. W Pascalu istnieją trzy rodzaje instrukcji iteracyjnych: instrukcje for .. do ("dla"), 
instrukcje while .. do ("dopóki") i instrukcje repeat .. until ("powtarzaj").

 

  

        Instrukcje "dla" tzw. pętlę stosuje się zwykle w celu wykonania pewnej grupy instrukcji w przypadku, 
gdy liczba powtórzeń jest znana w danym miejscu programu. Instrukcja ta moŜe mieć jedną z dwu następujących 
postaci:

 

background image

   

FOR zmienna:=wyraŜenie_1 TO wyraŜenie_2 DO intrukcja 
 
lub 
 
FOR zmienna:=wyraŜenie_1 DOWNTO wyraŜenie_2 DO intrukcja 

  

Zmienna, zwana zmienną sterującą, musi być identyfikatorem typu porządkowego i powinna być lokalna w 
bloku zawierającą daną instrukcję "dla". Wartość wyraŜenia 1 i wyraŜenia 2 powinna być zgodna w sensie 
przypisania z typem zmiennej sterującej. Instrukcja występująca po słowie kluczowym DO moŜe być dowolną 
instrukcją prostą lub strukturalną.

 

Przykłady:

 

   

FOR i:=1 TO 10 DO x:=x+i; 

  

Instrukcja wykonywana 10-krotnie powoduje zwiększenie zmiennej X o aktualną wartość zmiennej I.

 

   

FOR j:=10 DOWNTO 1 DO x:=x+j; 

  

Instrukcja wykonywana 10-krotnie (od "tyłu" :-)) powoduje zwiększenie zmiennej X o aktualną wartość 
zmiennej J.

 

  

      

  Instrukcja "dopóki" słuŜy do opisywania interacji ze sprawdzeniem warunku na początku i ma postać:

 

   

WHILE wyraŜenie DO intrukcja 

  

WyraŜenie, które najczęściej jest wyraŜeniem porównania, powinno w wyniku dawać wartość logiczną (True 
lub False), a instrukcja występująca po słowie do moŜe być dowolną instrukcją prostę lub strukturalną. 
Instrukcja ta wykonywana jest tak długo jak długo wartością wyraŜenia jest True.

 

Przykład:

 

   

k:=1; 
WHILE k<10 DO BEGIN 

background image

    x:=x*x; 
    k:=INC(k) {INC(k) działa jak k:=k+1;}; 
END

  

     

   Instrukcja "powtarzaj" słuŜy do opisywania interacji ze sprawdzeniem warunku na końcu i ma postać:

 

   

REPEAT 
   Instrukcja_1 
   Instrukcja_2 
   ... 
   Instrukcja_n 
UNTIL wyraŜenie 

  

WyraŜenie powinno dawać w wyniku wartość logiczną, a kaŜda z instrukcji moŜe być dowolną instrukcją prostą 
lub strukturalną. Instrukcje wewnętrzne są wykonywane conajmniej jeden raz, a zakończenie przetwarzania 
instrukcji "powtarzaj" następuje, gdy wartością wyraŜenia występującego po słowie kluczowym until jest True.

 

Przykład:

 

   

i:=1; 
REPEAT 
   Writeln('Linia ',i); 
   i:=i+1; 
UNTIL i=10; 

  

        

Do odwołania się do poszczegolnych pol rekordu lub obiektu słuŜą desygnatory pól, składające się z 

indentyfikatora odpowiedniego pola i nazwy zmiennej rekordowej lub obiektowej. Zastosowanie instrukcji 
wi
ąŜącej pozwala na wygodniejsze odwołanie się do wspomnianych pól, a takŜe zwiększa czytelność programu. 
Jej postać jest następująca:

 

   

WITH lista_zmiennychDO instrukcja 

  

przy czym lista zmiennych zawira oddzoelone przecinkami identyfikatory zmiennych rekordowych lub 
obiektowych, a instrukcja po słowie kluczowym do moŜe być dowolną instrukcją prostą lub strukturalną. 
Umieszczenie zmiennej rekordowej lub obiektowej po słowie kluczowym with pozwala wewnątrz instrukcji 
wiąŜącej na odwołanie się do pól tej zmiennej za pomocą samych identyfikatorów pól. Identyfikatory te 
traktowane są w instrukcji wewnętrznej jako zmienne.

 

Przykład:

 

   

background image

ZałóŜmy następującą deklarację: 
 
VAR comp: RECORD 
             re,im: Real
           END
 
Przypisanie do tego rekordu w instrukcji wiąŜącej 
jest następujące: 
 
WITH comp DO 
BEGIN 
    re:=1; 
    im:=1; 
END
 
Jest to równowaŜne z takim przypisaniem w instrukcji 
złoŜonej: 
 
BEGIN 
   comp.re:=1; 
   comp.im:=1; 
END

       

 Instrukcje asemblera wewnętrznego w tekście źródłowym języka Turbo Pascal są zapisywane jako 

instrukcja asemblerowa, która ma postać:

 

   

ASM 
   instrukcja_asemblera_1 
   instrukcja_asemblera_2 
   ... 
   instrukcja_asemblera_n 
END

  

Nie będę się więcej rozpisywać na ten temat gdyŜ instrukcja ta bez znajomości Assemblera jest bezuŜyteczna - w 
końcu to kurs dla początkujących, a oni raczej Assemblera nie znają. (Ups ! Chyba to juŜ pisałem...)

 

 

LEKCJA 5 

 

Moduły

 

        Moduły są podstawą programowania modularnego i słuŜą przede wszystkim do grupowania procedur i 
funkcji w biblioteki, a takŜe do dzielenia duŜych programów na powiązane logicznie części. Moduł nie stanowi 
samoistnego programu a jego uŜycie w programie wymaga deklaracji(USES). Po zadeklarowaniu modułu w 
danym programie dostępna jest kaŜda procedura i funkcja zdefiniowana w danym module, jak równieŜ 
zadeklarowane w nim stałe, typy i zmienne. Uruchomienie skompilowanego programu zawierającego deklaracje 
modułu wymaga, aby moduł taki był równieŜ wcześniej skompilowany. 
 
Dokładna postać modułu jest następująca:

 

   

background image

UNIT Nazwa_modułu; 
 
INTERFACE 
 
{Początek części opisowej modułu} 
 
   Deklaracje_modułów; 
   Definicje_literałów; 
   Definicje_typów; 
   Deklaracje_zmiennych; 
   Lista_nagłówków_procedur_i_funkcji; 
 
{Koniec części opisowej modułu  
i początek części implementacyjnej} 
 
IMPLEMENTATION 
 
   Deklaracje_etykiet; 
   Deklaracje_literałów; 
   Definicje_typów; 
   Deklaracje_zmiennych; 
   Definicje_funkcji_i_procedur_wewnętrznych; 
   Definicje_funkcji_i_procedur;  
   {których nagłówki podano w części opisowej} 
 
{Koniec części implementacyjnej} 
 
END.{Część inicjująca modułu} 

  

Część inicjująca modułu moŜe być takŜe instrukcją złoŜoną, która będzie wykonywana w celu zainicjowania 
modułu. Nazwa modułu jest identyfikatorem wykorzystywanym do deklaracji danego modułu w programie lub 
innym module - nazwa ta musi być unikatowa.

 

Jeśli chciałbyś się dowiedzieć jeszcze czegoś więcej o modułach to nie wahaj się 

napisać

LEKCJA 6 

 

Tryb 13H

 

Zacznę od wyjaśnienia, co to jest to tajemnicze 13H. OtóŜ tryb 13H jest to pewien tryb graficzny, który moŜna 
uzyskać na chyba kaŜdej karcie graficznej bez Ŝadnych dodatkowych sterowników. Daje on nam rozdzielczość 
320x200 i 256 kolorów. Dzięki temu moŜna tworzyć programy wykorzystujące więcej kolorów, np. ogień. 
Ogień jest prostym efektem graficznym, którego nie da się uzyskać w zwylym trybie graficznym w Turbo 
Pascal-u. Tryb ten ma równieŜ inne zalety. Bardzo łatwo się go uŜywa, nasze procedury zapisane w Assemblerze 
są szybsze i pewniejsze.

 

Jak juŜ wspomniałem tryb ten daje nam rozdzielczość 320x200 i 256 kolorór. Tryb ten zajmuje więc 64000 
bajtów pamięci (320x200=64000). Wiemy równieŜ, Ŝe mniej więcej tyle właśnie zajmuje jeden segment pamięci 
komputera. Segment pamięci ekranu w trybie 13H zaczyna się o adresie A000H. Literka H oznacza, Ŝe liczba 
zapisana jest w systemie szesnastkowym.

 

Do obsługi trybu graficznego słuŜy przerwanie 10H. Funcka 0H (Ah=0) ma za zadanie zmiany trybu 
graficznego/tekstowego. Dostępne są następujące tryby:

 

background image

AL

 

Rodzaj

 

Rozdz.

 

Kolory

 

Karta

 

Segment pamięci

 

0

 

tekstowy

 

40x25

 

16/8

 

CGA/EGA

 

B800H

 

1

 

tekstowy

 

40x25

 

16/8

 

CGA/EGA

 

B800H

 

2

 

tekstowy

 

80x25

 

16/8 (odcieni)

 

CGA/EGA

 

B800H

 

3

 

tekstowy

 

80x25

 

16/8

 

CGA/EGA

 

B800H

 

4

 

graficzny

 

320x200

 

4

 

CGA/EGA

 

B800H

 

5

 

graficzny

 

320x200

 

4 (odcienie)

 

CGA/EGA

 

B800H

 

6

 

graficzny

 

640x200

 

2

 

CGA/EGA

 

B800H

 

7

 

tekstowy

 

80x25

 

3

 

MDA/EGA

 

B000H

 

0DH

 

graficzny

 

320x200

 

16

 

EGA/VGA

 

A000H

 

0EH

 

graficzny

 

640x200

 

16

 

EGA/VGA

 

A000H

 

0FH

 

graficzny

 

540x350

 

3

 

EGA/VGA

 

A000H

 

10H

 

graficzny

 

640x350

 

4 lub 16

 

EGA/VGA

 

A000H

 

11H

 

graficzny

 

640x480

 

2

 

VGA

 

A000H

 

12H

 

graficzny

 

640x480

 

14

 

VGA

 

A000H

 

13H

 

graficzny

 

320x200

 

156

 

VGA

 

A000H

 

My włączamy tryb 13H, czyli nasza procedura InitGraph wygląda tak:

 

   

Procedure Init; Assembler; 
Asm; 
  MOV AX,0013H 
  INT 10H 
end; 

  

Na koniec pracy w grafice trzeba ten tryb zamknąć, a dokładnie mówiąc wywołać tryb standardowy tekstowy. 
Nasza procedura CloseGraph wygląda więc tak:

 

   

Procedure Close; Assembler; 
Asm; 
  MOV AX,0003H 
  INT 10H 
End; 

  

Punkt o współrzędnych [0,0] ma adres A000H:0. Tak więc punkt o współrzędnych [X,Y] znajduje się w pamięci pod adresem A000:Y*320+X.

 

Turbo Pascal daje nam moŜliwość odwoływania się do komórek pamięci za pomocą instrukcji MEM. Jeśli chcemy odczytać wartość danej komórki 
piszemy:

 

   

X:=MEM[segment:offset]; 

background image

  

Jeśli chcemy zmienić wartość danej komórki, napiszemy:

 

   

MEM[segment:offset]:=X; 

  

Prosta procedura rysująca punkt na ekranie mogłaby wyglądać więc tak:

 

   

Procedure PutPixel(X,Y : Integer; Kolor : Byte); 
Begin 
  MEM[$A000:Y*320+X]:=Kolor; 
End; 

  

Funkcja odczytująca kolor punktu pogłaby wyglądać tak:

 

   

Function GetPixel(X,Y : Integer) : Byte; 
Begin 
  GetPixel:=MEM[$A000:Y*320+x]; 
End; 

  

Opisze te instrukcje ze względu na działanie patematyczne (Y*320+X) oraz uŜycie Pascal'wej instrukcji MEM 
są bardzo proste. Dlatego naleŜy uŜywać procedury do wstawiania punktu napisanej w Assemblerze ? Wiemy, Ŝe 
ten język jest najszybszy. W Assemblerze nasza procedura PutPixel wyglądałaby tak:

 

   

Procedure PutPixel(X,Y : Integer; Kolor : Byte); Assembler; 
Asm 
  MOV AX,0A000H 
  MOV ES,AX 
  MOV DX,Y 
  MOV DI,X 
  SHL DX,6 
  ADD DI,DX 
  SHL DX,2 
  ADD DI,DX 
  MOV AL,Kolor 
  MOV ES:[DI],AL 
End; 

  

MoŜe być ? Ta procedura jest znacznie szybsza od poprzedniej. Działa w następujący sposób:

 

background image

   

MOV AX,0A000H 
MOV ES,AX 

  

W rejestrze ES mamy teraz segment naszego ekranu. Wystarczy wykonać działanie Y*320+X. MoŜna to zrobić 
uŜywając instrukcji MUL, która słuŜy do mnoŜenia, jednak jest ona strasznie wolna. Lepiej zastosować tutać 
SHL, czyli przesunięcie logiczne. Jest znacznie szybsze, a moŜna za pomocą niego wykonać mnoŜenie przez 
potęgę liczby 2. Działanie 320*Y zapisujemy jako Y*256+Y*64. Liczby 256 i 64 są potęgami liczby 2. 
Dlaczego akurat 256 i 64? Bo wiemy ze wzoru (a+b)*C=A*c+b*c, czyli (256+64)*Y.

 

Instrukcja GetPixel w Assemblerze jest bardzo podobna.

 

   

Function GetPixel(X,Y : Integer) : Byte; Assembler 
Asm 
  MOV AX,0A000H 
  MOV ES,AX 
  MOV DX,Y 
  MOV DI,X 
  SHL DX,6 
  ADD DI,DX 
  SHL DX,2 
  ADD DX,DI 
  MOV AL,ES:[DI] 
  MOV @Result,AL 
End; 

 

LEKCJA 7 

 

WyraŜenia

 

WyraŜenia składają się z argumentów i operatorów. Dzięki operatorom moŜemy wykonywać róŜne operacje na 
argumentach. Kolejność wykonywania działań jest określona tzw. priorytetem. PoniŜej znajduje się tabela 
poszczególnych operatorów i ich priorytety:

 

Operatory

 

Priorytety

 

@, NOT

 

1

 

*,/, DIV, MOD, AND, SHL, SHR

 

2

 

+,-, OR, XOR

 

3

 

=, <>, <, >, <=, >=, IN

 

4

 

Jeśli dwa operatory mają ten sam priorytet, to zostają wykonane od lewej do prawej.

 

Operatory arytmetyczne

 

Operator

 

Znaczenie

 

Typ argumentu

 

Typ wyniku

 

background image

+

 

zachowanie znaku

 

całkowity lub rzeczywisty

 

całkowity lub rzeczywisty

 

-

 

zmiana znaku

 

całkowity lub rzeczywisty

 

całkowity lub rzeczywisty

 

+

 

dodawanie

 

całkowity lub rzeczywisty

 

całkowity lub rzeczywisty

 

-

 

odejmowanie

 

całkowity lub rzeczywisty

 

całkowity lub rzeczywisty

 

*

 

mnoŜenie

 

całkowity lub rzeczywisty

 

całkowity lub rzeczywisty

 

/

 

dzielenie

 

całkowity lub rzeczywisty

 

rzeczywisty

 

DIV

 

dzielenie całkowite

 

całkowity

 

całkowity

 

MOD

 

dzielenie modulo

 

całkowity

 

całkowity

 

 

Operatory bitowe

 

Operator

 

Znaczenie

 

Typ argumentu

 

Typ wyniku

 

NOT

 

negacja

 

całkowity

 

całkowity

 

AND

 

iloczyn

 

całkowity

 

całkowity

 

OR

 

suma

 

całkowity

 

całkowity

 

 

Operatory logiczne

 

Operator

 

Znaczenie

 

Typ argumentu

 

Typ wyniku

 

NOT

 

negacja

 

logiczny

 

logiczny

 

AND

 

iloczyn

 

logiczny

 

logiczny

 

OR

 

suma

 

logiczny

 

logiczny

 

XOR

 

suma modulo 2

 

logiczny

 

logiczny

 

 
 
 
 
 
 
 
 
 
 
 

Operatory relacyjne

 

Operator

 

Znaczenie

 

Typ argumentu

 

Typ wyniku

 

=

 

równość

 

typy proste wskaźnikowe, 

zbiorowe łańcuchowe

 

logiczny

 

<>

 

nierówność

 

typy proste wskaźnikowe, 

zbiorowe łańcuchowe

 

logiczny

 

<

 

mniejszość

 

typy proste lańcuchowe 

PChar

 

logiczny

 

>

 

większość

 

typy proste lańcuchowe 

PChar

 

logiczny

 

<=

 

mniejszy-równy

 

typy proste lańcuchowe 

PChar

 

logiczny

 

>=

 

większy-równy

 

typy proste lańcuchowe 

PChar

 

logiczny

 

background image

<=

 

jest podzbiorem

 

zgodne zbiorowe

 

logiczny

 

=>

 

jest nadzbiorem

 

zgodne zbiorowe

 

logiczny

 

IN

 

zawarty w

 

 

 

logiczny

 

 

LEKCJA 8 

 

ędy podczas programowania

 

ędy podczas kompilacji

 

1. Invalid function number - czyli - Bledny numer funkcji 
2. File not found - czyli - Plik nie zostal znaleziony 
3. Path not found - czyli - Sciezka dostepu nie zostala znaleziona 
4. Too many open files - czyli - Zbyt duzo otwartych plikow 
5. File access denied - czyli - Brak dostepu do pliku 
6. Invalid file handle - czyli - niewlasciwy uchwyt pliku 
12. Invalid file access code - czyli - Niewlasciwy kod dostepu do pliku 
15. Invalid driver number - czyli - Niewlasciwy numer stacji 
16. Cannot remove current directory - czyli - Niemozliwe usuniecie biezacego katalogu 
17. Cannot rename across drives - czyli - Niemozliwa zmiana nazwy pliku 
18. No more files - czyli - Brak plikow o nazwach okreslonych w wywolaniach procedur FindFirs i FindNext 
100. Disk read error - czyli - Blad odczytu z dysku 
101. Disk write error - czyli - Blad zapisu na dysku 
102. File not assigned - czyli - Plik nie zostal powiazany ze zmienna plikowa 
103. File not open - czyli - Plik nie jest otwarty 
104. File not open for input - czyli - Plik nie jest otwarty do odczytu 
105. File not open for output - czyli - Plik nie jest otwarty do zapisu 
106. Invalid numeric format - czyli - Bledny format numeryczny 
150. Disk is write-protected - czyli - Dysk jest zabezpieczony przed zapisem 
151. Bad drive request struct length - czyli - Bledna nazwa stacji 
152. Drive not ready - czyli - Stacja nie jest gotowa 
153. Unknown command - czyli - Neeznana komenda 
154. CRC error in data - czyli - Blad danych 
156. Disk seek error - czyli - Blad przeszukiwania dysku 
157. Unknown media type - czyli - Nieznany typ urzadzenia 
158. Sector not found - czyli - Sektor nie zostal znaleziony 
160. Device write fault - czyli - Blad urzadzenia podczas zapisu 
161. Device read fault - czyli - Blad urzadzenia podczas odczytu 
162. Hardwere failure - czyli - Uszkodzenie sprzetu 
200. Devision by zero - czyli - Dzielenie przez zero 
201. Range chceck error - czyli - Blad przekroczenia zakresu 
202. Stack overlow error - czyli - Blad przepelnienia stosu 
203. Heap overlow error - czyli - Blad przepelnienia sterty 
204. Invalid pointer operation - czyli - Bledna operacja wskaznikowa 
205. Floating point overlow - czyli - Przepenienie w wyniku operacji zmiennoprzecinkowej 
206. Floating point underflow - czyli - Nadmiar w wyniku operacji zmiennoprzecinkowej 
207. Invalid floating point operation - czyli - Bledna operacja zmiennoprzecinkowa 
208. Overlay manager not installed - czyli - Program zarzadzajacy nakladkowaniem nie zostal zainstalowany 
209. Overlay file read error - czyli - Blad odczytu z pliku nakladkowego 
210. Object not initialized - czyli - Objekt nie zostal zainicjowany 
211. Call to abstract method - czyli - Wywolanie abstrakcyjne metody wirtualnej 
212. Stream registration error - czyli - Blad rejestracji strumienia 
213. Collection index out of range - czyli - Indeks kolekcji jest poza zakresem 
214. Collection overlow error - czyli - Blad przepenienia kolekcji 

background image

215. Arithmetic overlow error - czyli - Blad przepenienia lub wynik operacji arytmetycznej poza zakresem 
216. General Protection fault - czyli - Odwolanie sie przez program do pamieci dla niego niedostepnej

 

ędy podczas wykonywania programu

 

1. Out of memory - czyli - Brak pamieci 
2. Identifier expected - czyli - Oczekiwano identyfikatora 
3. Unkown identifier - czyli - Nieznany identyfikator 
4. Duplicate identifie - czyli - Podwojny identyfikator 
5. Syntax error - czyli - Blad skladni 
6. Error in real constant - czyli - Blad w stalej rzeczywistej 
7. Error in integer constant - czyli - Blad w stalej calkowitej 
8. String constant exceeds line - czyli - Stala lancuchowa przekracza wiersz 
9. Brak danych 
10. Unexpeced end of file - czyli - Niespodziewany koniec pliku 
11. Line too long - czyli - Zbyt dluga linia - maksymalnie 127 znakow 
12. Type identifier expected - czyli - Oczekiwany identyfikator typu 
13. Too many open files - czyli - Zbyt duzo otwartych plikow 
14. Invauld file name - czyli - Bledna nazwa pliku 
15. File not found - czyli - Nie znaleziono pliku 
16. Disk full - czyli - Dysk jest pelny 
17. Invaild compiler directive - czyli - Bledna dyrektywa kompilatora 
18. Too many files - czyli - Zbyt duzo plikow 
19. Undefined type in pointer definition - czyli - Niezdefiniowany typ w definicji wskaznika 
20. Variable identifier expected - czyli - Oczekiwano identyfikatora zmiennej 
21. Error in type - czyli - Blad w deklaracji typu 
22. Structure too large - czyli - Zbyt duzy typ strukturalny 
23. Set base type out of range - czyli - Typ bazowy przekracza zakres 
24. File components may not be files or object - czyli - Skladnikami pliku nie moga byc pliki ani objekty 
25. Invaild string length - czyli - Bledna dlugosc lancucha 
26. Type mismatch - czyli - Niezgodnosc typow 
27. Invaild subrange base type - czyli - Bledny typ bazowy typu okrojonego 
28. Lower boud greater than upper bound - czyli - Dolny zakres jest wiekszy od zakresu gornego 
29. Ordinal type expected - czyli - Oczekiwano typu porzadkowego 
30. Integer constant expected - czyli - Oczekiwano stalej calkowitej 
31. Constant expected - czyli - Oczekiwano stalej 
32. Integer or real constant expected - czyli - Oczekiwano stalej calkowitej lub rzeczywistej 
33. Pointer Type identifier expected - czyli - Oczekiwano identyfikatora typu wskaznikowego 
34. Invalid function result type - czyli - Bledny typ wyniku funkcji 
35. Label identufier expected - czyli - Oczekiwano identyfikatora etykiety 
36. BEGIN expected - czyli - Oczekiwano BEGIN 
37. END expected - czyli - Oczekiwano END 
38. Integer expression expected - czyli - Oczekiwano wyrazenia calkowitego 
39. Ordinal expression expected - czyli - Oczekiwano wyrazenia porzadkowego 
40. Boolean expression expected - czyli - Oczekiwano wyrazenia logicznego 
41. Operand types do not match operator - czyli - NIezgodnosc typow operandow dla operatora 
42. Error in expression - czyli - Blad w wyrazeniu 
43. Illegal assignment - czyli - Niedozwolone przypisanie 
44. Field identifier expected - czyli - Oczekiwano identyfikatora pola 
45. Object file too large - czyli - Zbyt duzy plik OBJ 
46. Undefined external - czyli - Niezdefinowany podprogram zewnetrzny 
47. Invalid object file record - czyli - Bledna zawartosc pliku OBJ 
48. Code segment too large - czyli - Zbyt duzy segment kodu 
49. Data segment too large - czyli - Zbyt duzy segment danych 
50. DO expected - czyli - Oczekiwano DO 
51. Invalid PUBLIC definition - czyli - Bledna definicja PUBLIC 
52. Invalid EXTRN definition - czyli - Bledna definicja EXTRN 
53. Too many EXTRN definitions - czyli - Zbyt duzo definicji EXTRN 
54. OF expected - czyli - Oczekiwano OF 
55. INTERFACE expected - czyli - Oczekiwano INTERFACE 

background image

56. Invalid relocatable reference - czyli - Bledne odwolanie relokowalne 
57. THEN expected - czyli - Oczekiwano THEN 
58. TO or DOWNTO expected - czyli - Oczekiwano TO lub DOWNTO 
59. Undefined forward - czyli - Niezdefiniowana deklaracja forward 
60. Brak danych 
61. Invalid typecast - czyli - Niewlasciwa konwersja 
62. Devision by zero - czyli - Dzielenie przez zero 
63. Invalid file type - czyli - Niewlasciwy typ plikowy 
64. Cannt read or write variables of this type - czyli - Bledny typ argumentu 
65. Pointer variable expected - czyli - Oczekiwano zmiennej wskaznikowej 
66. String variable expected - czyli - Oczekiwano zmiennej lancuchowej 
67. String expression expected - czyli - Oczekiwano wyrazenia lancuchowego 
68. Circular unit reference - czyli - Zapetlenie odwolan mieszy modulami 
69. Unit name mismatch - czyli - Niezgodnosc nazwy modulow 
70. Unit version mismatch - czyli - Niezgodnosc wersji modulow 
71. Internal stack overflow - czyli - Przepelnienie wewnetrzne stosu 
72. Unit file format error - czyli - Blad formatu pliku TPU 
73. IMPLEMENTATION expected - czyli - Oczekiwano IMPLEMENTATION 
74. Constant and case types do not match - czyli - Niezgodnosc stalej i pola wyboru 
75. Record or objest variable expected - czyli - Oczekiwano zmiennej rekordowej lub objektowej 
76. Constant out of range - czyli - Stala poza zakresem 
77. File variable expected - czyli - Oczekiwano zmiennej plikowej 
78. Pointer expression expected - czyli - Oczekiwano wyrazenia wskaznikowego 
79. Integer or real expression expected - czyli - Oczekiwano wyrazenia calkowitego lub rzeczywistego 
80. Label not wihin current block - czyli - Brak etykiety w biezacym bloku 
81. Label already defined - czyli -Etykieta jest juz zdefiniowana 
82. Undefined label in proceding statement part - czyli - Wystapila niezdefiniowana etykieta 
83. Invalid @ argument - czyli - Vledny argument operatora @ 
84. UNIT expected - czyli - Oczekiwano UNIT 
85. ; expected - czyli - Oczekiwano srednika 
86. : expected - czyli - oczekiwano dwukropka 
87. , expected - czyli - Oczekiwano przecinka 
88. ( expected - czyli - Oczekiwano nawiasu poczatkowego 
89. ) expected - czyli - Oczekiwano nawiasu konczacego 
90. = expected - czyli - Oczekiwano znaku roznosci 
91. := expected - czyli - Oczekiwano znaku przypisania 
92. [ or (. expected - czyli - Oczekiwano nawiasu poczatkowego [ lub (. 
93. ] or .) expected - czyli - Oczekiwano nawiasu konczacego ] lub .) 
94. . expected - czyli - Oczekiwano kropki 
95. .. expected - czyli - Oczekiwano dwoch kropek 
96. Too many variables - czyli - Zbyt duzo zmiennych 
97. nvalid FOR control variable - czyli - Bledna zmienna sterujaca w instrukcji FOR 
98. Integer variable expected - czyli - Oczekiwano zmiennej calkowitej 
99. Files types are not allowed here - czyli - Pliki sa tutaj niedozwolone 
100. String length mismatch - czyli - Niezgodnosc dlugosci lancuchow 
101. Invalid ordering of fields - czyli - Bledne uporzadkowanie pol 
102. String constant expected - czyli - Oczekiwano stalej lancuchowej 
103. Integer or real variable expected - czyli - Oczekiwano zmiennej calkowitej lub rzeczywstej 
104. Ordinal variable expected - czyli - Oczekiwano zmiennej porzadkowej 
105. INLINE error - czyli - Blad w instrukcji kodu INLINE 
106. Character expression expected - czyli - Oczekiwano wyrazenia znakowego 
107. Too many relocation items - czyli - Zbyt duzy program EXE 
108. Overlow in arithmetic operation - czyli - Przepelnienie w wyniku przekroczenia zakresu operacji 
arytmetycznej 
109. No enclosing FOR, WHILE or REPEAT statement - czyli - Procedury Break i Continue wystapily poza 
instrukcjami FOR, WHILE, REPEAT 
110. Debug information table oferlow - czyli - Przepelnienie podczas generowania do pliku EXE informacji dla 
debuggera 
111. Berak danych 
112. CASE constant out of range - czyli - Stala wybory poza zakresem 

background image

113. Error in statement - czyli - Blad w instrukcji 
114. Cannot call an interrupt procedure - czyli - Niemozliwe wywolanie procedury obslugi przerwania 
115. Brak danych 
116. Must be in 8087 mode to compile this - czyli - Kompilacja mozliwa przy uzyciu dyrektywy {$N+} 
117. Target address not found - czyli - Nie znaleziono adresu docelowego 
118. Include files are not allowed here - czyli - W tym miejscu dolaczenie pliku jest niemozliwe 
119. No inherited methods are accessible here - czyli - Uzycie slowa kluczowego INHERITED poza metoda lub 
w metodzie bez przodka 
120. NIL expected - czyli - Oczekiwano NIL 
121. Invalid qualifier - czyli - Bledny kwalifikator 
122. Invald variable reference - czyli - Bledne odwolanie do zmiennej 
123. Too many symbols - czyli - Zbyt duzo symboli 
124. Statement part too large - czyli - Zbyt duza czesc wykonawcza 
125. Brak danych 
126. Files must be var parametrs - czyli - Pliki musza byc parametrami przekazywanymi przez zmienna 
127. Too many conditional symbols - czyli - Zbyt duzo warunkowych nazw symbolicznych 
128. Misplaced conditional directive - czyli - Niewlasciwie umieszczona dyrektywa warunkowa 
129. ENDIF directive missing - czyli - Brak dyrektywy ENDIF 
130. Error in initial condidtional defines - czyli - Blad w definicji warunkowej nazwy symbolicznej 
131. Header does not match previous definition - czyli - Niezgodnosc naglowka z poprzednia definicja 
132. Brak dancych 
133. Cannot evaluate this expression - czyli - Obliczenie wyrazenia jest niemozliwe 
134. Expression incorrectly terminated - czyli - Nieprawidlowe zakonczenie wyrazenia 
135. Invalid format specifier - czyli - Bledny format elementu opisujacego 
136. Invalid indirect reference - czyli - Bledne odwolanie posrednie 
137. Structured variables are not allowed here - czyli - Uzycie zmiennych strukturalnych w tym miejscu nie jest 
dozwolone 
138. Cannot evaluate without System unit - czyli - Bez modulu System nie mozna wykonac danych obliczen 
139. Cannot access this symbol - czyli - Brak dostepu do danego symbolu 
140. Invalid floating point operation - czyli - Bledna operacja zmiennoprzecinkowa 
141. Cannot compile overlays to memory - czyli - Kompilowanie nakladek do pamieci jest niemozliwe 
142. Pointer or procedural variable expected - czyli - Oczekiwano zmiennej wskaznikowej lub proceduralnej 
143. Invalid procedure or function reference - czyli - Bledne odwolanie do procedury lub funkcji 
144. Cannot overlays this unit - czyli - Modul nie byl skompilowany z dyrektywa {$O+} i nie moze byc 
stosowany jako nakladka 
145. Too many nested scopes - czyli - Zbyt duzy zakres zagniezdzen - 512 dla calego programu lub 128 dla 
modulu 
146. File access denied - czyli - Brak dostepu do pliku 
147. Object type expected - czyli - Oczekiwano typu objektowego 
148. Local object types are not allowed - czyli - Lokalne typy objektowe nie sa dozwolone 
149. VIRTUAL expected - czyli - Oczekiwano VIRTUAL 
150. Method identifier expected - czyli - Oczekiwano identyfikatora metody 
151. Virtual constructors are not allowed - czyli - onstruktory wirtualne nie sa dozwolone 
152. Constructor identifier expected - czyli - Oczekiwano identyfikatora konstruktora 
153. Destructor identifier expected - czyli - Oczekiwano identyfikatora destruktora 
154. Fail only allowedwithin constructors - czyli - Procedura Fail moze byc wywolana tylko z wnetrza 
konstruktora 
155. Invalid combination of opcode and operands - czyli - Bledna kombinacja kodu operacji i operatorow 
156. memory reference expected - czyli - Oczekiwano odwolania do pamieci 
157. Cannot add or subtract relocatable symbols - czyli - Symbole relokowalne nie moga byc dodawane lub 
odejmowane 
158. Invalid register combination - czyli - Bledna kombinacja rejestrow 
159. 286/287 instructions are not enabled - czyli - Instrukcje procesora 80286 i koprocesora arytmetycznego 
80287 nie sa dozwolone 
160. Invalid symbol reference - czyli - Bledne odwolanie do symbolu 
161. Code generation error - czyli - Bledna generacja kodu 
162. ASM expected - czyli - Oczekiwano ASM 
163. Duplicate dynamic method index - czyli - Dwukrotne uzycie indeksu metody dynamicznej 
164. Duplicate resourceidentifier - czyli - Dwukrotne uzycie identyfikatora zasobu 
165. Duplicate or invalid export index - czyli - Dwukrotne uzycie lub bledny index eksportu 

background image

166. Procedure or function identifier expected - czyli - Oczekiwano identyfikatora procedury lub funkcji 
167. Cannot export this symbol - czyli - Symbol nie moze byc eksportowany 
168. Duplicate export name - czyli - Dwukrotne uzycie nazwy eksportowej 
169. Executable file header too large - czyli - Zbyt duzy naglowek pliku wykonywalnego 
170. Too many segments - czyli - Zbyt duzo segmentow

 

 

LEKCJA 9 

 

Kody klawiszy

 

Oznaczenie

 

Sam klawisz

 

Z SHIFT

 

Z CTRL

 

Z ALT

 

0

 

48

 

41

 

-

 

0 129

 

1

 

49

 

33

 

-

 

0 120

 

2

 

50

 

64

 

-

 

0 121

 

3

 

51

 

35

 

-

 

0 122

 

4

 

52

 

36

 

-

 

0 123

 

5

 

53

 

37

 

-

 

0 124

 

6

 

54

 

94

 

-

 

0 125

 

7

 

55

 

38

 

-

 

0 126

 

8

 

56

 

42

 

-

 

0 127

 

9

 

57

 

40

 

-

 

0 128

 

A

 

97

 

65

 

1

 

0 30

 

B

 

98

 

66

 

2

 

0 48

 

C

 

99

 

67

 

3

 

0 46

 

D

 

100

 

68

 

4

 

0 32

 

E

 

101

 

69

 

5

 

0 18

 

F

 

102

 

70

 

6

 

0 33

 

G

 

103

 

71

 

7

 

0 34

 

H

 

104

 

72

 

8

 

0 35

 

I

 

105

 

73

 

9

 

0 23

 

J

 

106

 

74

 

10

 

0 36

 

K

 

107

 

75

 

11

 

0 37

 

L

 

108

 

76

 

12

 

0 38

 

M

 

109

 

77

 

13

 

0 50

 

N

 

110

 

78

 

14

 

0 49

 

O

 

111

 

79

 

15

 

0 24

 

P

 

112

 

80

 

16

 

0 25

 

Q

 

113

 

81

 

17

 

0 16

 

R

 

114

 

82

 

18

 

0 19

 

S

 

115

 

83

 

19

 

0 31

 

T

 

116

 

84

 

20

 

0 20

 

U

 

117

 

85

 

21

 

0 22

 

V

 

118

 

86

 

22

 

0 47

 

W

 

119

 

87

 

23

 

0 17

 

background image

X

 

120

 

88

 

24

 

0 45

 

Y

 

121

 

89

 

25

 

0 21

 

Z

 

122

 

90

 

26

 

0 44

 

-

 

45

 

95

 

31

 

0 130

 

=

 

61

 

43

 

-

 

0 131

 

\

 

92

 

124

 

28

 

-

 

/

 

47

 

63

 

-

 

-

 

SPACJA

 

32

 

32

 

32

 

32

 

F1

 

0 59

 

0 84

 

0 94

 

0 104

 

F2

 

0 60

 

0 85

 

0 95

 

0 105

 

F3

 

0 61

 

0 86

 

0 96

 

0 106

 

F4

 

0 62

 

0 87

 

0 97

 

0 107

 

F5

 

0 63

 

0 88

 

0 98

 

0 108

 

F6

 

0 64

 

0 89

 

0 99

 

0 109

 

F7

 

0 65

 

0 90

 

0 100

 

0 110

 

F8

 

0 66

 

0 91

 

0 101

 

0 111

 

F9

 

0 67

 

0 92

 

0 102

 

0 112

 

F10

 

0 68

 

0 93

 

0 103

 

0 113

 

DO GÓRY

 

0 72

 

56

 

-

 

8

 

W PRAWO

 

0 77

 

54

 

0 116

 

6

 

W LEWO

 

0 75

 

52

 

0 115

 

4 lub 0 132

 

W DÓŁ

 

0 80

 

50

 

-

 

2 lub 0 130

 

HOME

 

0 71

 

55

 

0 119

 

7

 

END

 

0 79

 

49

 

0 117

 

1 lub 0 129

 

PgUp

 

0 73

 

57

 

0 132

 

9

 

PgDn

 

0 81

 

51

 

0 118

 

3 lub 0 131

 

Ins

 

0 82

 

48

 

-

 

-

 

Del

 

0 83

 

46

 

-

 

-

 

5 (num)

 

-

 

53

 

-

 

5 lub -

 

* (szary)

 

42

 

PrtSc

 

0 114

 

-

 

- (szary)

 

45

 

45

 

-

 

-

 

+ (szary)

 

43

 

43

 

-

 

-

 

ESC

 

27

 

27

 

27

 

-

 

BackSpace

 

8

 

8

 

127

 

-

 

TAB

 

9

 

0 15

 

-

 

-

 

ENTER

 

13

 

13

 

10

 

-

 

 

 

LEKCJA 10 

 
Algorytmy sortowania

  

InsertionSort

 

background image

Algorytm InsertionSort (przez wstawianie) jest jednym z najprostrzych algorytmów sortowania. Jest on uŜywany 
bardzo często w prostych programach osób, które dopiero zaczynają programować. Trudno popełnić w nim błąd 
ze względu na krótki i prosty jego zapis. Nie jest jednak wskazane uŜywanie jego w powaŜniejszych 
zastosowaniach, kiedy mamy do czynienia z sortowaniem bardzo duŜych tablic. Jest on klasy O(N

2

), czyli jest 

strasznie wolny.

 

Polega on na tym, Ŝe przeglądamy po kolei całą tablicę. JeŜeli któryś z elementów nie znajduje się na swoim 
miejscu, to wstawiamy go tam, gdzie powinien się znajdować, gdyby tablica była uporządkowana. Dlatego 
najpierw przesuwamy całą zawartość tablicy tak, by się zwolniło miejsce, a później uzupełniamy je naszą np. 
liczbą.

 

W Pascalu, algorytm mógłby wyglądać np. tak:

 

   

        Procedure InsertionSort(Var TAB : Tablica); 
        Var i,j  : Integer;  
            Temp : integer; 
        begin 
           for i:=2 to Ilosc do 
           begin 
             Temp:=TAB[i]; 
             TAB[0]:=Temp; 
             j:=i-1; 
             While Temp<TAB[j] do 
             Begin 
               TAB[j+1]:=TAB[j]; 
               j:=j-1; 
             end; 
             TAB[j+1]:=Temp; 
            End; 
        End; 

BubbleSort

 

Jest to jeden z najprostrzych algorytmów sortowania. Jako, Ŝe jest klasy O(N

2

), nie nadaje się do profesionalnych 

zastosowań, gdzie mamy do czynienia z sortowaniem bardzo duŜych tablic. Jeśli jednak tablica jest mała, to ze 
względu na jego bardzo prostą budowe, nadaje się wyśmienicie.

 

BubbleSort, czyli Sortowanie Bąbelkowe opiera się na zasadzie porównania i ewentualnej zmiany par 
sąsiadujących ze sobą elementów. Jeśli np. liczba 1 znajduje się na 5 pozycji w tablicy (a powinna na 1), to za 
pierwszym przebiegiem znajdzie się na pozycji 4, za kolejnym przebiegiem na 3, itd. aŜ dojdzie do 1. Nazwa 
sortowania pochądzi więc stąd, Ŝe w pionowo ustawionym ciągu elementy o małej wartości w czasie sortowania 
"wypływają do góry", jak bąbelki powietrza np. w wodzie.

 

Przykładowa funkcja sortująca algorytmem BubbleSort w Pascalu moŜe wyglądać tak:

 

   

        Procedure BubbleSort(Var TAB : Tablica); 
        Var i,j  : Integer;  
            Temp : integer; 
        begin 
           for i:=2 to Ilosc do 
             for j:=Ilosc DownTo i Do 
               if TAB[j-1]>A[j] Then 
               begin 
                  Temp:=TAB[j-1]; 

background image

                  TAB[j-1]:=TAB[j]; 
                  TAB[j]:=TEMP 
               End; 
        End; 

ShakerSort

 

Jest to poprawiona wersja sortowania bąbelkowego, często nazywana "Sortowaniem pęcherzykowym". RóŜnica 
między nim, a BubbleSort jest taka, Ŝe nie rozpoczyna w kaŜdym przebiegu zmiany elementów od początku, 
lecz na przemian od początku i od końca. Dzięki temu następuje niewielka (ale jednak) oszczędność czasu 
sortowania. Mniej jest pustych przebiegów. Zwiększenie szybkości jest szczególnie widoczne w częściowo 
posortowanych juŜ tablicach.

 

Algorytm ten w Pascalu wygląda następująco:

 

   

        Procedure ShakerSort(Var Tab : Tablica); 
        Var j,k        : Integer; 
            temp       : Integer; 
            left,right : Integer; 
        Begin 
          left:=1; 
          right:=Ilosc; 
          k:=Ilosc; 
          Repeat 
             for j:=right DownTo 1 do 
                if  Tab[j-1]>Tab[j] Then 
                Begin 
                   Temp:=Tab[j-1]; 
                   Tab[j-1]:=Tab[j]; 
                   Tab[j]:=Temp; 
                   k:=j; 
                End; 
                left:=k+1; 
             for j:=left to right do 
                if  Tab[j-1]>Tab[j] Then 
                Begin 
                   Temp:=Tab[j-1]; 
                   Tab[j-1]:=Tab[j]; 
                   Tab[j]:=Temp; 
                   k:=j; 
                End; 
                right:=k-1; 
          Until l>r; 
        End; 

QuickSort

 

Jest to jeden z najszybszych algorytmów sortowania, klasy O(N log

2

N). Autorem jego jest C.A.Hoare.

 

Procedura sortowania dzieli się na dwie części: część słuŜącą do właściwego sortowania (tzn. wywoływania 
samego siebie - rekurencji) oraz procedury rozdzielania elementów tablicy względem pewnej wartości komórki 
tablicy słuŜącej za oś podziału. Sortowanie jest wykonywane właśnie przez tę procedurę, a rekurencja zapewnia 
"sklejenie" wyników cząstkowych i w konsekwencji posortowanie całej tablicy.

 

Procedura podziału działa w taki sposób, Ŝe:

 

background image

 

w pierwszym momencie odczytuje wartość elementu osiowego P (zazwyczaj jest to pierwszy element 
tablicy)

  

 

w kolejnym kroku, tenŜe fragment tablicy jest dzielony (elementy tablicy są przemieszczane) tak, Ŝe po 
lewej stronie od P znajdują się elementy <P, a po prawej >=P

  

 

ostatnim krokiem jest wykonanie tego samego dla tablicy (kawałka tablicy) po prawej stronie od P i po 
lewej stronie od P. Dokonuje się to wywołując rekurencyjnie samą siebie.

  

MoŜna się spotkać z róŜnymi wersjami tego algorytmu. Na przykład taki jak poniŜej (dla Pascala):

 

   

        Procedure QuickSort(Var Tab : Tablica); 
 
          Procedure Sort(Left,Right : Integer); 
          Var i,j    : Integer; 
              x,temp : Integer;  
          Begin 
            i:=Left; 
            j:=Right; 
            X:=Tab[ (Left+Right) div 2]; 
            Repeat 
              While Tab[i]<x do i:=i+1; 
              While x<Tab[j] do j:=j-1; 
              if i<=j Then 
              Begin 
                 Temp:=Tab[i]; 
                 Tab[i]:=Tab[j]; 
                 Tab[j]:=Temp; 
                 i:=i+1; 
                 j:=j-1; 
              End; 
            Until i>j; 
            if Left<j Then Sort(L,j); 
            if i<Right Then Sort(i,Right); 
          End; 
 
          Begin 
            Sort(1,Ilosc); 
          End; 

 

LEKCJA 11 

 

Tryb graficzny [GRAPH.TPU]

 

Wstęp

 

Wszystkie procedury i funkcje związane z grafiką znajdują się w mdule GRAPH. By skorzystać z funkcji i 
procedur jakie daje nam ten moduł naleŜy najpierw przełączyć się do trybu graficznego. Do tego celu słuŜy 
procedura InitGraph. Jako pierwszy parametr podajemy typ sterownika graficznego, jaki mamy zainstalowany, 
jako drugi parametr podajemy tryb, w jaki chcemy przejść i trzeci parametr określa ścięŜkę dostępu do plików 
BGI. Trzeba zauwaŜyć, Ŝe po skompilowaniu programu napisanego w trybie graficznym, moŜe on u innej osoby 
nie działać poprawnie. Z tego względu, Ŝe kompilator nie dołącza plików BGI oraz plików czcionek CHR 
automatycznie do pliku wynikowego. Jak dołączyć pliki BGI do naszego programu dowiemy się w dalszej 
części tego artykułu. Po przejściu w tryb graficzny niektóre procedury nie działają, m.in. Write i Writeln. Do 
wyświetlania napisów słuŜą inne procedury, ale o tym później. 

background image

 
Ogólna składnia InitGraph jest następująca:

 

InitGraph(var GraphDrive : Integer; var GraphMode : Integer; PathToDriver : String);

 

W miejsce GraphDrive i GraphMode podajemy wartości typu całkowitego np. 9, moŜna równieŜ posłuŜyć się 
stałym przyjmującymi wartości odpowiednich trybów np. VGA. PoniŜej znajduje się tabela ze stałymi 
określającymi kartę graficzną, czyli GraphDrive:

 

KARTA GRAFICZNA

 

WARTOŚĆ

 

CurrentDriver

 

-128 (aktualny sterownik przesłany do procedury GetModeRange)

 

Detect

 

0 (automatyczne rozpoznanie sterownika graficznego)

 

CGA

 

1

 

MCGA

 

2

 

EGA

 

3

 

EGA64

 

4

 

EGAMono

 

5

 

IBM8514

 

6

 

HercMono

 

7

 

ATT400

 

8

 

VGA

 

9

 

PC3270

 

10

 

Jeśli więc nie wiemy, jaką kartę graficzną posiadamy moŜemy w jej miejsce wpisać wartość 0, bądz DETECT, a 
komputer automatycznie rozpozna zainstalowaną kartę graficzną.

 

W poniŜszej tabeli zamieściłem stałe określające wartości dla róŜnych trybów graficznych. Wartość tą 
wpisujemy do GraphMode:

 

STAŁA

 

WARTOŚĆ

 

ROZDZIELCZOŚĆ

 

NR. PALETY

 

LICZBA 

STRON

 

KOLORY

 

CGAC0

 

0

 

320x200

 

0

 

1

 

LightGreen, 

LightRed, 

Yellow

 

CGAC1

 

1

 

320x200

 

1

 

1

 

LightCyan, 

LightMagenta, 

White

 

CGAC2

 

2

 

320x200

 

2

 

1

 

Green, Red, 

Brown

 

CGAC3

 

3

 

320x200

 

3

 

1

 

Cyan, Magenta, 

LightGray

 

CGAHi

 

4

 

640x200

 

1

 

 

 

  

MCGAC0

 

0

 

320x200

 

0

 

1

 

LightGreen, 

LightRed, 

Yellow

 

MCGAC1

 

1

 

320x200

 

1

 

1

 

LightCyan, 

LightMagenta, 

White

 

MCGAC2

 

2

 

320x200

 

2

 

1

 

Green, Red, 

Brown

 

background image

MCGAC3

 

3

 

320x200

 

3

 

1

 

Cyan, Magenta, 

LightGray

 

MCGAMed

 

4

 

640x200

 

 

 

1

 

 

 

MCGAHi

 

5

 

640x480

 

 

 

1

 

 

 

EGALo

 

0

 

640x200

 

 

 

4

 

16

 

EGAHi

 

1

 

640x350

 

 

 

2

 

16

 

EGA64Lo

 

0

 

640x200

 

 

 

1

 

16

 

EGA64Hi

 

1

 

640x350

 

 

 

1

 

4

 

EGAMonoHi

 

3

 

640x350

 

 

 

1

 

64K

 

HercMonoHi

 

0

 

720x348

 

 

 

2

 

 

 

ATT400C0

 

0

 

320x200

 

0

 

1

 

LightGreen, 

LightLightRed, 

Yellow

 

ATT400C1

 

1

 

320x200

 

1

 

1

 

LightCyan, 

LightMagenta, 

White

 

ATT400C2

 

2

 

320x200

 

2

 

1

 

Green, Red, 

Brown

 

ATT400C3

 

3

 

320x200

 

3

 

1

 

Cyan, Magenta, 

LightCray

 

ATT400Med

 

4

 

640x200

 

 

 

1

 

 

 

ATT400Hi

 

5

 

640x400

 

 

 

1

 

 

 

VGALo

 

0

 

640x200

 

 

 

4

 

16

 

VGAMed

 

1

 

640x350

 

 

 

2

 

16

 

VGAHi

 

2

 

640x350

 

 

 

1

 

16

 

PC3270Hi

 

0

 

720x350

 

 

 

1

 

 

 

IBM8514Lo

 

0

 

640x480

 

 

 

  

256

 

IBM8514Hi

 

1

 

1024x768

 

 

 

  

256

 

Jeśli nie znamy nazwy naszej karty graficznej, ani nie wiemy, jaki jest najlepszy tryb dla tej karty, moŜemy 
posłuŜyć się procedurą, która rozpoznaje kartę i tryb. Ogólna jej składnia wygląda tak:

 

DetectGraph(var GraphDriver, GraphMode : Integer)

 

Po wykonaniu tej procedury parametry GraphDriver i GraphMode moŜemy podać do procedury InitGraph. Tak 
więc by przejść do trybu graficznego, dla kaŜdej karty graficznej (komputer sam ją rozpozna) naleŜy napisać 
następujący ciąg instrukcji:

 

uses Graph; 
var Karta, Tryb : Integer; 
begin 
DetectGraph(Karta,Tryb); 
InitGraph(Karta,Tryb,'c:\bp\bgi'); 
... 
End.

 

KaŜdy ewentualny błąd jaki powstanie podczas wykonywania instrukcji graficznych zwraca funkcja 
GraphResult. Wszystkie ewentulne błędy są reprezentowane przez stałe. PoniŜej znajduje się tabela z kodami i 
stałymi błędów, jaki zwraca funkcja GraphResult:

 

background image

STAŁA

 

WARTOŚĆ

 

OPIS

 

grOK

 

0

 

operacja graficzna wykonana pomyślnie

 

grNoInitGraph

 

-1

 

nie zainstalowano trybu graficznego

 

grNoDetect

 

-2

 

nie wykryto karty graficznej

 

grFileNotFund

 

-3

 

nie znaleziono pliku sterownika graficznego (BGI)

 

grInvalidDriver

 

-4

 

zastosowano niewłaściwy do załadowania sterownik graficzny

 

grNoLoadMem

 

-5

 

brakuje pamięci do załadowania sterownika graficznego

 

grNoScanMem

 

-6

 

przekroczenie pamięci przy wypełnianiu obszaru metodą scan

 

grNoFloodMem

 

-7

 

przekroczenie pamięci przy wypełnianiu obszaru metodą flood

 

grFontNotFund

 

-8

 

nie znaleziono pliku definiującego czcionki

 

grNoFontMem

 

-9

 

brakuje pamięci do załadowania kroju czcionek

 

grInvalidMode

 

-10

 

zastosowano niewłaściwy tryb lub sterownik graficzny

 

grError

 

-11

 

błąd operacji graficznych

 

grIOerror

 

-12

 

błąd wejścia - wyjścia graficznego

 

grInvalidFont

 

-13

 

zastosowano niewłaściwy krój czcionek

 

grInvalidFontNum

 

-14

 

zastosowano niewłaściwy numer kroju czcionek

 

Zawsze na koniec pracy w trybie graficznym naleŜy przywrócić tryb tekstowy, by nie wystąpiły ewentualne 
błędy. Do zamknięcia trybu graficznego słuŜy procedura CloseGraph. Jest to procedura bezparametrowa i 
powoduje powrót do trybu tekstowego. W programach moŜna wiele razy włączć i wyłączć tryb graficzny. Jeśli 
juŜ włączyłeś ten tryb i jesteś ciekaw jaką kartę graficzną masz zainstalowaną moŜesz to uczynić funkcją 
GetDriverName. Zwraca ona łańcuch zawierający nazwę aktualnego sterownika graficznego. Funckja 
GetModeName zwraca łańcuch zawierający nazwę aktualnego trybu graficznego.

 

W trybie graficznym kaŜdy punkt na ekranie ma swoje współrzędne X i Y. Współrzędna X rośnie od lewej do 
prawej, a Y z góry na dół. Punkt o współrzędnych X=1 i Y=1 leŜy w lewym górnym rogu ekranu. Moduł Graph 
daje nam równieŜ dwie bardzo poŜyteczne funkcje. GetMaxX i GetMaxY. Funkcja GetMaxX zwraca największą 
wartość współrzędnej poziomej X, natomiast GetMaxY pionowej Y. Jeśli chcesz więc napisać program, który 
niezaleŜnie od karty graficznej, a co za tym idzie rozdzielczości wstawił punkt w samym środku ekranu uŜycie 
tej funkcji jest niezbędne. Środek ekranu ma współrzędne X=GetMaxX div 2, a Y=GetMaxY div 2.

 

Większość z nas ma karty zgodne z VGA, więc będzie pracować w trybie graficzny określonym dla tych kart. 
Niestety tryb ten daje nam do dyspozycji tylko 16 kolorów. Jak sprawdzić na innych kartach, lub potwierdzić 
moje słowa o ilości dostępnych kolorów, naleŜy posłuŜyć się funkcją pezparametrową GetMaxColor, która 
zwraca największy z moŜliwych numerów koloru. W języku Turbo Pascal kolory mają swoje numery i stałe je 
reprezentujące. PoniŜej znajduje się tabela z kolorami i odpowiadjącymi im nazwami:

 

STAŁA

 

WARTOŚĆ

 

KOLOR

 

Black

 

0

 

czarny

 

Blue

 

1

 

niebieski

 

Green

 

2

 

zielony

 

Cyan

 

3

 

truskawkowy

 

Red

 

4

 

czerwony

 

Magenta

 

5

 

karmazynowy

 

Brown

 

6

 

brązowy

 

LightCray

 

7

 

jasnoszary

 

DarkCray

 

8

 

ciemnoszary

 

LightBlue

 

9

 

jasnoniebieski

 

background image

LightGreen

 

10

 

jasnozielony

 

LightCyan

 

11

 

jasnotruskawkowy

 

LightRed

 

12

 

jasnoczerwony

 

LightMagenta

 

13

 

jasnokarmazynowy

 

Yellow

 

14

 

Ŝ

ółty

 

White

 

15

 

biały

 

 

Pierwsze kroki

 

Nauczyliśmy się juŜ jak włączyć i wyłączyć tryb graficzny. Poradzimy sobie z ewentualnymi błędami. Potrafimy 
równieŜ koŜystać z funkcji GetMaxX i GetMaxY. Przejdźmy teraz do ciekawszych i przynoszących jakieś 
efekty procedur i funkcji. Zacznijmy od najprostrzej procedury PutPixel. Ogólna składnia tej procedury jest 
następująca:

 

PutPixel(X,Y : Integer; Pixel : Word);

 

Procedura wstawia w punkt o współrzędnych określonych przez X, Y i kolorze określonym przez Pixel. Jej 
odwrotnością jest bardzo przydatna funkcja GetPixel. Tej składnia jest następująca:

 

GetPixel(X,Y : Integer);

 

Funkcja ta zwraca numer koloru punktu, króry mieści się na ekranie o współrzędnych określonych przez X i Y. 
 
Przykładowy program z wykorzystaniem procedury PutPixel moŜe wyglądać tak:

 

uses Graph; 
var Karta, Tryb, i : Integer; 
begin 
DetectGraph(Karta, Tryb); 
InitGraph(Karta, Tryb, 'c:\bp\bgi'); 
if GraphResult<>grOk then halt; 
 
for i::=1 to 360 do PutPixel(GetMaxX div 2+Round(SIN(i)*10), GetMaxY div 2+Round(COS(i)*10),Yellow); 
 
Readln; 
CloseGraph; 
End.

 

PowyŜszy program rysuje na środku ekranu (dzięki funkcjom GetMaxX div 2 i GetMaxY div 2) okrąg o 
promieniu 10 i kolorze Ŝółtym. Nie jest on najpiękniejszy, ale dla nas wystarczy. Oczywiście Pascal umoŜliwia 
nam na prostrze rysowanie okręgów. Jest do tego celu specjalnie stworzona procedura. Składnia jej jest 
następująca:

 

Circle(X,Y : Integer; Radius : Word);

 

Rysuje ona okrąg o środku w punkcie określonym przez współrzędne X ,Y i promieniu Radius. Promień jest 
typu Word, a więc nie moŜe przyjmować wartości ujemnych. Ten sam rezultat co wyŜej za pomocą procedury 
Circle wyglądał by tak:

 

uses Graph; 
var Karta, Tryb, i : Integer; 
begin 
DetectGraph(Karta, Tryb); 
InitGraph(Karta, Tryb, 'c:\bp\bgi'); 
if GraphResult<>grOk then halt; 

background image

 
SetColor(Yellow); 
Circle(GetMaxX div 2, GetMaxY div 2, 10); 
 
Readln; 
CloseGraph; 
End.

 

Procedura SetColor z parametrem Yellow, który jest typu Word, określa kolor w jakim zostanie narysowany 
okrąg. Większość funkcji i procedur rysuje figury na kolor określony właśnie za pomocą tej procedury. 
Wszystkie figury będą rysowane na kolor określony przez SetColor dopóki nie zostanie on zmieniony za pomocą 
tej właśnie procedury. By uzyskać informacje o aktualnym kolorze, czyli takim jakim rysujemy, trzeba posłuŜyć 
się bezparametrową funkcją GetColor. Zwraca ona numer aktualnego koloru. Do ustawiania koloru tła słuŜy 
procedura SetBKColor o składni:

 

SetBkColor(Color : Word);

 

gdzie Color - jest kolorem tła

 

By sprawdzić, jakie aktualnie mamy tło uŜyjemy funkcji GetBkColor. Zwraca ona numer koloru tła.

 

Kiedy mamy juŜ zamazany cały ekran i przychodzi chwila, kiedy trzeba go wyczyścić, uŜywamy procedury 
ClearDevice.

 

Kolejnym często uŜywanym poleceniem jest Line. Składnia tej procedury jest następująca:

 

Line(X1,Y1, X2, Y2 : Integer);

 

Procedura rysuje linię prostą o końcach o współrzędnych X1,Y1 i X2,Y2.

 

Odpowiednikiem procedury GotoXY w trybie graficznym jest procedura MoveTo. Składnia tej procedury jest 
następująca:

 

MoveTo(X,Y : Integer);

 

Procedura przesuwa kursor na pozycję o współrzędnych określonych przez X,Y. W trybie graficznym moŜna 
uŜywać równieŜ dwóch funkcji: GetX i GetY. Zwracają one wartość współrzędnej kursora (X lub Y).

 

Procedura MoveRel o takiej samej składni przesuwa wpółrzędne kursora względem aktualnej pozycji o X,Y. 
Procedura LineTo o składni:

 

LineTo(Dx,Dy : Integer);

 

rysuje odcinek o współrzędnych: aktualnej pozycji kursora i współrzędnych punktu określonego przez Dx i Dy. 
Procedura LineRel o takie samej składni rysuje linię od punktu o współrzędnych aktualnych przez aktualną 
pozycję kursora, do punktu o współrzędnych przesuniętych względem pozycji kursora o Dx i Dy. Trochę to 
zagmatfane, ale chyba wszyscy zrozumieli :-))).

 

Pascal umoŜliwia nam wybór rodzaju linii, jaką chcemy rysować. Do tego celu słuŜy procedura SetLineStyle. Jej 
składnia jest następująca:

 

SetLineStyle(LineStyle : Word; Pattern : Word; Thickness : Word);

 

Parametr LineStyle określa rodzaj linii, Pattern - wzorzec i Thickness - grubość. By dowiedzieć się jakim 
aktualnie rysujemy stylem linii trzeba posłuŜyć się procedurą GetLineSettings. Jej składnia wygląda tak:

 

background image

GetLineSettings(var LineInfo : LineSettingsType);

 

Procedura w zmiennej Linenfo, która jest typu LineSettingsType zwraca rodzaj, wzorzec oraz grubość linii, 
którą aktualnie rysujemy. Typ LineSettingsType ma postać:

 

TYPE LineSettingsType = RECORD 
LineStyle : Word; 
Pattern : Word; 
Thickness : Word; 
END;

 

Narysujmy teraz przy pomocy linii prostokąt.

 

Line(100,50,200,50); 
Line(200,50,200,150); 
Line(200,150,100,150); 
Line(100,150,100,50);

 

Do rysowania prostokątów Pascal daje nam odzielną procedurę. PowyŜszy program moŜna zapisać jako:

 

Rectangle(100,50,200,150);

 

Procedura ta ma następującą składnię:

 

Rectangle(X1,Y1, X2, Y2 : Integer);

 

Współrzędne X1,Y1 są współrzędnymi lewego górnego rogu prostokąta, natomiast X2,Y2 prawego dolnego. 
MoŜna to sobie wyobrazić jako przekątną danego prostokąta.

 

Procedura Arc o składni:

 

Arc(X,Y: Integer; StAngle, EndAngle, Radius: Word);

 

powoduje narysowanie łuku okręgu o środku w punkcie X,Y i promieniu Radius. Początek łuku określony jest 
przez StAngle, a koniec przez EndAngle. Podobną do instrukcji Arc jest procedura Ellipse. Ma ona następującą 
składnię:

 

Ellipse(X,Y : Integer; StNagle, EndAngle : Word;XRadius,YRadius : Word);

 

Powoduje ona narysowanie wycinka elipsy o środku w punkcie X,Y, kącie początkowym StAngle, kącie 
końcowym EndAngle oraz promieniach X-XRadius i Y-YRadius.

 

 

Napisy

 

By wstawić jakiś napis na ekran w trybie graficznym, nie moŜna posłuŜyć się procedurami Write ani Writeln. W 
Pascal'u zostały stworzone do tego celu specjalne procedury. Teksty są na ekranie rysowane, mogą być rysowane 
róŜnymi czcionkami, dlatego wstawienie dwóch liter w tym samym miejscu ekranu, nie spowoduje zamazanie 
tej pierwszej, tylko narysowanie jej na wcześniejszej.

 

Procedura OutText ma następującą składnię:

 

OutText(TextString : String);

 

background image

Powoduje ona narysowanie napisu TextString na ekranie w miejscu określonym połoŜeniem kursora. Do 
określania połoŜenia kursora uŜywa się wcześniej opisaną procedurę MoveTo. Druga procedura do rysowania 
napisów na ekranie ma następującą składnię:

 

OutTextXY(X,Y : Integer; TextString : String);

 

RóŜni się ona od poprzedniej tym, Ŝe moŜemy określić miejsce rysowania naszego napisu. Obie procedury 
rysują napisy w kolorze określonym przez SetColor.

 

Do określania czcionki itp. słuŜy procedura SetTextStyle. Jej struktura wygląda tak:

 

SetTextStyle(Font : Word; Direction : Word; CharSize : Word);

 

 

Font - rodzaj czcionki, (0..10)

  

 

Direction - kierunek (0-poziomo; 1-pionowo)

  

 

CharSize - wielkość czcionki (1..10)

  

Procedury OutText i OutTextXY pozwalają na wstawianie napisów na ekran. By wstawić jakąś liczbę, trzeba 
posłuŜyć się procedurą Str:

 

Str(X[:Width [:Decimals] ]; var S);

 

Powoduje ona zmianę wartości numerycznej X na wartość łnńcuchową S. Odwrotnością jej jest procedura Val:

 

Val(S; var V; var Code : Integer);

 

Procedura ta powoduje zmianę wartości łańcuchową S na liczbową V. W przypadku wystąpienia jakiegoś błędu 
zmienna Code ma wartość róŜną od 0.

 

W trybie graficznym kaŜda litera, ciąg liter moŜe mieć róŜną długość i wysokość. Do określania tych 
właściwości słuŜą dwie funkcje:

 

 

TextHeight(TextString : String);

  

 

TextWidth(TextString : String);

  

Pierwsza zwraca wysokość naszego tekstu (TextString), natomiast druga jego długość. By np. wstawić napis 
BINBOY dokładnie na środku ekranu, napisalibyśmy:

 

... 
Napis:='BINBOY'; 
OutTextXY(GetMaxX div 2-TextWidth(Napis) div 2,GetMaxY div 2-TextHeight(Napis) div 2, Napis); 
...

 

Wypełnianie figur

 

Procedura FloodFill o składni:

 

FloodFill(X,Y : Integer; Border : Word);

 

powoduje wypełnienie wnętrza obszaru zamkniętego linią i obejmującego punkt o współrzednych X,Y. Brzeg 
tego obszaru zostanie zaznaczony kolorem określonym przez Border. Wypełniany obszar jest w sposób 
określony przez SetFillStyle.

 

< p>  

background image

Procedura ustala sposób wypełniania figur. Zmienna Pattern określa rodzaj wypełnienia (1..10), zmienna Color 
ustala kolor wypełnienia.

 

Procedura Bar o składni:

 

Bar(X1,Y1,X2,Y2 : Integer);

 

Rysuje prostokąt w ten sam sposób co Rectangle, tyle Ŝe zostaje on wypełniony w sposób określony procedurą 
SetFillStyle;

 

Podobną do instrukcji Bar jest procedura Bar3D. Ma ona następującą składnię:

 

Bar3D(X1,Y1, X2, Y2 : integer; Depth: Word; Top: Boolean);

 

Powoduje ona narysowanie trójwymiarowego wypełnionego prostopadłościanu. Ściana czołowa ma współrzędne 
(X1,Y1) (X2,Y2). Zmienna Depth określa głębie prostopadłościanu, natomiast zmienna Top określa, czy ma być 
rysowana górna powierzchnia prostopadłościanu.

 

 

Wycinanie obrazów

 

By wyciąć dany element obrazu trzeba przydzielić mu odpowiednią ilość pamięci. W tym celu trzeba uŜyć 
funkcji ImageSize. Ma ona następującą składnię:

 

ImageSize(X1,Y1,X2,Y2 : Integer);

 

Gdzie za pomocą prostokąta o wierzchołkach X1,Y1 i X2,Y2 obliczamy ilość pamięci jaka będzie potrzebna do 
zapamietania obrazka. Wiedząc juŜ ile pamięci będzie nap potrzebne, trzeba przydzielić tą pamięć. Do tego celu 
słuŜy procedura GetMem. Ogólna jej składnia jest następująca:

 

GetMem(var P : Pointer; Size: Size);

 

Powoduje przydzielenie bloku pamięci o wielkości Size i zwraca wskaźnik na ten blok w zmiennej P. Odwołanie 
do tego bloku następuje poprzez P^. By sprawdzić ile w danej chwili mamy dostępnej pamięci trzeba uŜyć 
funkcji MaxAvail, która zwraca jej wartość. Po zakończeniu programu naleŜy zwolnić przydzieloną wcześniej 
pamięć uŜywając procedury o składni:

 

FreeMem(var P : Pointer; Size: Word);

 

Powoduje ona zniszczenie zmiennej wskazywanej przez P i zwolnienie zajmowanej przez nią pamięci.

 

Mając juŜ przydzieloną pamięć naleŜy skopiować do niej nasz rysunek. Do tego celu słuŜy procedura GetImage 
o składni:

 

GetImage(X1,Y1,X2,Y2 : Integer; var BitMap);

 

Gdzie za pomocą X1,Y1 i X2,Y2 ustalamy okno, które jest kopiowanej pod adres BitMap.

 

Mamy juŜ zapamietany obrazek. By go wyświetlić posłuŜymy się procedurą PutImage. Ma ona następującą 
składnię:

 

PutImage(X,Y : Integer; var BitMap; BitBlt : Word);

 

Procedura ta słuŜy do wyświetlania na ekranie uprzednio zapamiętanego prostokątnego obrazu po zmienną 
BitMap. Współrzędne X,Y określają lewy górny róg tego obrazka, a parametr BitBld określa stosowany operator 
binarny podczas nakładania zapamiętanego obrazu na ekranie. MoŜe on przyjąć następujące wartości:

 

background image

 

CopyPut 0 (operacja MOV)

  

 

XORPut 1 (operacja XOR)

  

 

ORPut 2 (operacja OR)

  

 

ANDPut 3 (operacja AND)

  

 

NOTPut 4 (operacja NOT)

  

 

Strony

 

Turbo Pascal umoŜliwia nam pracę na kilku stronach graficznych, w zaleŜności od rodzaju i trybu pracy karty 
graficznej. Jest to bardzo przydatne. Do obsługi stron słuŜą dwie procedury:

 

SetActivePage(Page : Word);

 

Ustala aktywną stronę, czyli są na której będziemy rysować,oraz

 

SetVisualPage(Page : Word);

 

Ustala stronę, którą w danej chwili widzimy. Stosując strony moŜna np. wyświetlić napis "Loading...", podczas 
którego przygotowywać kolejną stronę. Jeśli pisałeś kiedyś jakąś animację, na pewno ekran strasznie skakał. 
Było widać jak rysuje się dany element, a później ściera. Strony pozwalają je wyeliminować.

 

 

Dołączanie sterowników

 

ZauwaŜyłeś pewnie, Ŝe po skompilowaniu programu jeśli zaniesiesz go koledze, to moŜe nie działać. 
Spowodowane jest to, Ŝe albo ten kolega nie ma sterowników BGI uŜywanych w twoim programie, albo ma je w 
innym miejscu. Sterowniki BGI są odpowiedzialne za obsługę grafiki i nie są dołączane do pliku 
wykonywalnego EXE. Jednak moŜna to zrobić samemu. W tym celu trzeba zrobić:

 

 

Utworzyć pliki OBJ z plików BGI. Do tego celu słuŜy program BINOBJ. Jego uŜycie jest następujące: 
BINOBJ <plikBGI> <plikOBJ> <NazwaProcedury>

  

 

Jeśli mamy juŜ pliki OBJ dołączamy je do naszego programu uŜywając dyrektywy $L, np. {$L 
EGAVGA.OBJ}

  

 

Tworzymy procedury EXTERNAL procedure EgaVgaDriverProc : external;

  

 

Teraz musimy tylko zarejestrować obecność sterownika w pliku: 
RegisterBGIDriver(@EGAVGADriverProc); Jest to funkcja. Jeśli przyjmie ona wartość <0 tzn. Ŝe 
wystąpił błąd.

  

 

Inicjujemy tryb graficzny InitGraph(karta,tryb,'');

  

W ten sam sposób moŜna dołącza do pliku sterowiniki do czcionek. Postępowanie jest takie same, tylko 
rejestrujemy je komendą RegisterBGIFont.