kurs pascala

background image

KURS

PASCALA

WSTĘP

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
CO2ST
TYPE
VAR
PROCEDURE
FU2CTIO2
{Koniec części opisowej}
BEGI2

background image

{Część wykonawcza programu}
E2D.

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;
...
BEGI2
GOTO skok_1;
...
...{Jakieś funkcje czy procedury.}
...
skok_1: Writeln('Skok do etykiety skok_1');
skok_2: Writeln('Skok do etykiety skok_2');
E2D.

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.

CO2ST MaxWysokosc = 100;
MaxPredkosc = 10;
lub

CO2ST 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 (CO2ST). 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;
...
BEGI2
Wynik:=0; {Wartość początkowa}
...
Wynik:=10; {Wartość przypisana później}
E2D.

P

rocedurę (PROCEDURE) lub funkcję (FU2CTIO2) 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
BEGI2
...Ciąg_instrukcji
E2D;

W definicji procedury listę parametrów możemy pominąć.

Definicja funkcji:

FU2CTIO2 Nazwa_Funkcji(lista_parametrów): Typ_wyniku;
...Część_opisowa
BEGI2
...Ciąg_instrukcji
E2D;

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 Boolean, ByteBool, WordBool 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;
...
BEGI2
...
GOTO et;
...
x := a+2;
...
E2D.

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]);
BEGI2
...
E2D;

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:

I2LI2E (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:

I2LI2E ($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

BEGI2
Instrukcja_1;
Instrukcja_2;
...
Instrukcja_n
E2D

Przykład:

BEGI2
a:=1;
b:=a+4;
c:=a-b;
GOTO Franek;
E2D

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 THE2 instrukcja

lub

IF wyrażenie THE2 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 THE2 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
E2D

lub

CASE wyrażenie OF
sekwencja_instrukcji_wyboru
ELSE instrukcja
E2D

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
'+' : BEGI2
d:=d+1;
z:=z-1;
E2D;
'-' : BEGI2
d:=d-1;
z:=z+1;
E2D;
E2D;

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 DOW2TO 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 DOW2TO 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 BEGI2

background image

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

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

REPEAT
Instrukcja_1
Instrukcja_2
...
Instrukcja_n
U2TIL 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;
U2TIL 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;
E2D;

Przypisanie do tego rekordu w instrukcji wiążącej
jest następujące:

WITH comp DO
BEGI2
re:=1;
im:=1;
E2D;

Jest to równoważne z takim przypisaniem w instrukcji
złożonej:

BEGI2
comp.re:=1;
comp.im:=1;
E2D;

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
E2D;

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

U2IT Nazwa_modułu;

I2TERFACE

{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}

IMPLEME2TATIO2

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}

E2D.{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

Błędy podczas programowania

Błę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

Błę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 GRAFICZ2A

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ŚĆ

2R. PALETY

LICZBA

STRO2

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.

2apisy

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.


Wyszukiwarka

Podobne podstrony:
Kurs Pascal
INDEX , Kurs Pascala dla poczatkujacych
kurs pascala
PASCAL kurs, SPIS TREŚCI, SPIS TREŚCI:
PASCAL kurs, Turbo Pascal - moduly uzytkowe, WSTĘP
PASCAL kurs, Turbo Pascal - moduly uzytkowe, WSTĘP
PASCAL kurs, KURS TURBO PASCALA, KURS TURBO PASCALA - wstęp
Kurs języka Turbo Pascal(1)
Kurstpv10, Kurs Turbo Pascal 7
Kurs Turbo Pascal 7.0 By Kajoj
24 C i Pascal kurs podstawowy
Turbo Pascal kurs, Technik Informatyk, Programowanie strukturalne i obiektowe Turbo Pascal
Kurs Turbo Pascal 7 0
Kurs-jezyka-Turbo-Pascal, ♪ DOKUMENTY(Arkusze-matura-inne), ♥ Edukacja i Technika, Informatyka
PEŁNY KURS TURBO PASCALA

więcej podobnych podstron