1.2.13. Funkcie definované užívateľom

 

Pri programovaní budeme potrebovať často vypočítať hodnotu z neštandardných funkcií, ktoré sa v programe opakujú. Aby sme nemuseli vždy tieto zložité výrazy celé vypisovať, definujeme si vlastnú funkciu. Ak potrebujeme vypočítať hodnotu tejto funkcie, vypíšeme len meno funkcie (hovoríme, že voláme funkciu) s príslušným argumentom. Ak je funkcia raz definovaná, pracujeme s ňou ako so štandardnou funkciou. Pred volaním funkcie ju musíme definovať príkazom DEF, ktorý má tvar:

      DEF FN názov (zoznam formálnych argumentov) = výraz

kde názov je názov nami definovanej funkcie. Názov funkcie je jedno písmeno (pokiaľ je výsledok číslo) alebo jedno písmeno a znak $ (pokiaľ je výsledkom reťazec). Zoznam formálnych argumentov je zoznam premenných oddelených čiarkou, kde mená sú jednopísmenové. Zoznam argumentov je nutné písať do uzatvorených zátvoriek. Funkciu definujete tým, že napíšete príkaz DEF niekde do programu. Definícia funkcie môže byť len na jednom riadku.

Napr. definujme funkciu, ktorej výsledkom je druhý mocnina argumentu.

      10 DEF FN s(x)= x * x: REM druha mocnina x

DEF získame v rozšírenom móde použitím SYMBOL SHIFT + 1. Pri vkladaní počítač pridá FN automaticky (pretože v príkaze DEF vždy ihneď nasleduje FN). Rovnítko potom znamená skutočnú definíciu funkcie. Funkcia môže byť definovaná akýmkoľvek výrazom a môžete sa na ňu odkazovať ako na obyčajnú premennú.

Volanie funkcie sa vykoná takto:

      FN názov (zoznam skutočných argumentov)

kde názov je názov definovanej funkcie, v zozname sú argumenty oddelené čiarkou. Skutočným argumentom môže byť ľubovolný odpovedajúci výraz (aritmetický alebo reťazec podľa definície funkcie). Pri volaní funkcie sa formálny argument v definícii nahradí skutočným argumentom (jeho hodnotu), ostatné premenné použité v definícii sa nahradia svojimi hodnotami v okamihu volania funkcie.

Príklad:

Našou úlohou je vypočítať obsah plochy medzikružia, polomer menšej kružnice je 10 cm, väčšej 15 cm. Obsah plochy medzikružia dostaneme tak, že od obsahu väčšieho kruhu odčítame plochu menšieho kruhu. Pretože obsah kruhu budeme počítať dvakrát, použijeme na jeho výpočet funkciu definovanú užívateľom.

      10 DEF FN o(r)=PI*r*r

      20 LET p1=FN o(10)

      30 LET p2=FN o(15)

      40 LET p=p2-p1

      50 PRINT "Obsah medzikruzia je ";p

Na riadku 10 definujeme funkciu o(r), ktorá počíta obsah kruhu s polomerom r.

Na riadku 20 voláme funkciu o so skutočným parametrom 10. Do výrazu na riadku 10 sa dosadí za argument r skutočný argument 10 a vypočíta sa hodnota výrazu PI*10*10. Hodnota funkcie sa priradí premennej p1.

Na riadku 30 analogicky voláme funkciu o so skutočným argumentom 15, vypočíta sa hodnota PI*15*15.

Na riadku 40 sa vypočíta rozdiel obsahov a výsledok sa vypíše (riadok 50).

Teraz si ukážeme definíciu užitočnej funkcie pre zaokrúhlenie. Funkcia INT vždy "zaokrúhľuje" dole. Aby zaokrúhlenie bolo "normálne" (do .5 dole, nad .5 hore), je treba použiť konštantu 0.5. Funkcia bude mať tvar:

      20 DEF FN r(x)=INT (x+0.5): REM zaokruhlenie

Potom dostanete:

      FN r(2.9) = 3                       FN r(2.4)=2

      FN r(-2.9) = -3              FN r(-2.4)=-2

Porovnajte výsledky s výsledkami, ktoré dostanete pri použití INT namiesto FN r.

Máme tu ďalší program pre použitie funkcií:

      10 LET x = 0: LET y = 0: LET a = 10

      20 DEF FN p(x,y)=a+x*y

      30 DEF FN q()=a+x*y

      40 PRINT FN p(2,3),FN q()

V tomto programe je viac zaujímavých bodov.

Po prvé, funkcia nie je obmedzená na 1 argument, môže mať viac alebo dokonca žiadny argument, ale stále musíte písať zátvorky. Po druhé, nezáleží na umiestnení DEF v programe, definícia funkcie môže byť na ľubovoľnom mieste programu. Funkcia nemôže byť však definovaná v priamom režime. V našom príklade sa po vykonaní riadku 10 sa preskočí na riadok 40, kde sa vytlačia hodnoty funkcií.

Po tretie, x a y sú mená premenných v programe a zároveň mená formálnych argumentov funkcie (čo nemá na hodnotu premenných žiadny vplyv). V definícii funkcie nie je však žiaden argument nazvaný a, ale iba premenná a. Tak pri vykonaní FN p(2,3) má premenná a stále hodnotu 10, pretože ide o premennú, argument x má hodnotu 2, pretože je to prvý argument, argument y má hodnotu 3, pretože je to druhý argument. Výsledkom je 10+2*3=16. Keď sa vykoná FN q() (funkcia nemá žiadne argumenty), a, x, y sú premenné a majú hodnoty 10, 0, 0. Odpoveď je v tomto prípade 10+0*0=10. Teraz zmeňte riadok 20 na:
      20 DEF FN p(x,y)=FN q()

teraz FN p(2,3) bude mať hodnotu 10, pretože FN q sa bude vracať k hodnotám x a y a argument FN p nie je použitý.

Niektoré verzie jazyka BASIC majú funkcie LEFT$, RIGHT$, MID$ a TL$, kde

      LEFT$ (a$,n) dáva podreťazec z a$ majúci prvých n znakov

      RIGHT$(a$,n) dáva podreťazec z a$ majúci posledných n

   znakov

      MID$(a$,n1,n2) dáva podreťazec z a$, ktorý má n2 znakov a

                        začína na pozícii n1.

      TL$(a$) dáva podreťazec z a$, ktorý sa skladá zo všetkých

               znakov mimo prvého

Kto je na tieto funkcie zvyknutý, môže napísať užívateľsky definované funkcie, ktoré robia to isté:

      10 DEF FN t$(a$) = a$(2 TO): REM TL$

      20 DEF FN l$(a$,n) = a$(TO n): REM LEFT$

Skontrolujte, či tieto funkcie pracujú s reťazcami s dĺžkou 0 alebo 1. Všimnite si, že naša funkcia l$ má dva argumenty, jeden je číslo a druhý je reťazec.

Funkcia môže mať až 26 číselných argumentov (prečo 26?) a zároveň až 26 reťazcových argumentov.

Na pravej strane definície funkcie môžeme použiť tiež ľubovoľnú funkciu (štandardnú i užívateľskú). Preto môžeme zadať napr.:

      DEF FN s(x) = SIN x