PODSTAWY PROGRAMOWANIA
Pierwszy opis języka Pascal
opublikował w 1971 r. Niklaus Wirth. Pomyślany on był jako język służący do
nauki programowania. Pascal stosowany początkowo do celów edukacyjnych stał się
profesjonalnym narzędziem informatycznym. Od tego czasu pojawiło się wiele
wersji tego języka, znacznie odbiegających od pierwowzoru, łamiących nawet
strukturalizm języka. Międzynarodowa Organizacja Normalizacyjna ISO
przedstawiła w 1980 roku celem ujednolicenia propozycję standardu Pascala.
Produkt firmy Borland International Inc. - Turbo Pascal odbiega od niego
znacznie.
Budowa
Programy napisane w języku Turbo Pascal, tak jak i w
większości innych języków, posiadają swoją własną określoną budowę. Program
taki powinien składać się z nagłówka, deklaracji modułów oraz bloku głównego. W
jego nagłówku określamy nazwę naszego programu. Nazwa ta nie jest jednak
nigdzie wyświetlana, jest widoczna tylko w kodzie źródłowym dla wiadomości
programisty. Przykładowy nagłówek może wyglądać np. tak:
PROGRAM Nazwa_programu;
W nazwie programu można używać liter, cyfr i znaku
podkreślenia. Nie wolno natomiast zacząć nazwy od cyfry, ani używać w niej
nawiasów, kropek itp. Występuje ona po słowie PROGRAM. Podczas pisania
programów zaleca się wstawianie nagłówka, jednak nie jest on konieczny. Występuje
opcjonalnie.
Kolejnym elementem programu jest deklaracja modułów.
"Mówi" ona kompilatorowi, jakie moduły mają zostać dołączone do
programu. Dołączane moduły udostępniają nam dodatkowe procedury i funkcje
(polecenia, które będziemy później mogli użyć). Istnieje wiele modułów. Można
również tworzyć własne. Dokładnie zostaną one omówione w części Moduły.
Przykładowa deklaracja modułów może wyglądać następująco:
USES Crt, Dos;
Wszystkie moduły deklarowane są po słowie kluczowym USES i
są oddzielone między sobą przecinkiem. Deklaracja modułów występuje (tak jak
nagłówek) opcjonalnie. Skromną część procedur i funkcji udostępnia nam moduł
SYSTEM, który dołączany jest do naszego programu automatycznie.
Po deklaracji modułów występuje blok główny programu.
Mieści się on pomiędzy słowami BEGIN (początek) i END. (koniec). Blok ten jest
obowiązkowy. Poprawnie napisany program wyglądać może tak:
PROGRAM Moj_pierwszy_program;
USES Crt, Dos;
BEGIN
...treść programu...
END.
Wielkość liter w programach napisanych w języku Turbo
Pascal nie gra roli (w przeciwieństwie do programów napisanych np. w C/C++).
Można więc używać i małych, i wielkich liter. Każda napisana poprawnie
instrukcja powinna być zakończona średnikiem. Zapominanie wstawienia średnika
jest podstawowym błędem popełnianym przez początkujących, uniemożliwiającym
poprawną kompilację.
Napiszmy więc prosty program wyświetlający na ekranie
napis. Do wyświetlenia napisu użyjemy procedury WRITELN. Ponieważ znajduje się
ona w module SYSTEM nie musimy deklarować żadnych innych unitów (modułów).
PROGRAM Napis;
BEGIN
Writeln('Witam uczniów
PSP na zajeciach');
END.
Sposób pisania
Jeśli już będziesz pisał dłuższe, rozbudowane
programy powinieneś pamiętać o komentarzach. Komentarze są to teksty
(objaśnienia), których kompilator nie bierze pod uwagę, są one ignorowane.
Widoczne są tylko przez programistę. Komentarze wstawia się między nawiasami
klamrowymi "{" i "}" lub między dwu znakami "(*"
i "*)". Wstawianie ich jest bardzo ważne, gdyż w dużych programach
łatwo się można pogubić.
Kolejnym elementem są odstępy. Pisanie "brzydkie"
polega na pisaniu programu "ciurkiem", z góry na dół. Kiedy w
programie występuje wiele pętli, przez co jest wiele słów BEGIN i END, można się łatwo pogubić i przez przypadek
postawić o jeden END więcej, co w rezultacie spowoduje błąd i przerwanie
kompilacji. Dlatego powinniśmy robić odstępy (spacjami lub tabulatorem), np.
każdy blok (polecenia między BEGIN
i END) przesunąć w prawo
o kilka spacji.
Kompilacja
By uruchomić napisany przez nas program trzeba go najpierw skompilować,
czyli przetłumaczyć z języka zrozumiałego przez człowieka na język zrozumiały
przez komputer. Do tego celu używa się różnych kompilatorów zewnętrznych np.
TPC, można również skorzystać z kompilatora wewnętrznego. Kombinacja klawiszy
Alt+F9 (COMPILE/COMPILE) wykonuje kompilację programu znajdującego się w
aktywnym okienku edycyjnym. Zostanie wyświetlone okienko z postępem
zaawansowania. Kiedy proces zakończy się sukcesem, należy dowolnym klawiszem
wyłączyć ów okienko. Klawiszem F9 (COMPILE/MAKE) wykonujemy kompilację
wszystkich plików związanych z programem znajdującym się w okienku głównym,
które nie uległy od ostatniej kompilacji zmianie. Następuje wtedy kompilacja
programu głównego oraz modułów (jeśli zostały zadeklarowane). Poleceniem
COMPILE/BUILD wykonujemy kompilację taką jak wyżej z tą różnicą, że kompilowane
są zbiory nawet jeśli nie uległy zmianie. Skompilowanie dowolną metodą pliku
programu powoduje powstanie pliku wykonywalnego EXE. Jeśli kompilujemy moduł,
to zostanie stworzony plik TPU. Jeśli chcemy zobaczyć wynik naszej pracy możemy
kombinacją klawiszy Ctrl+F9 lub RUN/RUN uruchomić istniejący w oknie głównym
program. Nie wolno używać CTRL+F9, kiedy w okienku edycyjnym mamy kod źródłowy
modułu.
BUDOWA PROGRAMU
Bloki
Blok, zarówno programu głównego, jak i
procedur, czy funkcji składa się z dwóch części: deklaracyjnej i instrukcyjnej.
Pierwsza występuje opcjonalnie, natomiast druga być powinna. Część instrukcyjna
mieści się między słowami kluczowymi BEGIN i END;, przed nią znajduje się część
deklaracyjna. W części tej deklarujemy następujące elementy:
·
etykiety
·
stałe
·
zmienne
·
typy
·
procedury
·
funkcje
Wszystkie zadeklarowane elementy są dostępne w obrębie
tylko danego bloku. Z tego wynika, że elementy zadeklarowane w programie
głównym są dostępne we wszystkich procedurach, funkcjach i bloku głównym.
Symbole podstawowe
W programach napisanych za pomocą języka
Turbo Pascal używa się następujących symboli:
·
liter wielkich : ABCDEFGHIJKLMNOPQRSTUVWXYZ
·
liter małych: abcdefghijklmnopqrstuvwxyz
·
cyfr: 0123456789
·
znaku podkreślenia : _
·
znaków specjalnych : +-*/=<>[],.():;'@{}$#
·
znaków podwójnych : <=>= := .. (* *) (..)
W programach występują również identyfikatory. Służą one do
opisu programów, modułów, typów, stałych, zmiennych, funkcji, itp.
Identyfikatory określają nazwę danego elementu. Za pomocą tych nazw będziemy
mogli się odwoływać do danego elementu. W nazwach można używać liter małych,
wielkich, cyfr i znaku podkreślenia. Nie wolno jednak zacząć nazwy
identyfikatora cyfrą. Tak mogą wyglądać przykładowe identyfikatory:
imię, nazwisko, liczba, x,... itp.
Słowa kluczowe
W Pascalu (jak i w większości innych
językach) zostały wyodrębnione pewne identyfikatory o szczególnym znaczeniu.
Używa się ich w z góry określony sposób. Nie mogą być zmieniane przez
programistę, w przeciwieństwie do procedur, czy funkcji. Ich nazw nie wolno
niegdzie w programie użyć jako identyfikatora do jakiegoś elementu. Noszą one
nazwę słów kluczowych oraz dyrektyw. Wszystkie słowa kluczowe poprawnie
napisane są wyświetlane standardowo białym kolorem. Te słowa to:
and |
file |
of |
type |
array |
for |
or |
unit |
asm |
function |
packed |
uses |
begin |
goto |
procedure |
var |
case |
if |
program |
while |
const |
implementation |
record |
with |
constructor |
in |
repeat |
xor |
destructor |
inherited |
set |
|
div |
label |
shl |
|
do |
mod |
shr |
|
downto |
nil |
string |
|
else |
not |
then |
|
end |
object |
to |
|
Do standardowych dyrektyw należą:
absolute |
foward |
public |
assembler |
interrupt |
virtual |
external |
near |
|
far |
private |
|
Liczby
Język Pascal daje nam do dyspozycji dwa
systemy liczbowe: dziesiętny i szesnastkowy. Każda liczba zapisana w systemie
szesnastkowym powinna być poprzedzona znakiem '$'. Wszystkie liczby bez tego
znaku są traktowane jako liczby zapisane w systemie dziesiętnym. W systemie
dziesiętnym mamy do dyspozycji cyfry od 0 do 9, natomiast w systemie
szesnastkowym od 0 do 9 i od A do F. Przy zapisie liczb rzeczywistych można
również używać notacji naukowych. Pascal daje nam następujące notacje:
·
m - liczba rzeczywista ze znakiem, określająca mantysę
liczby
·
c - liczba całkowita ze znakiem, określająca cechę liczby
·
e - symbole notacji naukowej
Oto przykładowe liczby:
35, $F,$14, -3.14159, 3.2E10,
2.7E-10
Etykiety
Etykiety służą do oznaczania pewnych miejsc w
programie. Za pomocą nich będziemy mogli w każdej chwili "skoczyć"
pod dane miejsce. Każda etykieta powinna być zakończona znakiem ":"
(dwukropek) i powinna być zadeklarowana w części deklaracyjnej. Do tego celu używa
się słowa kluczowego LABEL. By kazać programowi skoczyć do danej etykiety używa
się polecenia GOTO. Skok jednak jest możliwy tylko w obrębie danego bloku i
jest to skok bezwarunkowy np.:
LABEL Poczatek, Koniec;
BEGIN
...
Poczatek:
...
Koniec:
...
GOTO Poczatek;
END;
Zalecane jest nie stosowanie skoku bezwarunkowego.
Wykorzystuj polecenie GOTO tylko w ostateczności. Lepiej jest użyć np.
instrukcji REPEAT lub FOR.
TYPY
DANYCH
W języku Turbo Pascal każda stała, zmienna, funkcja itp.
musi być ściśle określonego typu. Na podstawie tego typu kompilator rezerwuje
odpowiednią ilość pamięci na dany element. Typ ten charakteryzuje zbiór
wartości przyjmowanych przez niego. W Pascalu istnieje bardzo wiele różnych
typów. Programista ma możliwość również tworzenia własnych. Możemy wyróżnić
cztery standardowe typy:
1. Typ liczb
całkowitych
2. Typ liczb
rzeczywistych
3. Typ znakowy
4. Typ logiczny
Dodatkowo typy definiowane przez użytkownika można
podzielić na:
1. Typ okrojony
2. Typ wyliczeniowy
3. Typ łańcuchowy
4. Typ wskaźnikowy
5. Typ tablicowy
6. Typ rekordowy
7. Typ obiektowy
8. Typ zbiorowy
9. Typ plikowy
10. Typ proceduralny
Typ całkowity
Wszystkie elementy tego typu stanowią zbiór
liczb całkowitych. Różnią się tylko przedziałem, a co za tym idzie ilością
pamięci potrzebnej na zapisanie danej liczby. Istnieją następujące typy
całkowite:
TYP |
ZAKRES |
ROZMIAR |
ShortInt |
-128..127 |
1 |
Byte |
0..255 |
1 |
Integer |
-32768..32767 |
2 |
Word |
0..65635 |
2 |
LongInt |
-2147483648..2147483647 |
4 |
Typ rzeczywisty
Dane tego typu stanowią zbiór liczb
rzeczywistych. Poszczególne podtypy różnią się między sobą zakresem oraz
ilością zajmowanej przez nie pamięci. Mamy więc następujące podtypy:
TYP |
ZAKRES |
LICZBA CYFR
ZNACZĄCYCH |
ROZMIAR |
Single |
1.5e-45..1.7e38 |
7-8 |
4 |
Real |
2.9e-39..1.7e38 |
11-12 |
6 |
Comp |
-2.63+1..2e63-1 |
19-20 |
8 |
Double |
5.0e-324..1.7e308 |
15-16 |
8 |
Extended |
3.4e-4932..1.1e4932 |
19-20 |
10 |
Jeśli przy deklaracji elementu typu Comp lub Extended
pokaże się komunikat: "Must be in 8087 mode to compile this.", to
znaczy, że musisz w menu OPTIONS/COMPILER w dziale Numeric processing wybrać
opcję 8087/80287 :-).
Typ łańcuchowy
Dane typu łańcuchowego składają się z ciągu znaków. Ciąg
ten poprzedzony jest jednym bajtem, w którym zapisana jest jego długość. Z tego
też względu maksymalna długość ciągu wynosi 255 znaków. (Jeśli potrzebujesz
zmiennej typu łańcuchowego dłuższej niż 255 znaków, to zajrzyj do strony Dyrektywy).
Typ łańcuchowy deklarujemy za pomocą słowa kluczowego STRING. Zadeklarowany
element domyślnie przyjmuje długość 255 bajtów. Zalecane jest, aby określać
jego długość samemu. W tym celu po słowie STRING w nawiasach kwadratowych
wpisujemy liczbę określającą długość naszego elementu, a co za tym idzie ilość
pamięci potrzebnej na jego zapamiętanie. Zmienne i stałe tego typu mogą być
traktowane przez użytkownika jako tablica, np., aby zmienić trzecią literę
zmiennej na K napiszemy:
Nazwa_zmiennej[3]:='K';
Jeśli chcemy dowiedzieć się o długości naszej zmiennej
posłużymy się funkcją Length bądź odczytamy zerowy bajt naszej zmiennej za
pomocą polecenia Ord np.:
długość_łańcucha:=Ord(Nazwa_zmiennej[0]);
Gdybyśmy chcieli zmienić wszystkie litery z małych na
wielkie moglibyśmy posłużyć się funkcją Upcase. Jednak pozwala ona zmieniać
tylko jedną literę. Przykładowy ciąg instrukcji zmienia wielkość liter w
zmiennej NAPIS na wielkie:
VAR NAPIS : STRING[10];
{deklarowanie zmiennej
NAPIS typu string o długości 10 znaków}
BEGIN
FOR I:=1 TO
LENGTH(NAPIS) DO
NAPIS[I]:=UPCASE(NAPIS[I]);
END;
Typ wyliczeniowy
Typ wyliczeniowy definiuje zbiór
identyfikatorów oznaczających poszczególne wartości przez ich wyliczenie.
Pierwszy identyfikator ma wartość 0, dla kolejnego 1 itd. Przykład:
TYPE Tydzien=(Niedziela,
Poniedzialek, Wtorek, Sroda, Czwartek, Piatek, Sobota);
Typ znakowy
Typ znakowy określa zbiór znaków. Do zmiennej
tego typu można, więc zapamiętać kod ASCI jednego znaku.
TYPE Znak=CHAR;
Typ logiczny
Typ logiczny jest typem wyliczeniowym,
który może przyjąć tylko dwie wartości: FALSE, wtedy wartość porządkowa wynosi
0 (fałsz) i TRUE wartość porządkowa jest większa niż 0 (prawda). Istnieją
cztery podtypy:
TYP |
ROZMIAR W BAJTACH
|
Boolean |
1 |
ByteBool |
1 |
WordBool |
2 |
LongBool |
4 |
Typ proceduralny
Język Turbo Pascal traktuje procedury i
funkcje jako elementy języka, które można przywiązywać do zmiennych i przesyłać
jako parametry. Przykładowa deklaracja typu proceduralnego może wyglądać tak:
TYPE
A=Procedure;
B=Procedure(a:Byte);
C=Function(A:Byte):CHAR;
</BLOCKQUOTE<
Zmienne typu proceduralnego nie mogą być zwracane przez
funkcję.
Typ okrojony
Typ okrojony określa podzbiór
dowolnego typu porządkowego lub wyliczeniowego. Jest on ograniczony pewnym
zakresem. Wykorzystywany jest do określania typu zmiennych, które mogą przyjąć
wartości ze ściśle określonego przedziału, np.
TYPE Rok=1990..1999;
VAR a : Rok;
Teraz zmienna "a" może przyjąć wartości od 1990
do 1999.
Typ wskaźnikowy
Typ wskaźnikowy pozwala na
określenie zmiennych, za pomocą, których będziemy mogli odwoływać się od
pewnych obszarów pamięci operacyjnej. Istnieją następujące deklaracje typu
wskaźnikowego.
TYPE
Wsk_1 = ^Typ_podstawowy;
Wsk_2 = Pointer;
Wsk_3 = PChar;
Typ tablicowy
Typ ten określa tablicę
składającą się ze stałej liczby elementów. Wszystkie elementy tablicy muszą być
również określonego typu. Do każdego elementu odwołujemy się poprzez indeks
podawany w nawiasach kwadratowych i określający pozycję danego elementu. Każda
tablica może być wielowymiarowa. Przykładowa deklaracja tablicy 100 znaków może
wyglądać następująco:
Nazwa_tablicy: ARRAY[1..100] of
Char;
Słowo kluczowe ARRAY, służy właśnie do definiowania tablic.
Na końcu tej definicji, typ Char oznacza, że każdy element tej tablicy jest
typu Char, czyli jest to znak. By zmienić trzeci element tablicy możemy napisać
tak:
Nazwa_tablicy[3]:='K';
Każdą tablicę można przedstawić w postaci tabeli. By
stworzy tablicę, w której zapamiętalibyśmy tabliczkę mnożenia do 10, moglibyśmy
napisać:
Mnozenie : Array[1..10,1..10] of
Word;
Powyższa deklaracja tworzy tablicę, którą graficznie można
przedstawić jako tabelę o 10 wierszach i 10 kolumnach.
Typ rekordowy
Opisuje złożoną strukturę
danych. Taka struktura składa się z kilku pól. Każde z nich jest ściśle
określonego typu. Definicję rekordu zamieszcza się między słowami kluczowymi
RECORD i END;.
Przykładowo by zapamiętać dane o pracownikach w jakiejś
firmie, używając samej definicji tablicy byłoby to bardzo trudne, lub nawet
niemożliwe. Używając tablicy typu X, gdzie X jest typem rekordowym, wykonanie
powyższego zadania jest bardzo proste:
TYPE
Osoba = RECORD
Imie: String[10];
Nazwisko : String [20];
Wiek : Byte;
END;
VAR Ludzie: Array[1..1000] of Osoba;
Do odczytania informacji zapisanych w danym polu rekordu
używa się kropki ("."). np.:
Writeln(Ludzie[10].imie);
Ludzie[11].nazwisko:='Nowak';
Jeśli chcemy np. podać wszystkie dane osoby nr. 2 można
napisać:
WITH Ludzie[2] DO
BEGIN
Imie:='Jan';
Nazwisko:='Nowak';
Wiek:=20;
END;
Można również deklarować rekordy z wariantami o zmiennej
strukturze. Rekord taki zawiera specjalne pole, którego wartość decyduje o
wyborze wariantu układu pól w zmiennej części rekordu. Pole to nazywa się
wyróżnikowym. Rekord wariantowy zajmuje obszar pamięci potrzebny do
zapamiętania rekordu o najdłuższej części wariantowej. Jednak odmiennie
interpretuje dane różnych wariantów. Przykładowy rekord z wariantem:
TYPE Osoba = RECORD
Imie: String[10];
Nazwisko: String[20];
Case Stan_cywilny OF
samotny: ();
zonaty: (Data_slubu: String[10]);
rozwiedziony: (Data_slubu:
String[10];
Data_rozw: String[10]);
Pole wariantowe musi być ostatnim polem rekordu.
Typ obiektowy
Typ obiektowy opisuje złożoną
strukturę danych. Składa się ona z pól, podobnie jak struktura rekordu, oraz
tzw. metod, czyli operacji wykonywanych na objecie. Definicja obiektu
rozpoczyna się słowem OBJECT, i kończy END;. Ma następującą budowę:
OBJECT (dziedziczność)
Pole: Typ;
Pole: Typ;
..
..
Metoda;
Metoda;
END;
Typ zbiorowy
Typ ten określa
zbiór potęgowy, którego elementy są typu porządkowego. Przez zbiór potęgowy
należy rozumieć zbiór wszystkich możliwych podzbiorów wartości typu
porządkowego, włączając w to zbiór pusty. Definicja tego typu jest następująca:
Typ_zbiorowy = SET OF Typ;
np.:
TYPE
Litery = SET OF 'a'..'z';
Cyfry=SET OF '0'..'9';
Teraz zmienne typu Cyfry mogą przyjmować tylko wartości od
'0' do '9'.
Na zbiorach można wykonywać następujące operacje:
·
+ - dodawanie
·
- - odejmowanie
·
* - mnożenie (iloczyn zbiorów)
·
IN - sprawdzanie przynależności
·
= - sprawdzanie równości
·
<=,>= - sprawdzanie relacji inkluzji zbiorów
Typ plikowy
Typ ten określa zbiór danych sekwencyjnych o
zmiennej liczbie elementów tego samego typu. Elementy składowe nie mogą być
typu plikowego oraz typu, który zawiera w sobie deklaracje typu plikowego.
Ogólna postać definicji typu plikowego jest następująca:
Plik_1: FILE OF Typ_podstawowy;
Plik_2: FILE;
Plik_3: Text;
np.:
VAR
Plik: FILE OF Byte;
STAŁE
I ZMIENNE
Stałe
Stała jest identyfikatorem, któremu
przyporządkowano podczas inicjacji wartość, której w programie nie wolno
zmieniać. wszystkie stałe deklaruje się po słowie CONST. np.:
CONST Litera_A:='A';
Zmienne
Są to identyfikatory określające jakąś
wartość, która może być w programie zmieniana. Zmienna zajmuje pewną ilość
pamięci, dlatego każda zmienna jest określonego typu. Zmienne definiuje się po
słowie kluczowym VAR, np:
VAR a: Integer;
W języku Turbo Pascal istnieją również tzw. zmienne
absolutne, które określają umiejscowienie zmiennej w pamięci. Ogólny sposób
definiowania takich zmiennych jest następujący:
VAR Nazwa: Typ ABSOLUTE segment:offset;
np.:
VAR CrtMode: Byte ABSOLUTE
$0049:$0049;
OPERATORY
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 |
PRIORYTET |
@, 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 ARG. |
TYP WYN. |
+ |
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 ARG. |
TYP WYN. |
NOT |
negacja |
całkowity |
całkowity |
AND |
iloczyn |
całkowity |
całkowity |
OR |
suma |
całkowity |
całkowity |
Operatory logiczne
OPERATOR |
ZNACZENIE |
TYP ARG. |
TYP WYN. |
NOT |
negacja |
logiczny |
logiczny |
AND |
iloczyn |
logiczny |
logiczny |
OR |
suma |
logiczny |
logiczny |
XOR |
suma modulo 2 |
logiczny |
logiczny |
Operatory relacyjne
OPERATOR |
ZNACZENIE |
TYP ARG. |
TYP WYN. |
= |
równość |
typy proste wskaźnikowe, zbiorowe łańcuchowe |
logiczny |
<> |
nierówność |
typy proste wskaźnikowe, zbiorowe łańcuchowe |
logiczny |
< |
mniejszość |
typy proste łańcuchowe PChar |
logiczny |
> |
większość |
typy proste łańcuchowe PChar |
logiczny |
<= |
mniejszy-równy |
typy proste łańcuchowe PChar |
logiczny |
>= |
większy-równy |
typy proste łańcuchowe PChar |
logiczny |
<= |
jest podzbiorem |
zgodne zbiorowe |
logiczny |
=> |
jest nadzbiorem |
zgodne zbiorowe |
logiczny |
IN |
zawarty w |
|
logiczny |
Instrukcja warunkowa
Instrukcję tą stosuje się wtedy, kiedy chcemy
wykonać jakąś operację, jeśli zostaje spełniony jakiś warunek. Język Turbo
Pascal daje nam do dyspozycji dwa rodzaje instrukcji warunkowych:
·
Instrukcja IF
·
Instrukcja CASE
Instrukcja IF
Składnia jej jest następująca:
IF warunek THEN instrukcja1;
lub
IF warunek THEN Instrukcja1 ELSE Instrukcja2;
Przy pierwszym zapisie komenda znajdująca się po słowie
THEN zostanie wykonana tylko wtedy, gdy "warunek" jest spełniony, np.
X:=10;
Y:=5;
IF X>Y THEN Writeln('X jest większy od Y');
IF X<Y THEN Writeln('Y jest większy od X');
IF X=Y THEN Writeln('X jest równe Y');
Powyższy program wyświetla jeden z napisów znajdujących się
po słowie THEN, w tym wypadku napis pierwszy, czyli "X jest większy od
Y".
W drugim zapisie, "instrukcja1" zostanie wykonana
tylko wtedy, gdy "warunek" jest spełniony, w przeciwnym wypadku
zostanie wykonana "instrukcja2". Instrukcja1 nie może być zakończona
średnikiem, np.:
X:=5;
Y:=10;
IF X>Y THEN Writeln('X jest większe od Y')
ELSE Writeln('Y jest
większe niż X');
Jeśli chcemy wykonać więcej niż jedną instrukcję w
przypadku, gdy zostanie spełniony warunek lub nie, to możemy zastosować
instrukcję strukturalną używając BEGIN i END. Gdy używamy instrukcji
strukturalnej i słowa kluczowego ELSE, należy pamiętać, że zamknięcie tej
instrukcji, czyli END stawiamy bez średnika.
np.:
X:=5;
Y:=10;
IF X>5 THEN
BEGIN
Writeln('X jest większe
od Y');
...
END ELSE
BEGIN
Writeln('Y jest większe
od X');
...
END;
Przy pisaniu warunków można używać następujących operatorów
logicznych:
·
AND - "i"
·
OR - "lub"
·
NOT - "nie"
Kiedy warunek składa się z kilku podwarunków, to każdy taki
podwarunek musi znajdować się w nawiasach np.:
IF (Imie='Jan') AND (Nazwisko="Kowalski') THEN ...
IF (Imie="Stanislaw') OR (Imie='Piotr') THEN ...
Do określania warunków służą następujące operatory:
·
= "równe"
·
< "mniejsze"
·
> "większe"
·
<= "mniejsze bądź równe"
·
>= "większe bądź równe"
·
<>"różne"
·
·
Instrukcja CASE
Instrukcja ta posiada następującą składnię:
CASE wyrażenie OF
wartość1: Instrukcja1;
wartość2: Instrukcja2;
...
END;
lub
CASE wyrażenie OF
wartość1: Intrsukcja1;
wartość2 : Instrukcja2;
...
ELSE Instrukcja3
End;
Działanie jej jest następujące: zostanie obliczone
[wyrażenie] i jeśli jest ono równe [wartość1] zostanie wykonana [Instrukcja1],
Jeśli wartość wyrażenia jest równe [wartość2], zostanie wykonana [instrukcja2]
itd., Jeśli wynikiem wyrażenia nie jest żaden z podanych poniżej wartości zostanie
wykonana instrukcja znajdująca się po opcjonalnym parametrze ELSE.
Instrukcja iteracyjna
Instrukcje iteracyjne służą do
wielokrotnego wykonania pewnej grupy lub jednej instrukcji. W Turbo Pascalu są
następujące instrukcje iteracyjne:
Instrukcja FOR
Powoduje ona wykonanie jakiejś operacji określoną liczbę
razy. Ma ona następującą składnię:
FOR licznik:=poczatek TO koniec DO Instrukcja;
lub
FOR licznik:=koniec DOWNTO początek DO Instrukcja;
Oczywiście zamiast jednej instrukcji można wpisać szereg
poleceń między BEGIN i END;.
[Licznik] - jest to zmienna sterująca pracą. W zapisie
pierwszym nadajemy jej początkową wartość [początek]. Następnie [Instrukcja]
jest wykonywana tyle razy, aż [licznik] będzie równy [koniec]. Za każdą
"pętlą" licznik zostaje zwiększony o jeden. Jeśli mamy zapis drugi to
[licznik] ma początkową wartość [koniec], i [instrukcja] jest tak długo
wykonywana, aż [licznik] będzie równy [początek]. Przy każdej pętli licznik
jest zmniejszany o jeden. Przykładowy program wyświetlający 10 liczb może
wyglądać tak:
VAR Integer; {licznik}
BEGIN
For i:=1 to 10 DO Writeln(i); {napisz liczbę i}
END.
Instrukcja REPEAT
Instrukcja ta ma następującą składnię:
REPEAT
Instrukcja;
...
Instrukcja;
UNTIL warunek;
Instrukcję między słowami REPEAT i UNTIL są tak długo
wykonywane, aż wartość [warunek] zostanie spełniony. W warunku tym można używać
instrukcji matematycznych. W module CRT znajduje się funkcja KEYPRESSED, która
jest typu BOOLEAN i przyjmuje wartość TRUE, jeśli zostanie wciśnięty jakiś
klawisz na klawiaturze. Jeśli mamy więc program, który ma działać tak długo, aż
zostanie wciśnięty dowolny klawisz na klawiaturze napiszemy:
USES CRT;
BEGIN
Writeln('Coś tam');
REPEAT UNTIL KeyPressed;
END.
Instrukcja WHILE
Posiada ona następującą składnię:
WHILE wyrażenie DO instrukcja;
[Instrukcja] jest tak długo wykonywana, aż wartość wyrażenia
jest prawdziwa. Ten sam program co powyżej, z użyciem tej instrukcji wyglądałby
tak:
USES CRT;
BEGIN
Writeln('Coś tam');
WHILE NOT KeyPressed DO ;
END.
Jeśli klawisz nie został wciśnięty, to funkcja KEYPRESSED
zwraca wartość FALSE. Powyższy program wyświetla napis i czeka, aż zostanie
wciśnięty klawisz. Instrukcja WHILE jest spełniona, gdy KeyPressed ma wartość
FALSE i jeśli jest spełniona to wykonuje instrukcję znajdującą się po słowie
DO, czyli ";". Średnik oznacza instrukcję pustą, więc nie zostaje
wykonane żadne polecenie. Kiedy wciśniemy jakiś klawisz, funkcja KeyPressed
zwróci wartość TRUE, wartość wyrażenia NOT KeyPressed jest FALSE, więc zostaje
zakończone wykonywanie tej instrukcji i wyłączenie programu.
Instrukcja wiążąca
Instrukcja wiążąca ma następującą składnię:
WITH nazwa DO instrukcja;
Zamiast [instrukcji] można wstawić również blok instrukcji.
Pozwala ona na odwoływanie się do pól rekordu lub obiektu bez konieczności
stosowania kwantyfikatora, np.:
Mamy następujący typ:
TYPE Dane = RECORD
Imie: String;
Nazwisko: String;
Wiek: Byte;
END;
VAR osoba: Dane;
Odwołujemy się do poszczególnych pól rekordu w następujący
sposób:
WITH osoba DO
BEGIN
Imie:='Stanislaw';
Nazwisko:='Zawalny';
Wiek:=49;
END;
Instrukcja koduosiada następującą składnię:
INLINE (lista_elementów);
Wszystkie elementy[listy_elementów] oddzielone są od siebie
ukośnikami i mogą być:
·
stałymi określającymi wartości liczbowe
·
identyfikatorami zmiennych
·
identyfikatorami zmiennych ze stałą poprzedzoną + lub -
·
operatorami rozmiaru kody <i>
Przykładowe użycie tej procedury:
INLINE($EA/$F0/$FF/$00/$F0); {spowoduje zresetowanie się
komputera}
Instrukcja asemblerowa
Składnia jej jest następująca:
ASM
Instrukcja;
...
Instrukcja;
END;
END.
Słowo kluczowe UNIT oznacza nagłówek modułu. W
przeciwieństwie do PROGRAM nazwa ta musi wystąpić, ponieważ za jej pomocą
będziemy odwoływać się do danego modułu. Nazwa pliku TPU powinna mieć również
nazwę taką jak UNIT.
Część modułu po słowie kluczowym INTERFACE służy do deklaracji typów, stałych,
zmiennych oraz nagłówków procedur i funkcji. Będą wszystkie one dostępne w
programie, w którym deklarujemy dany moduł, natomiast część modułu po słowie
IMPLEMENTATION zawiera deklaracje stałych, zmiennych i typów, które będą
dostępne tylko w obrębie modułu. Znajdują tutaj się również wszystkie procedury
i funkcje. Muszą być wszystkie te, których nagłówki zadeklarowaliśmy w części
INTERFACE, ale mogą być również inne, które będą używane podczas wykonywania
procedur zadeklarowanych.
Przykładowy moduł zawierający jedną procedurę PiszXY może
wyglądać tak:
UNIT Modul;
INTERFACE;
USES CRT;
PROCEDURE PiszXY(X,Y: Word; Napis: STRING);
IMPLEMENTATION
PROCEDURE PiszXY(X,Y :
Word; Napis: STRING);
BEGIN
GotoXY(X,Y);
Write(Napis):
END;
END.
DYNAMIKA
Każda zmienna zadeklarowana w bloku głównym programu po
słowie VAR jest zmienną statyczną. Dla nich wszystkich kompilator podczas
swojej pracy rezerwuje pamięć w segmencie danych programu. Jednak dobrze wiemy,
że każdy segment ma 64KB, więc tym samym suma wszystkich zmiennych statycznych
deklarowanych w programie nie może przekroczyć tej granicy. Nie można więc
stworzyć np. tablicy o rozmiarze 5000 typu WORD. Próba taka, zostanie
zakończona stosowanym komunikatem ze strony kompilatora.
Nie można także w trakcie działania programu zmieniać np. wielkości
zadeklarowanej tablicy, gdyż dla niej miejsce zostało przydzielone podczas
kompilacji. Jest to bardzo poważny minus, bo albo: mamy za mało pamięci na
zapamiętanie pewnych danych, albo marnujemy pamięć tworząc tablicę, która
pomieściłaby wszystkie nasze dane w najgorszym wypadku.
Każda zmienna deklarowana w obrębie tylko jednej procedury lub funkcji jest już
zmienną dynamiczną, jednak my na nią i tak nie mamy wpływu. Zmienne lokalne są
tworzone podczas wchodzenia do danej funkcji (procedury) i usuwane podczas
wychodzenia. Dzieje się to automatycznie, gdyż zmienne lokalne zapamiętywane są
na stosie. Wielkość stosu określa się pierwszym parametrem dyrektywy $M, jednak
ponieważ jest to również jeden segment nie może on przekroczyć 64KB
(standardowo stos jest ustawiony na 16384 bajty). Dlatego nie można np. tworzyć
skompilowanych, pełnych wielu zmiennych lokalnych, procedur rekurencyjnych, bo
szybko stos się zapełni i praca programu zostanie wstrzymana.
Jak więc obsłużyć pamięć, którą mamy w naszym komputerze? Właśnie za pomocą
zmiennych dynamicznych. Dzięki nim, mamy dostęp do całej pamięci
konwencjonalnej, ok. 640KB., Jeśli i to dla nas za mało, to trzeba nauczyć się
obsługiwać pamięć XMS lub EMS.
Zmienne dynamiczne tworzone są na "stercie". Jej wielkość minimalną i
maksymalną podajemy jako dwa olejne parametry dyrektywy $M.
Do sprawdzenia ilości wolnej pamięci sterty służy funkcja MEMAVAIL. Zwraca ona
w bajtach ilość aktualnie dostępnej pamięci. My jednak przydzielamy pamięć
pewnymi blokami (np. rekord, czy zmienna). Każdy blok ma swoją określoną
wielkość. Za pomocą funkcji MAXAVAIL dowiemy się, jaki jest w tej chwili
dostępny (w bajtach) największy wolny blok na stercie. Bo co z tego, że mamy
100KB wolnej pamięci, jak jest ona tak "pozaśmiecana", że największy
wolny blok ma 50KB, a nasza zmienna, której przydzielamy pamięć ma 60KB? Nie
mam wówczas możliwości tego wykonania.
Zmienne dynamiczne są tworzone programowo i usuwane również programowo. Oznacza
to, że programista w dowolnej chwili może przydzielić pamięć na jakieś danej na
stercie, a później je usunąć.
Ze zmiennymi dynamicznymi związany jest typ wskaźnikowy i zanim przejdziemy
dalej, musimy go dokładnie zrozumieć.
Zmienne wskaźnikowe i wskazywane
W Pascalu mamy do dyspozycji
tzw. typ wskaźnikowy. Umożliwia on organizacje dynamicznych struktur danych.
Każda zmienna wskazująca (wskaźnikowa) jest zmienną statyczną. Zajmuje ona 4
bajty pamięci. Zawiera ona adres do zmiennej wskazywanej, tzn. zmiennej dynamicznej.
Zmienne wskaźnikowe deklarujemy w następujący sposób:
TYPE Nazwa_typu_wsk = ^Nazwa_typu;
Teraz zmienne typu NAZWA_TYPU_WSK mogą zawierać adres
wskazujący na zmienną dynamiczną, która jest typu NAZWA_TYPU, np.:
TYPE TByte = ^BYTE;
Zmienne typu TByte są wskaźnikami do zmiennych
dynamicznych, które są typu BYTE.Nie wykorzystuje się jednak (lub bardzo
rzadko) zmiennych wskaźnikowych, które wskazują na zmienne typu prostego.
Wskaźniki zazwyczaj robi się do rekordów lub tablic, np.:
TYPE
TDANE = ^DANE;
DANE = RECORD
Imie: String[15];
Nazwisko: String[30];
END;
Teraz każda zmienna typu TDANE jest wskaźnikiem do
zmiennych dynamicznych typu DANE, czyli rekordów zawierających pola IMIE i
NAZWISKO.
Mając już zdefiniowany typ wskaźnikowy, możemy stworzyć
zmienną wskaźnikową, np.:
VAR ZDANE: TDANE;
Teraz zmienna ZDANE jest zmienną wskaźnikową. Zajmuje stałą
ilość pamięci równą 4 bajtów i potrafi wskazywać na zmienne dynamiczne o
strukturze DANE. Potrafi!!!!, a nie wskazuje!!! Zmienna dynamiczna nie została
jeszcze stworzona, dlatego adres na jaki wskazuje ZDANE trzeba ustawić na NIL,
czyli:
BEGIN
ZDANE:=NIL
...
Zbliżony do typu wskaźnikowego jest predefiniowany typ
adresowy POINTER.
VAR
ADR1: TDANE;
ADR2: POINTER
...
BEGIN
ADR1:=ADR2;
ADR2:=ADR1;
...
Przydzielanie pamięci zmiennym dynamicznym
Mając już określony typ np. TDANE i stworzoną
zmienną tego typu ZDANE, możemy utworzyć zmienną dynamiczną o strukturze DANE,
którą będzie wskazywała ZDANE. Robimy to w następujący sposób:
NEW(ZDANE);
Dopiero teraz, gdzieś w pamięci zostanie utworzona zmienna
dynamiczna, na którą wskazuje zmienna wskaźnikowa ZDANE.
Utworzenie zmiennej dynamicznej (jak wyżej) oprócz
stworzenia zmiennej wiąże się jeszcze ze stworzeniem do niej wskaźnika, tzn.
jej adres jest zapamiętywany w ZDANE. Możemy więc teraz się do niej odwoływać,
np.:
Writeln(ZDANE^.Nazwisko);
ZDANE^.Imie:='Karol';
Jeśli używamy znaczka "^", tzn. że odwołujemy się
nie do wskaźnika ZDANE, a do zmiennej, którą on wskazuje.
Na koniec pracy ze zmienną dynamiczną, trzeba ją usunąć, a
tym samym zwolnić pamięć jej przydzieloną. Piszemy wówczas:
DISPOSE(ZDANE);
Zmienne dynamiczne można również tworzyć za pomocą
procedury GETMEM. Jako jej parametry podajemy wówczas: zmienną wskaźnikową
(typu POINTER) i ilość bajtów pamięci jaka ma zostać przydzielona. Taką zmienną
można usunąć procedurą FREEMEM. Tej z kolei jako parametr podajemy utworzoną
wcześniej zmienną wskaźnikową.
Mając zadeklarowane dwie zmienne wskaźnikowe, np:
VAR A,B: TDANE;
i utworzone dwie zmienne dynamiczne, na które one wskazują:
NEW(A);
NEW(B):
Można zrobić np. tak:
A:=B;
Teraz zmienna A wskazuje na to samo, co zmienna B.
Straciliśmy więc dostęp do tego, co wcześniej wskazywała A. Nie możemy również
zwolnić przydzieloną jej wcześniej pamięć.
Można napisać również tak:
A^:=B^;
Teraz nastąpi przepisanie zmiennej wskazywanej B do
zmiennej, na którą wskazuje A. Nie stracimy natomiast dostępu do żadnej ze
zmiennych.
Zmienne wskaźnikowe i programowanie
dynamiczne jest wykorzystywane do tworzenia dynamicznych struktur danych, czyli:
list, kolejek, stosów, grafów, etc. Różnią się one tym, że dla każdego elementu
przydzielana jest oddzielnie pamięć. Dzięki temu można np. stworzyć bardzo dużo
rekordów (w zależności ile mamy wolnej pamięci), więcej niż 64KB. Można też
tworzyć je dynamicznie, tzn. jedne tworzyć, a inne usuwać, dzięki czemu nie
marnujemy, tak jak w tablicach statycznych, pamięci na puste rekordy.
DYREKTYWY KOMPILATORA
Dyrektywy służą do określania pracy
kompilatora. Za pomocą nich "mówimy" kompilatorowi, jak ma wykonać
kompilację programu, lub jego części, np. czy używać koprocesora
arytmetycznego, czy nie. W języku Turbo Pascal mamy do dyspozycji trzy typy
dyrektyw:
·
dyrektywy przełącznikowe
·
dyrektywy parametryczne
·
dyrektywy warunkowe
Dyrektywy podajemy w nawiasach klamrowych , po znaku '$'.
jeśli wypisujemy więcej niż jedną dyrektywę możemy je oddzielać przecinkiem,
nie pisząc za każdym razem znaku '$'. W dyrektywach przełącznikowych używamy
również dwóch dodatkowych znaków: "+" oznaczający włączenie danej
dyrektywy i "-" wyłączenie.
{$N+}
{$E-, N+}
Dyrektywy przełącznikowe
Dzielą się na globalne - obejmujące cały
program i lokalne - odnoszące się do części programu.
·
$A - Dyrektywa ta powoduje zapamiętanie danych w pamięci
komputera przez ich wyrównanie do granicy słowa maszynowego. Jest ona dyrektywą
globalną i standardowo włączoną. Powoduje przyspieszenie dostępu do zmiennych
zapamiętanych w pamięci, jednak na procesorach 8088 i wyższych nie przynosi
pożądanych rezultatów.
·
$B - Jest dyrektywą lokalną. Powoduje optymalizowanie
generowanego kodu dla wyrażeń logicznych. Włączenie dyrektywy powoduje, że dane
wyrażenie logiczne jest analizowane do końca, natomiast wyłączenie tej
dyrektywy powoduje, że wyrażenie analizowane jest aż do uzyskania wyniku
(często przed końcem wyliczania pozostałych operacji). Dyrektywa jest
standardowo wyłączona.
·
$D - Powoduje umieszczenie w generowanych plikach (EXE lub
TPU) informacji o możliwie występujących błędach. Jest to dyrektywa globalna i
standardowa włączona.
·
$E - Kolejna dyrektywa globalna. Jej włączenie powoduje, że
w przypadku nie wykrycia koprocesora arytmetycznego zostanie dołączona
biblioteka, która będzie go emulować. Dyrektywa jest standardowo włączona.
·
$F - Określa rodzaj odwołań do procedur i funkcji. Jeśli
jest włączona, wszystkie odwołania do procedur i funkcji są delay (FAR),
natomiast, gdy jest wyłączona, odwołanie są bilks (NEAR). Dyrektywa jest
lokalne i standardowo wyłączona.
·
$G - Dyrektywa globalna. Jej włączenie powoduje generowanie
kodu dla pracy w trybie chronionym, natomiast wyłączenie dla pracy w trybie
rzeczywisty. Program wygenerowany z opcją włączoną nie będzie mógł być
uruchomiony na komputerach starszych niż 80286.
·
$I - Standardowo włączona, lokalna dyrektywa, która
powoduje generowanie kodu, kontrolującego operacje wejścia/wyjścia. Jeśli jest
wyłączona, kod błędu przekazany jest za pomocą funkcji IOResult.
·
$L - Powoduje automatyczne generowanie kodu zawierającego
informacje o typach wszystkich zmiennych i stałych. Jest to standardowo
włączona globalna dyrektywa.
·
$N - Powoduje, że program będzie wykorzystywał koprocesor
arytmetyczny do obliczeń na liczbach zmienno przecinkowych, we wszystkich
typach rzeczywistych, w przeciwnym wypadku zostanie użyta biblioteka, która
będzie go emulowała. Dyrektywa jest standardowo wyłączona. Jest dyrektywą
globalną.
·
$O - Dyrektywa jest włączana, gdy generowany kod ma być
nakładką. Standardowo jest to wyłączona, globalna dyrektywa.
·
$P - Powoduje, że użycie słowa STRING będzie oznaczało tzw.
łańcuch otwarty, w przeciwnym wypadku będzie on miał długość 256 bajtów.
Standardowo jest ona wyłączona. Dyrektywa globalna.
·
$Q - Powoduje włączenie kontroli przepełnienia dla
generowanego kodu. Dyrektywa lokalna, standardowo wyłączona.
·
$R - dyrektywa lokalna, standardowo wyłączona, powoduje, że
wygenerowany kod będzie podlegał kontroli zgodności indeksów tablic i łańcuchów
z wartościami zadeklarowanymi.
·
$S - Powoduje automatyczne generowanie kodu, który podczas
wywoływania procedury lub funkcji kontroluje dostępną ilość wolnej pamięci.
Dyrektywa lokalna, standardowo włączona.
·
$T - Określa rodzaj wskaźnika generowanego przez operator
@. Jeśli jest wyłączona znak @ oznacza typ Pointer, w przeciwnym wypadku jest
wskaźnik na zmienną określonego typu (^TYP). Lokalna, standardowo włączona
dyrektywa.
·
$V - Dyrektywa globalna, standardowo włączona, powoduje
ustawienie zgodności pomiędzy typem PChar i tablicami znaków zaczynających się
od indeksu zerowego.
·
$Y - Dyrektywa umożliwia wyświetlanie symboli i odwołań do
nich za pomocą okienka Object Browser. Standardowo włączona, globalna.
Dyrektywy
parametryczne
·
$I nazwa_pliku - powoduje ona dołączenie do kompilowanego
programu pliku określonego nazwą [nazwa_pliku]. W nazwie można używać ścieżki
dostępu. Dyrektywa ta ma zasięg lokalny.
·
$L nazwa_pliku - powoduje ona dołączenie do kompilowanego
programu pliku już skompilowanego z rozszerzeniem OBJ. W nazwie programu nie
trzeba podawać rozszerzenia OBJ. Dyrektywa posiada zasięg lokalny
·
$M stos, min_sterty, max_stery - Dzięki tej dyrektywie możemy
określić rozmiar pamięci przeznaczonej dla segmentu stosu oraz sterty. Parametr
[stos] określa rozmiar segmentu stosu w bajtach. Maksymalna jego wartość wynosi
65536 bajtów. Parametr [min_sterty] określa minimalny rozmiar sterty w bajtach.
Standardowo wynosi on 0. Może przyjąć maksymalną wartość równą 655360. Ostatni
parametr [max_sterty] określa maksymalny rozmiar sterty w bajtach, który
standardowo wynosi 655360. Nie może on być mniejszy od [min_sterty]
·
$O nazwa_modułu - dyrektywa określa moduł o podanej nazwie
jako nakładkę. Dyrektywa ta musi wystąpić bezpośrednio po klauzuli USES.
Dyrektywy
warunkowe
Pozwalają one na warunkową pracę kompilatora.
·
$DEFINE nazwa_symbolu - Dyrektywa służy do definiowania
nazw symbolu, który będzie używany przez pozostałe dyrektywy warunkowe. Symbole
te odpowiadają zmiennym typu Boolean. Dyrektywa $DEFINE nadaje im wartość TRUE.
Język Turbo Pascal definiuje standardowo następujące symbole:
·
VER70 - inne wersje języka mają symbole różniące się
numerem
·
MSDOS - gdy systemem operacyjnym jest MS-DOS lub MC-DOS
·
CPU86 - gdy procesor należy do rodziny 80x86
·
CPU87 - gdy wykryty zostanie koprocesor arytmetyczny z
rodziny 80x87
·
$UNDEF nazwa_symbolu - dyrektywa jest przeciwieństwem
dyrektywy $DEFINE i określa wartość symbolu na FALSE
Pozostałe dyrektywy warunkowe posiadają zdefiniowane
symbole. Korzysta się z nich w następujących konstrukcjach:
$IFxxx nazwa_symbolu
...
$ENDIF
oraz
$IFxxx nazwa_symbolu
....
ELSE
....
$ENDIF
Jako $IFxxx wpisujemy:
·
$IFDEF - wykonuje program gdy nazwa symbolu została
zdefiniowana
·
$IFNDEF - wykonuje program gdy nazwa symbolu nie została
zdefiniowana
·
$IFOPT przełącznik - wykonuje program gdy stan przełącznika
w tej dyrektywie odpowiada aktualnie ustawionej dyrektywie
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 |
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 |
- |