1
Program w Turbo Pascalu
nagłówek programu
begin
end.
program p02;
begin
end.
program p03;
begin
writeln(’Cześć’);
writeln(’Uczymy się programowania w Pascalu’)
end.
end.
begin
ciąg instrukcji
ciąg instrukcji
Syntaks - zasady budowania poprawnych konstrukcji języka
Semantyka - znaczenie instrukcji zapisanych w języku
Diagramy syntaktyczne - graficzne przedstawienie reguł języka
2
ELEMENTY PROGRAMU posiadają
- identyfikator czyli nazwę,
- typ czyli zakres wszystkich wartości, które mogą przyjmować,
- wartość jedną spośród wszystkich dostępnych
IDENTYFIKATOR
- ciąg znaków alfanumerycznych rozpoczynający się od litery bądź znaku podkreślenia,
- małe i duże litery nie są rozróżniane,
- dowolna liczba znaków (kompilator interpretuje jedynie pierwsze 63 znaki),
- bez spacji,
- różne od słów kluczowych.
_alfa
Warszawa-22
godz
ten dzień
20lat
q22222345
TYPY
proste
strukturalne
wskaźnikowe
całkowity
tablicowy
wyliczeniowy
rekordowy
logiczny
zbiorowy
okrojony
plikowy
znakowy
obiektowy
rzeczywisty
3
Typy całkowite
Typ danych
Zakres wartości
Miejsce w pamięci
byte
0..255
8 bitów
shortint
-128..127
8 bitów
word
0..65535
16 bitów
integer
-32768..32767
16 bitów
longint
-2147483648..2147483647
32 bity
Typ znakowy
char - znaki tabeli kodowej ASCII;
umieszczane w apostrofach: ’A’, ’a’, ’ ’,’:’;
1 bajt = 8 bitów;
Typy rzeczywiste
Typ danych
Zakres wartości
Dokładność
real
2.9*10
-39
do 1.7*10
38
11-12 miejsc
single
1.5*10
-45
do 3.4*10
38
7-8 miejsc
double
5.0*10
-324
do 1.7*10
308
15-16 miejsc
extended
3.4*10
-4932
do 1.1*10
4932
19-20 miejsc
comp
-9.2*10
-18
do 9.2*10
18
18.0
127.54
0.67
4.
1.7435E-12
7E20
3.56789E4
4
Program w Turbo Pascalu
nagłówek programu
end.
begin
ciąg instrukcji
ciąg instrukcji
lista deklaracji
Każdy obiekt użyty w programie musi być zadeklarowany!
Deklaracja - przypisanie identyfikatora do obiektu
Zmienna - pozycja w pamięci opisana identyfikatorem, w której
przechowywana jest wartość danej mogącej ulec zmianie
12345
wartość
(integer)
typ
zmienna
alfa
identyfikator
Deklaracja jednej lub kilku zmiennych
identyfikator
,
:
typ
;
zm1,zm2,zm3:integer;
cena,koszt:real;
5
identyfikator
=
wartość
;
wartość początkowa
;
=
Stała -
zawartość pamięci której nie można zmieniać w trakcie wykonywania programu,
a do której odnosimy się poprzez identyfikator
Definicja stałej
pi = 3.14159;
max = 20;
spacja = ’ ’;
Definicja stałej typowej
identyfikator
:
typ
i : integer=1;
znak :char=’t’;
Stała typowa -
zmienna z wartością przypisaną w momencie deklaracji
Lista definicji stałych
var
definicja stałej
definicja stałej typowej
Lista deklaracji zmiennych
deklaracja jednej lub kilku zmiennych
const
6
PRZYSTĘPUJEMY DO DZIAŁANIA...
end.
begin
ciąg instrukcji
Część wykonawcza programu:
instrukcja
Ciąg instrukcji
;
INSTRUKCJA
prosta
strukturalna
przypisania złożona
procedury warunkowa
skoku iteracyjna
pusta wiążąca
INLINE
Instrukcja przypisania
identyfikator zmiennej
identyfikator funkcji
:=
wyrażenie
cena:=234;
litera:=’c’;
liczba:=2.67;
7
WYRAŻENIE jest zbudowane ze stałych, zmiennych i operatorów i oznacza wartość pewnego typu
OPERATORY ARYTMETYCZNE
+ (jednoargumentowy) identyczność
argumenty całkowite bądź
rzeczywiste
- (jednoargumentowy) zmiana znaku
+
dodawanie
wynik całkowity jeśli oba argumenty
całkowite
-
odejmowanie
w przeciwnym przypadku wynik
rzeczywisty
*
mnożenie
/
dzielenie
argumenty całkowite bądź rzeczywiste; wynik
rzeczywisty
DIV
dzielenie całkowite bez reszty
MOD
reszta z dzielenia całkowitego
zarówno argumenty jak i
wynik całkowite
ZGODNOŚĆ TYPÓW -
wartość wyrażenia występującego w instrukcji przypisania powinna być takiego
samego typu jak zmienna, do której następuje przypisanie
WARTOŚCIOWANIE WYRAŻEŃ - wyrażenia obliczane są od strony lewej do prawej zachowując
priorytety operatorów w kolejności: operatory multiplikatywne
a następnie addytywne; zmiana tych priorytetów może nastąpić
w wyniku użycia nawiasów.
3+6 x 2*x+6 i mod 7 (4 div k) / 7 (x+y+z) * 3
8
Dane wejściowe
Standardowe urządzenia wejścia : klawiatura
Bufor klawiatury -pamięć rejestrująca każdy wciśnięty klawisz lub ich kombinacje. Procedury
korzystające z tego bufora:
Read,
Readln
funkcja
ReadKey
Read ( lista argumentów);
Readln (lista argumentów);
lista argumentów - ciąg zmiennych oddzielonych przecinkami
read (a,b);
readln (c);
Readln - można wykorzystać do zatrzymania pracy programu do chwili naciśnięcia klawisza
ENTER;
ReadKey -
powoduje wczytanie jednego znaku z bufora klawiatury.
9
Formatowanie wyjścia
Standardowe urządzenia wyjścia : monitor
Write (lista argumentów);
Writeln(lista argumentów);
lista argumentów - ciąg stałych, zmiennych lub wyrażeń oddzielonych przecinkami
write(’ Ala ma ’, i:2,’ koty ’);
writeln(’ Wartość zmiennej x wynosi ’,x);
Writeln - powoduje przejście do nowej linii;
Wartości wyrażeń typu Char, String, Boolean, całkowitego można formatować korzystając z
parametru pole
(wyrażenie całkowite nieujemne):
write( i:3, ’Ala’:10);
Do formatowania wartości wyrażeń rzeczywistych oprócz parametru polewykorzystuje się
parametr miejsca_dziesiętne:
dla x=5.13
write(x:7:1)
| -5.1
write(x:7:3)
| -5.13
write(x:7:4)
| -5.130
write(x:7:7)
|-5.130000
write(x:7:8)
|-5.1300000
10
Poza minimalizm...dodawanie komentarzy do programu
Komentarz to ignorowana przez kompilator część programu zamknięta
w nawiasach {} lub (* *)
- nie mieszamy dwóch typów komentarzy,
- nie umieszczamy znaku $ jako pierwszego znaku komentarza,
- nie zagnieżdżamy komentarzy tego samego rodzaju.
(*...}
niepoprawnie
{... *)
niepoprawnie
(*$...*)
niepoprawnie
(*...(*...*)...*)
niepoprawnie
(*...*)...*)
niepoprawnie
{...{...}...}
niepoprawnie
{......}...}
niepoprawnie
{...{... ...}
poprawnie
(*...(*... ...*)
poprawnie
(*... {... ... } ...*)
poprawnie
{...(*... ... *) ...}
poprawnie
instrukcja
;
Blok czyli instrukcja złożona
begin
end
Dyrektywy kompilatora:
(*$I+}
{$I+*)
{(*$I+*) (*...*)}
(* {$I+} {...} *)
begin
11
Podprogram po raz pierwszy - co to jest funkcja
Podprogram -
wyodrębniona część programu, stanowiąca całość (tzw.blok), posiadająca nazwę i ustalony sposób wymiany informacji
z pozostałymi częściami programu.
function
identyfikator
lista parametrów formalnych
:
typ wyniku
Deklaracja funkcji
nagłówek funkcji
;
ciało funkcji
;
Nagłówek funkcji
Ciało funkcji
end
begin
ciąg instrukcji
lista deklaracji
identyfikator
:=
wyrażenie
12
Parametry formalne i aktualne
Lista parametrów formalnych
(
deklaracja jednej lub kilku zmiennych
var
;
)
function max3 (a,b,c:real):real;
function test (a:integer; zn:char):real;
Lista parametrów formalnych pozwala w sposób jawny przekazywać dane do funkcji bądź procedury.
W wywołaniu funkcji listę parametrów formalnych zastępuje lista parametrów aktualnych
Parametr aktualny musi być takiego samego typu jak odpowiadający mu na liście parametr formalny.
Parametry aktualne w wywołaniu funkcji oddzielone są przecinkami.
-Funkcja zawsze zwraca jedną wartość określonego typu;
-Każda funkcja musi być zadeklarowana w części deklaracji w programie;
-Funkcja może być wielokrotnie wywoływana w części wykonawczej;
-Funkcje używane są w wyrażeniach w taki sam sposób jak zmienne i stałe;
-Lista parametrów jest sposobem na komunikowanie się z programem;
13
Standardowe funkcje arytmetyczne
Postać funkcji
Działanie
Typ wyniku
abs(x)
arctan(x)
cos(x)
exp(x)
frac(x)
int(x)
wartość bezwględna z x
arctg x
cosinus x
e do potęgi
część ułamkowa x
część całkowita x
rzeczywisty lub
całkowity
rzeczywisty
rzeczywisty
rzeczywisty
rzeczywisty
rzeczywisty!!
ln(x)
pi
random
logarytm naturalny z x
liczba pi = 3.141593...
liczba losowa z <0,1)
rzeczywisty
stała rzeczywista
rzeczywisty
random(n)
round(x)
sin(x)
liczba losowa z {0,1,...,n-1}
zaokrąglenie do całkowitej
sinus x
całkowity
Longint
rzeczywisty
sqr(x)
sqrt(x)
trunc(x)
x do kwadratu
pierwiastek kwadratowy z x
obcięcie części ułamkowej
rzeczywisty lub
całkowity
rzeczywisty
Longint
program p04;
{ program demonstruje użycie funkcji standardowych oraz funkcji własnej}
var p1,p2,p3:real;
function przeciwprost(a,b:real):real;
{ funkcja oblicza długość przeciwprostokątnej dla zadanych długości
przyprostokątnych a i b }
begin
przeciwprost:=sqrt(sqr(a)+sqr(b))
end;
begin
write(’ Podaj długość pierwszej przyprostokątnej ’);
readln(p1);
write(’ Podaj długość drugiej przyprostokątnej ’);
readln(p2);
write(’ Długość przeciwprostokątnej wynosi ’, przeciwprost(p1,p2):5:3)
end.
14
Podejmowanie decyzji w programie
warun
ek
instrukcjaB
instrukcjaA
FAŁSZ
PRAWDA
WARUNEK - Wyrażenie logiczne przyjmujące wartość
prawdy lub fałszu
Typ logiczny BOOLEAN
(FALSE, TRUE)
Operatory relacji
najniższy priorytet
OPERATOR
ZNACZENIE
=
równe
<>
różne
<
mniejsze
>
większe
<=
mniejsze lub równe
>=
większe lub równe
-12>-100
x<=5
23+4<>50/2
Operatory logiczne
OPERATOR
ZNACZENIE
not
negacja
and
koniunkcja
or
alternatywa
xor
różnica symetryczna
p
q
p and q
p or q
p xor q
false
false
false
false
false
false
true
false
true
true
true
false
false
true
true
true
true
true
true
false
(x<10) and (3=5) (x>0) or ( y>0) (x>0) or (y>0) and not (z>0) (zn=’t’) or (zn=’T’)
15
if
Instrukcje warunkowe
• instrukcja
jeśli
• instrukcja
wyboru
Instrukcja jeśli
then
instrukcja
instrukcja
else
wyrażenie logiczne
instrukcja
if (dzielnik<>0) then wynik:=dzielna/dzielnik
else writeln(’ dzielenie przez zero jest niewykonalne!!!’);
if (dzielnik<>0) then begin
wynik:=dzielna/dzielnik;
writeln(’ dzielenie wykonano’)
end
else writeln(’ dzielenie przez zero jest niewykonalne!!!’);
16
function min3(a,b,c:real):real;
begin
if a<=b then if a<=c then min3:=a
else min3:=c
else if b<=c then min3:=b
else min3:=c
end;
Instrukcje zagnieżdżone
function min3(a,b,c:real):real;
var w1,w2,w3:boolean; {deklaracja zmiennych logicznych}
begin
w1:=(a<=b) and (a<=c);
w2:=(b<=a) and (b<=c);
w3:=(c<=a) and (c<=b);
if w1 then min3:=a;
if w2 then min3:=b;
if w3 then min3:=c
end;
Instrukcje wielowariantowe
program p05;
{ program wczytuje ocenę jako cyfrę i podaje jej słowną interpretację}
var
ocena:byte;
begin
write(’ Podaj ocenę ’);
readln(ocena);
if ocena=6 then writeln(’celujący’)
else if ocena=5 then writeln(’bardzo dobry’)
else if ocena=4 then writeln(’dobry’)
else if ocena=3 then writeln(’dostateczny’)
else if ocena=2 then writeln(’mierny’)
else if ocena=1 then writeln(’niedostateczny’)
else writeln(’Błędne dane’)
end.
17
Instrukcja wyboru
case
of
wybór
else
wyrażenie
ciąg instrukcji
;
en
d
Wybór
stała
. .
,
:
stała
instrukcja
program p06;
{ program wczytuje ocenę jako cyfrę i podaje jej słowną interpretację}
var
ocena:byte;
begin
write(’ Podaj ocenę ’);
readln(ocena);
case ocena of
6: writeln(’celujący’);
5: writeln(’bardzo dobry’);
4: writeln(’dobry’);
3: writeln(’dostateczny’);
2: writeln(’mierny’);
1:writeln(’niedostateczny’)
else writeln(’Błędne dane’);
end
end.
18
Co należy zapamiętać o instrukcjach warunkowych?
Instrukcja if
- w instrukcji if przed słowem kluczowym else nie można postawić średnika
- zarówno po then jak i else może wystąpić tylko jedna instrukcja, jeśli trzeba używamy
instrukcji złożonej
- część ze słowem kluczowym else nie musi wystąpić
- w instrukcjach zagnieżdżonych należy pamiętać, że słowo else kojarzone jest z
najbliższym mu if
- po słowie kluczowym if znajduje się wyrażenie logiczne
Instrukcja case
- wyrażenie w instrukcji case musi być typu porządkowego
- zbiory wartości stałych występujących w wyborze powinny być rozłączne
- jeśli występuje więcej stałych w wyborze to są oddzielone przecinkiem
- zakres wartości stałych od do można zapisać używając dwóch kropek
- przed słowem kluczowym else, w przeciwieństwie do instrukcji if, może wystąpić
średnik
- po dwukropku w wyborze może wystąpić tylko jedna instrukcja
- po słowie kluczowym else może wystąpić więcej niż jedna instrukcja
- część else nie musi się pojawić
19
Pętla - inaczej instrukcja cykliczna powodująca, że pewna sekwencja działań będzie wielokrotnie powtarzana
warun
ek
instrukcja
FAŁSZ
PRAWDA
Instrukcja iteracyjna: -„dopóki”
-„powtarzaj”
- „dla”
while
do
instrukcja
wyrażenie logiczne
Instrukcja „dopóki”
...
write(’Podaj należną kwotę ’);
readln(kwota_nal);
write(’Podaj kwotę wpłacaną ’);
readln(kwota_wp);
while kwota_wp<kwota_nal do
begin
writeln(’ Wpłacona kwota jest zbyt mała!!!’);
write(’ Podaj kwotę wpłacaną ’);
readln(kwota_wp)
end;
...
1) warunek logiczny pętli sprawdzany jest na początku
2) instrukcja jest wykonywana tak długo dopóki warunek
logiczny przyjmuje wartość True
3) jeśli warunek jest fałszem przy pierwszym sprawdzeniu
to instrukcja nie będzie wykonana ani razu
4) każdorazowe wykonanie instrukcji nazywa się iteracją
20
warun
ek
instrukcja
FAŁSZ
PRAWDA
repeat
until
wyrażenie logiczne
ciąg instrukcji
Instrukcja „powtarzaj”
...
write(’Podaj należną kwotę ’);
readln(kwota_nal);
repeat
write(’Podaj kwotę wpłacaną ’);
readln(kwota_wp);
until kwota_wp>=kwota_nal;
...
1) warunek logiczny pętli sprawdzany jest na końcu
2) ciąg instrukcji jest wykonywany tak długo dopóki warunek
logiczny przyjmuje wartość False
3) ciąg instrukcji będzie zawsze wykonany przynajmniej raz
...
write(’Podaj należną kwotę ’);
readln(kwota_nal);
i:=0;
repeat
if i<>0 then writeln(’ Wpłacona kwota jest zbyt mała’);
write(’Podaj kwotę wpłacaną ’);
readln(kwota_wp);
i:=1;
until kwota_wp>=kwota_nal
...
21
for
Instrukcja „dla”
to
wyrażenie1
downto
identyfikator zmiennej
instrukcja
:=
wyrażenie2
do
1) Instrukcja wykonywana jest określoną
liczbę razy
2) Zmienna zwana zmienną sterującą musi być
typu
porządkowego
3) Wyrażenia muszą dawać wartość tego
samego typu
co zmienna sterująca
4) Po słowie kluczowym do występuje jedna
instrukcja
5) Jeśli wyrażenie1 > wyrażenie2 w pętli z to
lub
wyrażenie1 <wyrażenie2 w pętli z downto
to instrukcja
nie zostanie wykonana
6) Jeśli wyrażenie1 = wyrażenie2 to w obu
przypadkach
instrukcja będzie wykonana dokładnie
jeden raz
7) W każdym kroku pętli po wykonaniu
instrukcji zmienna
sterująca jest automatycznie zwiększana
bądź
zmniejszana o jeden
8) Po raz ostatni instrukcja jest wykonana dla
zmiennej
sterującej równej wyrażeniu2
program p07;
uses crt;
var liczba:integer;
odp:char;
function silnia(licz:integer):longint;
var pom,licznik:longint;
begin
pom:=1;
for licznik:=1 to licz do pom:=pom*licznik;
silnia:=pom
end;
begin
clrscr;
repeat
write(’ Dla jakiej liczby całkowitej chcesz obliczyć wartość silni ? ’);
readln(liczba);
writeln(’ Wartość silni dla ’,liczba:5,’ wynosi ’, silnia(liczba));
write(’ Czy liczysz dalej ? (t/n) ’);
readln(odp);
until (odp<>’t’) and (odp<>’T’)
end.
22
Którą instrukcję pętli wybrać?
function silnia(liczba:integer):longint;
var pom,licznik:longint;
begin
pom:=1;
for licznik:=2 to liczba do
pom:=pom*licznik;
silnia:=pom
end;
function silnia(liczba:integer):longint;
var pom,licznik:longint;
begin
pom:=1;
licznik:=1;
repeat
pom:=pom*licznik;
licznik:=licznik+1
until licznik>liczba;
silnia:=pom
end;
function silnia(liczba:integer):longint;
var pom,licznik:longint;
begin
pom:=1;
licznik:=2;
while licznik<=liczba do
begin
pom:=pom*licznik;
licznik:=licznik+1
end;
silnia:=pom
end;
1) Jeśli instrukcja ma być wykonana określoną liczbę razy wybierz for
2) Jeśli warunkiem przerwania pętli jest wyrażenie logiczne i instrukcja ma być wykonana przynajmniej raz wybierz repeat
3) Jeśli warunkiem przerwania pętli jest wyrażenie logiczne i nic nie wiadomo o pierwszym wykonaniu wybierz while
4) Jeśli masz wątpliwości wybierz while
5) Pamiętaj o sprawdzeniu czy na pewno zaistnieje warunek kończący pętle (pętla nieskończona)
23
W jaki sposób wpływać na zmianę realizacji pętli ? - procedury standardowe Continue i Break
while wyr do
begin
I1;
I2;
if wyr1
then continue;
I3;
I4
end;
while wyr do
begin
I1;
I2;
if wyr1
then break;
I3;
I4
end;
- jeżeli wartość wyrażenia wyr1 będzie prawdą
to wszystkie instrukcje w danej iteracji występujące
po wywołaniu procedury continue zostaną pominięte;
następnie rozpoczyna się kolejny krok instrukcji pętli.
- jeżeli wartość wyrażenia wyr1 będzie prawdą
to nastąpi natychmiastowe przerwanie procesu
iteracji;
następną wykonaną instrukcją będzie pierwsza instrukcja
poza pętlą.
Procedury continue i break mogą być wywoływane tylko wewnątrz pętli. Mogą być użyte wewnątrz każdej instrukcji złożonej
występującej w pętlach for, repeat oraz while. Użycie tych procedur poza instrukcjami pętli spowoduje błąd kompilacji.
24
Kilka przydatnych użyć pętli:
for zmienna:=1 to 25000 do; (* wielokrotne wykonanie instrukcji pustej spowoduje opóźnienie
wykonania programu*)
for zmienna:=1 to 25000 do
if KeyPressed then exit;
(* podobnie jak poprzednio jednakże istnieje
możliwość ingerencji z klawiatury*)
repeat until KeyPressed;
(* zatrzymanie programu w oczekiwaniu na naciśnięcie
dowolnego klawisza *)
repeat
...
wybrany_klawisz:=ReadKey
until wybrany_klawisz=#13; (* oczekiwanie na naciśnięcie określonego klawisza np.
>>ENTER<< *)
repeat
...
write(’ Podaj hasło ’);
readln(wyraz)
until haslo = wyraz;
(* zabezpieczanie danego programu przed obcym dostępem *)
25
Podprogramy - ciąg dalszy
Funkcja - podprogram zwracający dokładnie jedną wartość, która jest utożsamiana z nazwą i jest używana w wyrażeniach.
Procedura -podprogram wykonujący jedną lub więcej czynności i zwracający od zera dokilku wyników; nazwa używana jest
w charakterze instrukcji w programie.
procedure
identyfikator
lista parametrów formalnych
Deklaracja procedury
nagłówek procedury
;
ciało procedury
;
Nagłówek procedury
end
begin
ciąg instrukcji
lista deklaracji
Ciało procedury
26
Parametry formalne i aktualne raz jeszcze
Parametry formalne - pojawiają się w nagłówku deklaracji funkcji bądź procedury i są używane w
instrukcjach funkcji
lub procedury
jak zwykłe zmienne. Liczba parametrów
formalnych nie jest ograniczona i ich kolejność występowania jest
dowolna.
Parametr formalny jest obowiązkowo zmienną.
Parametry aktualne - są parametrami występującymi w bloku, z którego wywoływana jest funkcja lub
procedura i używane są
w wywołaniu tychże. Liczba parametrów aktualnych musi być taka sama jak liczba
parametrów formalnych
i należy pamiętać o zgodności typów. Parametrem aktualnym może być wyrażenie,
zmienna bądź stała.
Wywołanie procedury polega na wpisaniu nazwy procedury z odpowiednią listą parametrów aktualnych
jako instrukcji programu.
program p08;
{program wyświetla powitanie w postaci:
**********************************
**********************************
WITAJ W SZKOLE
**********************************
**********************************
**********************************
**********************************}
uses crt;
procedure gwiazdki(l_linii:integer);
var zm_st:integer;
begin
for zm_st:=1 to l_linii do
writeln(’*********************************’)
end;
begin
clrscr;
gwiazdki(2); (* wywołanie procedury *)
writeln(’ WITAJ W SZKOLE ’);
gwiazdki(4)
end.
27
Dalej o parametrach
Parametry przekazywane przez wartość: (przekazywanie w jedną stronę)
procedure gwiazdki(l_linii:integer);
function temp_c(temp_f:real):real;
function reszta(kwota_nal,kwota_wp:integer):integer;
W wyniku wywołania procedury lub funkcji parametrom formalnym zostaje przypisana wartość początkowa równa
wartościom odpowiednich parametrów aktualnych. Operacje wykonywane w treści funkcji lub procedury wykonywane
są na kopii umieszczonej na stosie i w związku z tym nie powodują zmian wartości odpowiadających im parametrów
aktualnych.
Parametry przekazywane przez zmienną: (przekazywanie w obie strony)
procedure czytaj_liczbe(var liczba:real);
procedure pierw_kw(a,b,c:real; var x1,x2:real);
Operacje wykonywane w treści funkcji lub procedury wykonywane są bezpośrednio na przekazywanych do funkcji
lub procedury parametrach aktualnych. Efektem takiego działania jest zmiana wartości parametrów aktualnych po wywołaniu
procedury lub funkcji.
28
Zasięg oddziaływania identyfikatorów
program A;
var B:byte;
const C=2;
procedure L;
var B:char;
procedure C(var F:char);
var B:byte;
begin
...
end;
procedure L(E:boolean);
begin
...
end;
function F:byte;
var E:word;
begin
...
end;
begin
...
end;
begin
...
end.
- zasięg identyfikatora zdefiniowanego w danym bloku rozpoczyna się od miejsca jego zdefiniowania (definicje, deklaracje) aż do końca bloku;
- zasięg parametru formalnego podprogramu rozpoczyna się od nagłówka podprogramu i obowiązuje do końca bloku podprogramu;
- na tym samym poziomie identyfikatory muszą być różne,
- identyfikatory mogą być takie same na różnych poziomach i identyfikator na niższym poziomie przesłania identyfikator z wyższego poziomu.
B,C,L
B,C,L,F
E
E
F,B
29
REKURENCJA - podprogram wywołujący sam siebie
function silnia(liczba:integer):longint;
var pom,licznik:longint;
begin
pom:=1;
for licznik:=1 to liczba do
pom:=pom*licznik;
silnia:=pom
end;
0!=1
n! = 1*2*3*...*n
0!=1
n! = n*(n-1)!
function silnia(liczba:integer):longint;
begin
if liczba=0 then silnia:=1
else silnia:=liczba*silnia(liczba-1)
end;
silnia(3)=3*silnia(2)
zawieszone obliczenie
silnia(3)
silnia(2)=2*silnia(1)
zawieszone obliczenie
silnia(2)
silnia(1)=1*silnia(0)
zawieszone obliczenie
silnia(1)
silnia(0)=1
powrót i obliczenie
silnia(1)
silnia(1)=1*1=1
powrót i obliczenie
silnia(2)
silnia(2)=2*1=2
powrót i obliczenie silnia(3)
silnia(3)=3*2=6
- przy każdym kolejnym wywołaniu podprogramu, tworzony jest na stosie komplet zmiennych lokalnych tego podprogramu,
- podczas wywołania rekurencyjnego na stosie może być wiele kompletów zmiennych ale dostępny jest tylko ostatni,
- po zakończeniu wywoływania rekurencyjnego następuje usuwanie ze stosu kompletów zmiennych w odwrotnej kolejności
do ich składania na stosie.
30
Kilka uwag i rad
- jeśli podprogram ma zwracać więcej niż jedną wartość, bądź modyfikować wartości
parametrów aktualnych użyj procedury;
- jeśli ma być zwrócona dokładnie jedna wartość użyj funkcji;
- jeśli masz wątpliwości użyj procedury;
- jeśli oba typy podprogramów są dopuszczalne użyj tego, który jest ci łatwiej zastosować;
- zmienne mające w podprogramie charakter roboczy należy deklarować jako zmienne
lokalne;
- bardziej bezpieczne i zalecane jest przekazywanie parametrów przez wartość
(chroni przed niepotrzebnymi zmianami tych parametrów);
- jeśli parametr służy do komunikowania otoczeniu efektów wykonania podprogramu
to musi być przekazywany przez zmienną;
- jeśli mamy do przekazania duże struktury danych to unikamy ich przekazywania
przez wartość - pozwoli to na lepsze gospodarowanie pamięcią (dla parametrów
przekazywanych przez wartość tworzona jest ich kopia na stosie);
N.Wirth:
„Nie należy wahać się nad sformułowaniem ciągu instrukcji jako procedury - nawet
jeśli miałaby ona być wywoływana tylko raz- jeżeli zwiększymy w ten sposób
czytelność programu. Definiowanie kolejnych kroków programu jako procedur
w trakcie jego konstrukcji sprawia, że staje się on zrozumiały dla innych i umożliwia
wykazanie poprawności programu”
31
TYPY
proste
strukturalne
wskaźnikowe
całkowity
tablicowy
wyliczeniowy
rekordowy
logiczny
zbiorowy
okrojony
plików
znakowy
obiektowy
rzeczywisty
Typy porządkowe: Wszystkie typy proste poza rzeczywistymi
1) odliczanie ( z wyjątkiem typu całkowitego) rozpoczynamy od 0
2) każdy element typu porządkowego ma dokładnie określone miejsce w zbiorze, które może być odczytane przy pomocy
standardowej funkcji ord
3) dla każdego elementu (poza ostatnim) istnieje przynajmniej jeden element następny - funkcja succ
4) dla każdego elementu (poza pierwszym) istnieje przynajmniej jeden element poprzedni - funkcja pred
Typ logiczny:
boolean = (false, true)
ord(false) = 0
ord(true)=1
succ(false) = true
succ(true) - wartość niezdefiniowana
pred(false) - wartość niezdefiniowanapred(true) =false
32
Typ znakowy - char
TABELA ASCII
0
NUL
32
SPACJA 64
@
96
`
1
SOH
33
!
65
A
97
a
2
STX
34
„
66
B
98
b
3
ETX
35
#
67
C
99
c
4
EOT
36
$
68
D
100
d
5
ENQ
37
%
69
E
101
e
6
ACK
38
&
70
F
102
f
7
BEL
39
’
71
G
103
g
8
BS
40
(
72
H
104
h
9
HT
41
)
73
I
105
i
10
LF
42
*
74
J
106
j
11
VT
43
+
75
K
107
k
12
FF
44
,
76
L
108
l
13
CR
45
_
77
M.
109
m
14
SO
46
.
78
N
110
n
15
SI
47
/
79
O
111
o
16
DLE
48
0
80
P.
112
p
17
DC1
49
1
81
Q
113
q
18
DC2
50
2
82
R
114
r
19
DC3
51
3
83
S
115
s
20
DC4
52
4
84
T
116
t
21
NAK
53
5
85
U
117
u
22
SYN
54
6
86
V
118
v
23
ETB
55
7
87
W
119
w
24
CAN
56
8
88
X
120
x
25
EM
57
9
89
Y
121
y
26
SUB
58
:
90
Z
122
z
27
ESC
59
;
91
[
123
{
28
FS
60
<
92
\
124
}
29
GS
60
=
93
]
125
|
30
RS
62
>
94
^
126
~
31
US
63
?
95
-
127
DEL
Funkcja ord zmienia znak
na kod z tabeli
Funkcja chr zmienia
wartość porządkową na
znak z tabeli
Znak można zapisać
również w postaci: # +
kod np.:
#7 = BEL; #13=ENTER
Funkcja upcase powoduje
zamianę argumentu na
dużą literę:
upcase(’a’)=’A’;
upcase(’A’)=’A’
33
Typy rzeczywiste
Zapis liczby w postaci zmiennoprzecinkowej l=m*e
w
l - liczba rzeczywista
m - mantysa
e - podstawa stosowanego systemu
w - cecha
Arytmetyka zmiennopozycyjna:
dodawanie i odejmowanie:
dodajemy lub odejmujemy mantysy (po przesunięciu mantysy i zwiększeniu cechy jeśli to konieczne)
3.12 x 10
1
+4.26 x 10
1
6.18 x 10
1
+1.81 x 10
-1
mnożenie:
cechy są dodawane a mantysy mnożone
2.37 x 10
2
x -3.64 x 10
-2
4.27 x 10
1
x 3.68 x 10
1
dzielenie:
cechy są odejmowane a mantysy dzielone
2.37 x 10
2
x -3.64 x 10
-2
4.27 x 10
1
x 3.68 x 10
1
Konsekwencje:
- dodawanie lub odejmowanie małych (ale różnych od zera liczb) może nie dać spodziewanego efektu
5.18 x 10
2
+4.37 x 10
-1
- często wynik a x 1/a nie jest 1 np. a=3.00 x 10
0
- wynik a+(b+c) nie zawsze jest taki sam jak (a+b)+c np. a=6.31 x 10
1
b=4.24 x 10
0
c=2.47 x 10
-1
34
Typy definiowane
type
Lista definicji typów
deklaracja typu
identyfikator
=
typ
;
Deklaracja typu
type
calkowity = integer;
logiczny = boolean;
- Typ wyliczeniowy - jest typem porządkowym, o skończonym zbiorze wartości określonych identyfikatorami
type
dzien_tygodnia = (pon,wt,sr,czw,pt,sob,nd);
plec = (kobieta, mezczyzna);
Porządek w typie jest zgodny z kolejnością wyliczenia w definicji,
Wartości typu wyliczeniowego wymienione kolejno w definicji mają liczby porządkowe równe 0,1,...
Dwa różne różne typy wyliczeniowe występujące w tym samym bloku nie mogą mieć takich samych wartości,
Zmienne i stałe typów wyliczeniowych nie mogą być parametrami procedur write, read...
- Typ okrojony - jest podzbiorem typu porządkowego, zachowującym wszystkie własności typu pierwotnego dla ograniczonych wartości
type
dzien_tygodnia = (pon,wt,sr,czw,pt,sob,nd);
dni_robocze = pon..pt;
litera = ’A’..’Z’;
zakres = 1..200;
35
program p09;
uses crt;
type dzien_tyg = (pon,wt,sr,czw,pt,sob,nd);
var dzien, dz : dzien_tyg;
d:1..7;
procedure pisz_dzien(d:dzien_tyg);
begin
case d of
pon: writeln(’poniedziałek’);
wt: writeln(’wtorek’);
sr: writeln(’środa’);
czw: writeln(’czwartek’);
pt:writeln(’piątek’);
sob:writeln(’sobota’);
nd:writeln(’niedziela’);
end
end;
begin
repeat
write(’ Podaj jaki dzisiaj jest dzień (1-pon,2-wt,...’);
readln(d);
until (d>=1) and (d<=7);
dzien:=dzien_tyg(d-1); { zmiana typu zmiennej}
write(’ Dzisiaj jest ’);
pisz_dzien(dzien);
dzien:=succ(dzien);
writeln(’ Do konca tygodnia zostały jeszcze ; ’’);
for dz:=dzien to nd do
pisz_dzien(dz)
end.
Zmiana typu wyrażenia lub zmiennej
-
operacje zmiany typów dotyczą tylko typów porządkowych
lub wskaźnikowych
- Nazwa_typu(wyrażenie) lub nazwa_typu(identyfikator zmiennej)
- zmieniane typy muszą pasować do siebie pod względem wielkości
- zmiana typu zmiennej nie wpływa na jej wielkość ani adres,
zmienia się tylko jej wartość
36
Typy strukturalne: typy, których każdy element jest zbiorem komponentów,
istnieje określony sposób dotarcia do pojedynczych składowych danego elementu,
dozwolona wielkość typu strukturalnego 65520 bajtów
Typ tablicowy - typ strukturalny, którego komponenty są jednego typu i ich kolejność jest ściśle określona;
dostęp do składowych poszczególnych elementów odbywa się poprzez indeksy
array
typ
identyfikator
=
zakres
]
Deklaracja typu tablicowego
[
of
type
wektor = array[1..10] of integer;
nazwisko = array (.1..50.) of char;
suma = array[1..200] of real;
dni_tyg = (pn,wt,sr,czw,pt,sob,nd);
var
x:wektor;
tab_naz:nazwisko;
a:array [1..31] of dni_tyg;
37
program p10;
{ program wczytuje 5 liczb całkowitych
i wypisuje je w odwrotnej kolejności,
używamy tylko zmiennych prostych}
uses crt;
var l_1,l_2,l_3,l_4,l_5:integer;
begin
clrscr;
writeln(’ Podaj kolejno 5 liczb);
readln(l_1);
readln(l_2);
readln(l_3);
readln(l_4);
readln(l_5);
writeln(’ wypisuję liczby w odwrotnej kolejności’);
writeln(l_5);
writeln(l_4);
writeln(l_3);
writeln(l_2);
writeln(l_1)
end.
program p11;
{ program wczytuje 5 liczb całkowitych
i wypisuje je w odwrotnej kolejności,
używamy tablic}
uses crt;
var a:array [1..5] of integer;
i:integer;
begin
writeln(’ Podaj kolejno 5 liczb);
for i:=1 to 5 do readln(a[i]);
writeln(’ wypisuję liczby w odwrotnej kolejności’);
for i:=5 downto 1 do writeln(a[i])
end.
Każda składowa tablicy jest oddzielnie dostępna :
nazwa_tablicy[indeks]
i może być traktowana jako zmienna typu prostego
Nie można dokonywać operacji na zmiennych tablicowych
jako całości
Zmienne tablicowe mogą występować jako parametry
formalne i aktualne w procedurach i funkcjach;
parametr formalny może być zadeklarowany jako tablica
jeśli wcześniej został zdefiniowany typ tablicowy
(tzn. na liście parametrów formalnych nie może wystąpić
pełna deklaracja typu tablicowego)
38
TYP STRING - typ łańcuchowy
wewnętrzna definicja typu:
type
string = array[0..255] of char
łańcuch jest „kolekcją” znaków traktowanych jako całość
Sposób reprezentacji łańcucha:
zmienne typu łańcuchowego deklarujemy:
var nazwa:string[9]; { potencjalna maksymalna długość łańcucha wynosi 9 znaków}
tekst:string; { tak zadeklarowana zmienna zajmuje w pamięci 256 bajtów! }
5
I
W
O
N
A
0
1
2
3
4
5
6
7
8
9
Funkcje standardowe do działań na łańcuchach:
Length(s) - wynikiem jest długość łańcucha s bez uwzględnienia bajtu 0
Length(’tekst’) ---> 5; s:=’Pascal’; Length(s) ---> 6
Copy(s,indeks,licznik) - z łańcucha s od miejsca indeks zostanie wycięty podłańcuch o długości licznik
Copy(’Turbo Pascal’,7,6) ---> ’Pascal’; Copy(’Ala ma kota’,8,3) ---> ’kot’
Concat(s1,s2,...,sn) - łańcuchy s1,s2,...,sn zostaną połączone w jeden wspólny łańcuch (znaki ponad 255 zostaną obcięte)
Concat(’Ala’,’ ’,’ma’,’ ’,’kota’) ---> „Ala ma kota’
Taki sam efekt można uzyskać korzystając z operatora + : ’Ala’+’ ’ +’ma’+’ ’ +’kota’
Pos(s1,s) - w łańcuchu s poszukiwany jest łańcuch s1; zwracana jest pozycja pierwszego wystąpienia
Pos(’gra’,’programista’) ---> 4; Pos(’t’,’programista’) ---> 10
39
Procedury standardowe:
Delete(s,indeks,licznik) - z łańcucha s od miejsca indeks zostanie ususniętych licznik znaków, s musi być zmienną
Insert (s1,s,indeks) - do łańcucha s od pozycji indeks zostanie dopisany łańcuch s1, s musi być zmienną
var
s:string[10];
begin
s:=’algorytm’;
delete(s,1,4);
writeln(s);
{ ---> ’rytm’ }
insert(’algo’,s,1);
writeln(s);
{ ---> ’algorytm’}
s:=’dwa bobry’;
delete(s,2,4);
writeln(s);
{ ---> ’dobry’}
insert(’wa b’,s,2);
writeln(s);
{ ---> ’dwa bobry’}
end.
Val(s,x,kod) - łańcuch s zostaje zamieniony na wartość numeryczną x, a kod informuje czy ta zamiana odbyła się bez błędu ( 0 )
Val(’2’,x,kod) ---> jeśli x jest typu integer to x = 2, kod = 0
jeśli x jest typu real to x=2.0000000000E+00, kod =0
Val(’1234g5’,x,kod) ---> x=0, kod=5
Str(x[:dłudość[:miejsca dziesiętne]],s) - wartość liczbowa x zostaje przekształcona na łańcuch s
Str(240.0,s) ---> s = ’2.4000000000E+02’
Str(240,s) ---> s = ’240’
Str(2.4E+02:3:1,s) --> s = ’240.0’
Str(123.3456777:15:3,s) ---> s = ’123.346’
40
program p12;
{ program wypełnia tablicę łańcuchów pozycjami
z listy, zapisanej w łańcuchu, w którym poszczególne
elementy są oddzielone przecinkami}
const max_elem =50;
var tablica: array[1..max_elem] of string;
i,k:integer;
lista:string;
znak:char;
begin
writeln(’Podaj listę słów oddzielonych przecinkami ’);
readln(lista);
znak:=‘,’;
if Length(lista) >0 then
begin
i:=1;
while (Pos(znak,lista)>0 do
begin
tablica[i]:=Copy(lista,1,Pos(znak,lista)-1);
lista:=Copy(lista,Pos(znak,lista)+1,length(lista));
i:=i+1;
end;
tablica[i]:=lista;
writeln(’ Utworzona tablica ma ’,i:2,’ elementów ’);
for k:=1 to i do writeln(tablica[k])
end
else writeln(’ Tablica nie posiada żadnych elementów’)
end.
Jeszcze trochę informacji o łańcuchach:
- łańcuchy można porównywać korzystając z operatorów relacji:
=, <=,>=,<,>,<>
- do poszczególnych elementów łańcucha można się odnosić tak
jak do elementów tablicy - poprzez indeks:
s[3], s[10], s[0]
trzeba pamiętać, że te elementy są już typu char a nie string
- string jest jedynym typem tablicowym, na którym dopuszczalne są
operacje agregujące np. ’+’; oraz wartości tego typu mogą być
parametrami procedur write i read
Różnice pomiędzy łańcuchami i tablicami o elementach znakowych:
- tablica znakowa może mieć dowolną długość,
- liczba znaków wpisanych do tablicy nie jest nigdzie zapamiętywana,
- elementy tablicy nie są w żaden sposób powiązane ze sobą
i dlatego można się do nich odwoływać pojedynczo lub w całości
jako tablicy (nie można odwoływać się do podzbiorów)
- łańcuch może być traktowany jako jednowymiarowa tablica znaków
natomiast tablica może mieć wiele wymiarów.
41
record
Typ rekordowy
lista pól
część stała
;
część wariantowa
;
Lista pól
Typ rekordowy - typ strukturalny łączący w jedną całość komponenty różnych typów
end
Część stała
lista identyfikatorów
:
typ
;
type
data = record
day: 1..31;
month:1..12;
year:integer
end;
42
program p13;
uses crt;
type
data = record dzien:1..31;
miesiac:1..12;
rok:integer
end;
osoba =
record imie, nazwisko: string[15];
urodz: data;
end;
var
x:osoba;
procedure wczytajdane(var ktos:osoba);
begin
clrscr;
writeln(’ Podajesz dane osobowe : ’);
write(’ Imię ’);
readln(ktos.imie);
write(’Nazwisko ’);
readln(ktos.nazwisko);
write(’ data ur. dz: ’);
readln(ktos.urodz.dzien);
write(’ m: ’);
readln(ktos.urodz.miesiac);
write(’ r: ’);
readln(ktos.urodz.rok)
end;
begin
wczytajdane(x)
end.
Co trzeba zapamiętać o zmiennych typu rekordowego?
- rekordy mogą być zagnieżdżone, tzn pole rekordu może być
ponownie typu rekordowego; mówimy wówczas o strukturze
hierarchicznej;
- pola tego samego typu mogą wystąpić oddzielone przecinkiem;
- dostęp do poszczególnych komponentów rekordu odbywa się
przy pomocy kropki oraz nazwy pola;
- podobnie jak w przypadku tablic zmienna rekordowa jako całość
nie może być parametrem procedur write i read,
- zmienne rekordowe mogą wystąpić w instrukcji przypisania pod
warunkiem, że są zdefiniowane tym samym typem;
- pola rekordów mogą występować we wszystkich operacjach,
jakie są dopuszczalne dla zadanego typu (typu pola), w szczególności
mogą być parametrami procedur lub funkcji;
- instrukcja wiążąca upraszcza dostęp do pól zmiennej rekordowej,
podobnie jak rekordy mogą być zagnieżdżone tak i instrukcja wiążąca
może być zagnieżdżona.
43
procedure wczytajdane(var ktos:osoba);
begin
clrscr;
writeln(’ Podajesz dane osobowe : ’);
with ktos do
begin
write(’ Imię ’);
readln(imie);
write(’Nazwisko ’);
readln(nazwisko);
with urodz do
begin
write(’ data ur. dz: ’);
readln(dzien);
write(’ m: ’);
readln(miesiac);
write(’ r: ’);
readln(rok)
end
end
end;
with
identyfikator
do
Instrukcja wiążąca
,
instrukcja
Zagnieżdżone instrukcje wiążące mogą być zapisane w sposób
uproszczony, należy jednak pamiętać o kolejności identyfikatorów:
with ktos, urodz do
begin
write(’ Imię ’);
readln(imie);
write(’Nazwisko ’);
readln(nazwisko);
write(’ data ur. dz: ’);
readln(dzien);
write(’ m: ’);
readln(miesiac);
write(’ r: ’);
readln(rok)
end
Zapis with urodz, ktos do spowoduje błąd kompilacji
44
case
Część wariantowa
identyfikator
:
typ
of
wariant
Wariant
stała
,
:
(
lista pól
)
type
data = record day:1..31;
month:1..12;
year:integer
end;
sex = (female, male);
alpha15 = string[15];
osoba =
record first_name, surname: alpha15;
birth: data;
case s:sex of
female: (maidenname: alpha15);
male: (beard, moustache: boolean;
case armyservice:boolean of
false : ();
true : (enddate:data))
end;
- wybór wariantu odbywa się programowo poprzez
nadanie wartości tzw. polu wyróżnikowemu,
- typem pola wyróżnikowego może być dowolny
typ prosty porządkowy,
- część wariantowa jest zawsze ostatnią częścią
definicji rekordu,
- rozmiar rekordu z wariantami jest sumą rozmiaru
części stałej i najdłuższego wariantu części zmiennej
Rekordy o zmiennej strukturze