E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
PODPROGRAMY - PROCEDÚRY A FUNKCIE
Naše programy, vytvárané v predošlých lekciách, boli pomerne krátke – vmestili sa na výšku
jednej obrazovky. Predstavme si ale komplexnejší program napr. na spracovanie nameraných
údajov meteorologickej stanice:
•
načítavanie údajov, ich uloženie do súboru
•
štatistické vyhodnocovanie (hľadanie najnižšej a najvyššej teploty, priemernej teploty,
odchýlok, porovnávanie teplôt)
•
výpis štatistických výpočtov
Modulárne a štruktúrované programovanie
Takýto rogram by zaberal určite viac obrazoviek a jeho kontrola, či hľadanie chýb by boli
komplikovanejšie. „Dlhé“ profesionálne programy programuje tím programátorov, pričom
každý má za úlohu naprogramovať len časť programu. Preto sa programuje modulárne
a štruktúrovane:
•
Modulárne programovanie – program sa podelí na uzavreté celky – moduly, každý modul
sa naprogramuje ako tzv. podprogram (procedúra resp. funkcia), hlavný program sa
potom skladá z volaní podprogramov. Často sa časť programu opakuje, alebo sa opakuje
s premenlivou vstupnou hodnotou a vtedy je úplne výhodné zapísať tento kód pomocou
podprogramu.
•
Štruktúrované programovanie – jazyk Turbo Pascal je štruktúrovaný jazyk, vytvára
uzavreté štruktúry (napr. cykly), nedovoľuje napísať neprehľadný – neštruktúrovaný
program, naše vzorové programy sa snažíme písať prehľadne, aby boli jasne čitateľné.
V tejto kapitole sa naučíme vytvárať podprogramy, podeliť program na menšie moduly –
procedúry a funkcie, neskôr si ukážeme, ako z procedúr a funkcií vytvoriť knižnicu programov.
Definícia procedúr a
funkcií
Procedúry a funkcie sú umiestnené
pod hlavičkou programu v časti
deklarácií a definícií a uvádzame
ich slovíčkom procedure resp.
function, pod deklaráciou
premenných:
1
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Definícia procedúr
procedure MENO (zoznam formálnych parametrov);
var zoznam lokálnych premenných;
begin
...
telo procedúry;
...
end;
•
MENO - nesmie obsahovať medzerník, či interpunkčné znamienka, ak chcete zvoliť viac
slov, oddeľte ich podčiarovníkom
•
formálne parametre – premenné, za ktoré sa dosadia skutočné hodnoty pri volaní
procedúry, slúžia na definovanie kódu procedúry
•
lokálne premenné – premenné, ktoré používa procedúra iba vo svojom tele, platia
iba v jej tele (lokálne)
•
telo procedúry – kód, ktorý vykoná procedúra, pričom môže aj niečo odkázať
programu prostredníctvom premenných volaných odkazom
parametre procedúry
volané hodnotou
Príklad:
N: integer;
a: real;
parametre volané hodnotou –
procedúra hodnoty potrebuje pre
vykonanie svojho kódu
(vstup do procedúry)
volané odkazom
Príklad:
var N: integer;
var a: real;
parametre volané odkazom –
procedúra prostredníctvom týchto
premenných odkazuje zmenené, či
načítané hodnoty programu
(výstup z procedúry)
Príklad 1 - Hviezdy:
Napíšme jednoduchú procedúru, ktorá vykreslí „k“ hviezdičiek do riadku a kurzor prejde do
nového riadku:
procedure HVIEZDY(k: integer);
var i: integer;
begin
for i:=1 to k do write (’*’);
writeln;
end;
premenná k – je volaná hodnotou (k je „vstup“ do procedúry, procedúra nemení hodnotu k)
premenná i – lokálna premenná – len pre potreby procedúry
2
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Príklad volania procedúry v programe:
program OBRAZOK;
var n: integer;
procedure HVIEZDY(k: integer);
var i: integer;
begin
for i:=1 to k do write (’*’);
writeln;
end;
begin {main}
writeln(‘Zadaj počet riadkov‘)
readln(n);
for i:=1 to n do HVIEZDY(i);
for i:=n downto 1 do HVIEZDY(i);
end.
•
Premenná n – globálna premenná, platná v celom programe včítane podprogramov.
•
Pri volaní procedúry HVIEZDY(i) sa za premennú k dosadí hodnota premennej i, takže
procedúra sa volá zakaždým s inou hodnotou najprv s 1 (1 hviezdička), s 2 (2 hviezdičky)
až do n, potom od n do 1.
•
Porozmýšľajte, čo nakreslí program OBRAZOK?
•
Nakreslite konkrétny obrázok pre n=5.
•
Ako by OBRAZOK vyzeral, ak by sme zamenili poradie cyklov for – to a for – downto?
Úloha 1 (Hviezdičky po ďalšie...):
Napíšte program, ktorý len pomocou procedúry HVIEZDY nakreslí štvorec resp. obdĺžnik.
program OBDLZNIK;
var a,b: integer;
procedure HVIEZDY(k: integer);
var i: integer;
begin
for i:=1 to k do write (’*’);
writeln;
end;
begin {main}
writeln (‘Zadaj strany obdlznika‘);
readln (a,b);
for i:=1 to b do HVIEZDY(a);
end.
Čo by ste museli v programe zmeniť, aby za pomoci procedúry HVIEZDY vykreslil
trojuholník?
Príklad 2 - Výmena:
Napíšme jednoduchú procedúru, ktorá vymení hodnoty dvoch premenných. Pozor, keďže
procedúra mení hodnoty a odkazuje ich do tela programu, musíme použiť parametre volané
odkazom:
3
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
program VYMENA(var a,b: integer);
var pom: integer;
begin
pom:=a;
a:=b;
b:=pom;
end.
premenné a, b – formálne parametre volané odkazom
premenná pom – lokálna premenná procedúry VYMENA
Príklad volania procedúry v programe:
Pri otáčaní poľa (úloha 2 v predošlej lekcii) sme použili nasledujúci kód výmeny
odpovedajúcich prvkov (útržok tela programu):
for i:=1 to N div 2 do begin
pom:= a[i];
a[i]:= a[N-i+1];
a[N-i+1]:= pom;
end;
Použitím procedúry VYMENA, ktorú by sme vložili pod hlavičku programu, by sme kód
upravili do tvaru:
for i:=1 to N div 2 do VYMENA(a[i],a[N-i+1]);
Úloha 2 (Znova Euklid a najmenší násobok):
Prepíšte program EUKLID na hľadanie NSD dvoch celých kladných čísel na procedúru
a použite ho v programe na krátenie zlomkov, ak načítame čitateľa a menovateľa zlomku
(čitateľa aj menovateľa musíme vydeliť ich najväčším spoločným deliteľom, čím dostaneme
základný zlomok):
program KRATENIE_ZLOMKOV;
var cit, men, nsd: integer;
procedure EUKLID (a,b:integer, var c:integer);
begin
while a<>b do
if a>b then a:=a-b
else b:=b-a;
c:=a;
end;
begin {main}
writeln (‘Zadaj citatela a menovatela‘);
readln(cit, men);
EUKLID(cit,men,nsd);
if nsd=1 then (‘Zlomok je v zakladnom tvare‘)
else begin
cit:=cit div nds;
men:=men div nsd
writeln(‘Krateny zlomok: cit, men‘)
end;
end.
4
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Definícia funkcií
function MENO(zoznam formálnych parametrov):typ_funkcie;
var zoznam lokálnych premenných;
begin
...
telo funkcie (musí obsahovať MENO funkcie na ľavej
strane priraďovacieho príkazu);
...
end;
•
MENO - nesmie obsahovať medzerník, či interpunkčné znamienka, ak chcete zvoliť viac
slov, oddeľte ich podčiarovníkom
•
formálne parametre – premenné, za ktoré sa dosadia skutočné hodnoty pri volaní
funkcie, slúžia na definovanie kódu funkcie
•
typ funkcie - výsledkom funkcie je napríklad číslo, reťazec, znak – istého typu (napr.
integer, real, string, boolean,...)
•
lokálne premenné – premenné, ktoré používa funkcia iba vo svojom tele, platia iba
v tele funkcie
•
telo funkcie – v tele sa musí vyskytovať (aspoň raz) priradenie do mena funkcie
výraz rovnakého typu, ako je funkcia. (Meno funkcie je teda na ľavej strane priraďovacieho
príkazu. Meno funkcie sa môže vyskytovať aj na pravej strane priraďovacieho príkazu, ale
iba v tzv. rekurzívnych funkciách, tie si ukážeme neskôr)
Príklad 3 – jednoduchá funkcia:
Napíšme jednoduchú funkciu, ktorá pre dané dve celé čísla vypočíta ich súčet a ešte pripočíta
ich súčin, teda pre čísla x a y funkcia vypočíta x+y+x.y:
Function VYPOCET(a,b: integer): integer;
begin
VYPOCET:=a+b+a*b;
end;
premenné a, b – formálne parametre volané hodnotou
Príklad volania procedúry v programe:
program POCITAJ;
var x,y: integer;
function VYPOCET(a,b: integer): integer;
begin
VYPOCET:=a*b+a+b;
end;
begin {main}
writeln(‘Zadaj dve cele cisla‘);
readln(x,y);
writeln(‘Vysledok: ‘,VYPOCET(x,y))
end.
5
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Funkcia sa v tele programu volá so skutočnými parametrami buď v príkaze write
(writeln), ktorý vypíše jej hodnotu, alebo sa jej meno vloží do pravej strany priraďovacieho
príkazu (jej výpočet uľahčí zápis iného váýpočtu).
Príklad 4 – Kombinačné číslo:
Funkcie je vhodné použiť pri rôznych výpočtoch. Vypočítame kombinačného číslo pomocou
funkcie na výpočet faktoríálu. Kombinačné číslo  i  (čítame i nad k ) vypočítame podľa
k
 
vzorca
i
,
i!
 k  = (i − k )!.k!
 
kde i! je faktoriál čísla i, (i-k)! je faktoriál čísla i-k a k! je faktoriál čísla k.
Napíšme si najprv funkciu pre výpočet faktoriálu (jej kód už nie je žiadnou novinkou J)
Function FACT (n: integer): longint;
var f:longint; i:integer;
begin
f:=1;
for i:=1 to n do f:=f*i;
FACT:=f;
end;
premenné a, b – formálne parametre volané hodnotou
POZOR! – nie je možné priamo do mena funkcie realizovať výpočet, teda použiť príkaz
FACT:=FACT*i, lebo jednak sa meno funkcie nesmie nachádzať na pravej strane výrazu
(pokiaľ to nie je rekurzívna funkcia) a jednak sa funkcia nemôže vyskytovať na pravej strane
výrazu bez parametrov.
Príklad volania procedúry v programe:
program KOMB_CISLO;
var n, k, kc: integer;
function FACT (n: integer): longint;
var f:longint; i:integer;
begin
f:=1;
for i:=1 to n do f:=f*i;
FACT:=f;
end;
begin {main}
writeln('Zadaj dve cele cisla');
readln(n,k);
kc:=(FACT(n) div FACT(n-k))div FACT(k);
writeln('Vysledok: ',kc)
end.
Úloha 3 (Pascalov trojuholník):
Prepíšte predošlý program ako funkciu KC na výpočet kombinačného čísla a vypíšte
tzv. Pascalov trojuholník v tvare podľa obrázka nižšie. Pascalov trojuholník vytvorte
6
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
pomocou kombinačných čísel postupne pre i = 0,1,2,3,... a k = 0,1,2,... , i (i a k vo vzorci i
:
i!
  =
 k  (i − k )!.k!
Trojuholník vypíšeme v nasledujúcom tvare:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
0
 
0
1
 
0
 2
 0 
 
 3
 0 
 
 4
 0 
 
1
1 1
1
 
1
 2
 1 
 
 3
 1 
 
 4
 1 
 
1 2 1
 2
 2 
 
 3
 2 
 
 4
 2 
 
1 3 3 1
 3
 3
 
 4  4
 3   4 
   
1 4 6 4 1
Takto by mal vyzerať Pascalov
trojuholník – ukážeme si to neskôr.
program PASCAL_TROJUHOLNIK;
var i,k,n: integer;
function KC(n,k:integer):integer;
var n, k, kc: integer;
function FACT (n: integer): longint;
var f:longint; i:integer;
begin
f:=1;
for i:=1 to n do f:=f*i;
FACT:=f;
end;
begin
KC:=(FACT(n) div FACT(n-k))div FACT(k);
end;
begin {main}
writeln('Zadajte stupen trojuholnika');
readln(n);
for i:=1 to n do
begin
for k:=1 to i do write (KC(i,k):5);
writeln;
end;
end.
Pozn. :Pascalov trojuholník sa dá vytvoriť aj inak (jednoduchšie na základe rekurzívnej
definície), ale to si ukážeme neskôr.
Úloha 4 (Výpočet prepony):
Napíšte (matematickú) funkciu pre výpočet prepony pravouhlého trojuholníka
pomocou Pytagorovej vety, ak poznáme odvesny trojuholníka.
function C(a,b: integer): real;
begin
C := sqrt(sqt(a)+sqr(b))
end;
7
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
„Booleanovské“ funkcie a príkaz „exit“
Funkcie typu boolean použijeme tam, kde chceme len zistiť, či daná vlastnosť platí, alebo nie.
V tele funkcie musíme ošetriť obe možnosti – true aj false. Niekedy je výhodné funkciu
predčasne ukončiť s istým výsledkom (true, resp. false), ktorý nastavíme na začiatku. Možnosti
týchto funkcií si vysvetlíme na príkladoch a úlohách:
Príklad 5 – Test na prvočíslo:
Už sme vypisovali prvočísla rôznym spôsobom. Pri testovaní čísla na deliteľnosť sme
zbytočne zisťovali deliteľov, ak napr. bolo číslo párne – deliteľné už prvým deliteľom –
dvojkou. Deliteľnosť ďalšími číslami ja už zbytočne zisťovať, hneď ukončíme zisťovanie
deliteľnosti. To nám umožní funkcia a jej okamžité ukončenie príkazom exit.
Príkaz
exit predčasne ukončí vykonávanie podprogramu (funkcie resp. procedúry)
a vráti sa do programu na nasledujúci príkaz po príkaze svojho volania.
Zostavíme funkciu, ktorá len zistí o čísle, či je prvočíslo, alebo je zložené. Funkcia bude typu
boolean: pre hodnotu true - to bude prvočíslo, pre hodnotu false – zo nebude prvočíslo, ale
zložené číslo:
function PRVOCISLO (c: integer): boolean;
var d:integer;
begin
PRVOCISLO:=false;
for d:=2 to trunc(sqrt(c)) do
if c mod d = 0 then exit;
PRVOCISLO:=true;
end;
Pozn:. Ak už o 2, či 3 zistíme, že číslo c delí, príkaz exit spôsobí jej ukončenie s výsledkom
false. Ak však žiadny deliteľ d nedelí číslo c, funkcia sa ukončí posledným príkazom a do
svojho mena uloží hodnotu true.
Úloha 5 (Je pravouhlý?):
Napíšte funkciu, ktorá zistí, či je trojuholník so stranami a, b, c pravouhlý (teda funkcia
bude typu boolean).
function PRAVOUHLY(a,b,c: integer): boolean;
begin
if c = sqrt(sqt(a)+sqr(b))
then PRAVOUHLY:=true
else PRAVOUHLY:=false;
end;
Úloha 6 (Je dokonalé?):
8
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Napíšte funkciu ktorá zistí, či je vstupné číslo dokonalé – či súčet všetkých jeho deliteľov
okrem seba samého sa rovná danému číslu. (Napr. 28 je dokonalá – 28=1+2+4+7+14)
function DOKONALE (c: integer): boolean;
var sucet, del :integer;
begin
sucet:=0;
for del:=1 to c div 2 do
if c mod del = 0 then
sucet := sucet + del;
if c = sucet then DOKONALE:=true
else DOKONALE:=false;
end;
Úloha 7 (Úsečka v kružnici):
Rozhodnite, či úsečka AB o súradniciach A[xA,yA], B[xB,yB] leží celá vo vnútri kružnice
k[S,r], ak stred kružnice má súradnice S[xS,yS].
Pozn. Ak body A,B budú ležať vo vnútri kružnice, bude aj celá úsečka ležať v kružnici. Bod
leží vo vnútri kružnici, ak jeho vzdialenosť od stredu kružnice je menšia ako jej polomer. Teda
|AS|<r, pričom |AS|=
(xA − xS )2 + ( y A − yS )2
function USECKA_IN : boolean;
function PODMIENKA: boolean;
begin
PODMIENKA:=(sqr(xA-xS)+sqr(yA-yS)<sqr(r)) and
(sqr(xB-xS)+sqr(yB-yS)<sqr(r))
end;
begin
if PODMIENKA then USECKA_IN := true
else USECKA_IN := false;
end;
9
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
Neriešené úlohy:
1.
Napíšte funkciu, ktorá zistí, či je dané celé kladné číslo párne, alebo nepárne.
2.
Napíšte procedúru, ktorá vypíše k – krát pozdrav „Ahoj“ na samostatné riadky.
3.
Napíšte funkciu, ktorá zistí, či je dané celé kladné číslo deliteľné všetkými svojimi ciframi.
4.
Napíšte funkciu na výpočet mocniny xn pre ľubovoľné reálne číslo x a celé kladné číslo n.
Uvedomme si, že xn = x.x.x.x. ... .x (n-krát).
5.
Prepíšte program z úlohy 5 v 5. lekcie tak, aby ste použili „boolovskú“ funkciu, ktorá zistí,
či je číslo Amstrongovo. Použite funkciu v programe pre výpis všetkých Amstrongových
čísel menších ako 10 000.
6.
Zostavte procedúru, ktorá vypíše všetky prvočíselné dvojčatá s použitím „boolovskej“
funkcie PRVOCISLO. Prvočíselné dvojčatá sú susedné prvočísla s rozdielom 2.
7.
Vytvorte funkciu na výpočet ciferného súčtu daného celého čísla.
8.
Zostavte funkciu na výpočet početnosti danej cifry v danom celom čísle.
9.
Zostavte funkciu, ktorá zistí, či dané číslo sa rovná druhej mocnine svojho ciferného súčtu.
10. Zostavte funkciu , ktorá zistí o dvoch daných číslach či sú spriatelené.
(Pre spriatelené čísla platí: súčet všetkých kladných deliteľov jedného z nich, okrem seba
samého, sa rovná druhému číslu a naopak.)
11. Napíšte procedúru, ktorá vypíše N náhodných vygenerovaných čísel v intervale <a,b>.
12. Čo vypíše program CO_ROBI1 a CO_ROBI2 ? Napíšte zdôvodnenie.
program CO_ROBI1;
var a,b: integer;
procedure UROB( var x,y:integer);
begin
x:=1; y:=2
end;
begin
writeln('dve cisla '); readln(a,b);
UROB(a,b);
writeln('a=',a,' b=',b)
end.
program CO_ROBI2;
var a,b: integer;
procedure UROB( x,y:integer);
begin
x:=1; y:=2
end;
begin
writeln('dve cisla '); readln(a,b);
UROB(a,b);
writeln('a=',a,' b=',b)
end.
13. Akú hodnotu nadobudne premenná r pre c = 1234567, a prečo?
procedure ZISTI(c: longint;var r:longint);
begin
r:=1;
while c>r do r:=r*10;
r:=r div 10;
end;
14. Nájdite chyby v zápise funkcie MOCNINA, ktorá vypoèíta n-tú mocninu èísla 2:
Function MOCNINA (n: integer): integer ;
var i: integer;
begin
MOCNINA:=1;
for i:=1 to n do MOCNINA:= MOCNINA*2
end;
10
E-learningový kurz – Základy programovania v jazyku Turbo Pascal
Gymnázium P. Horova
ZADANIE 7.1:
Zostavte funkciu na výpočet mocniny 2n pre celé kladné číslo n. Uvedomte si, že
2n = 2.2.2.2. ... .2 (n-krát). Použite funkciu v programe.
ZADANIE 7.2:
Napíšte procedúru tak, aby nakreslila nasledujúci obrázok - 2 pravouhlé trojuholníky
s odvesnou N (náš obrázok je nakreslený konkrétne pre N=5). Použite procedúru v programe
a nakreslite obrázok. (Súčasťou procedúry môže byť aj funkcia HVIEZDY zo začiatku lekcie).
***** *****
****
****
***
***
**
**
*
*
11
Download

PODPROGRAMY - PROCEDÚRY A FUNKCIE