Programovateľná kalkulačka bc

23.06.2013 18:16 | Články | mirek biňas
Programovateľná kalkulačka bc
V predchádzajúcom článku sme sa pozreli na základné použitie jazyka bc, ktorý sa vo svojom interaktívnom režime dá veľmi dobre použiť ako kalkulačka v príkazovom riadku. Dnes sa na bc pozrieme znova, ale tentokrát naozaj ako na programovací jazyk. Pozrieme sa teda, čo všetko si v ňom môžeme dovoliť a ako budeme vedieť využiť jazyk bc ako programovateľnú kalkulačku.

Práca so vstupom a výstupom

Našu výpravu do programovania v jazyku bc začneme štandardným príkladom Hello world!. Jeho podoba v tomto jazyku sa nachádza v nasledujúcom príklade:
print "Hello world!\n"
Po napísaní tohto riadku v interaktívnom režime jazyka bude tento riadok priamo spustený a na obrazovke sa zobrazí správa Hello world!

Parametrom príkazu print je zoznam reťazcov a výrazov, ktoré sú oddelené čiarkami. V reťazci je možné použiť špeciálne znaky – teda znaky, ktoré začínajú spätným lomítkom. bc rozpoznáva nasledovné špeciálne znaky: "\a" (upozornenie alebo zvonček), "\b" (backspace), "\f" (form feed), "\n" (nový riadok), "\r" (carriage return), "\q" (úvodzovky), "\t" (tabelátor), a "\\" (spätné lomítko).

Ak je parametrom výraz, bude tento najprv vyhodnotený a až následne bude jeho výsledok vypísaný na obrazovku. Výsledok posledne vypísaného výrazu sa bude následne nachádzať v špeciálnej premennej last.

Pre načítanie hodnoty zo štandardného vstupu je možné použiť štandardnú funkciu read(). Jej použitie ilustruje nasledovný príklad:
print "Zadaj zakladnu trojuholnika: "
a=read()
print "Zadaj vysku trojuholnika: "
va=read()
print "Obsah trojuholnika je ", a*va/2
Funkcia read() prečíta zo vstupu číslo v závislosti od nastavenia špeciálnej premennej ibase.

Skriptovanie v jazyku bc

Napísané skripty v jazyku bc je možné ukladať do samostatných súborov s príponou .bc (kvôli zvýrazňovaniu syntaxe vo vašom najobľúbenejšom editore (vim) a kvôli jednoduchej identifikácii jazyka, v ktorom bol skript napísaný). Spustiť takto napísaný skript je možné dvoma spôsobmi.

Prvý spôsob znamená spustiť interpreter jazyka s parametrom s názvom súboru, ktorý má interpretovať. Ak teda posledný príklad na výpočet obsahu trojuholníka uložíme do súboru triangle.bc, je možné ho z príkazového riadku spustiť nasledovne:

$ bc triangle.bc
Tu však pozor! Po vykonaní programu sa totiž interpreter jazyka bc neukončí, ale zostane aj naďalej v interaktívnom režime. Toto naozaj nie je chyba, ale vlastnosť, o ktorej sa dočítate v prvom odstavci manuálovej stránky v časti Description. Manuálová stránka teda hovorí, že po spracovaní všetkých vstupných súborov a ich vykonaní bude bc naďalej čítať vstup zo štandardného vstupu. Ak však nechcete, aby po vykonaní vášho programu bc zostal v interaktívnom režime, použite príkaz halt. Akonáhle interpreter dosiahne riadok s týmto príkazom, ukončí sa.

Druhý spôsob, ktorý je možné použiť na spúšťanie skriptov napísaných v jazyku bc, je spraviť zo súboru s kódom spustiteľný súbor s použitím príkazu chmod:
$ chmod +x triangle.bc
To však ale nie je všetko. Aby všetko pracovalo tak, ako má, je potrebné pridať do vášho súboru prvý (!) riadok, ktorý bude identifikovať umiestnenie interpretra jazyka bc v systéme. Ak by sa totiž tento riadok v spustiteľnom skripte nenachádzal, bash alebo ktorýkoľvek iný interpreter príkazového riadku by ho pri spustení považoval za shell skript a pri pokuse o jeho vykonanie by došlo ku chybe. Podoba prvého riadku teda môže byť nasledovná:
#!/usr/bin/bc -ql
Ako je vidieť, bc bude rovno spustený v tichom režime a matematickou knižnicou, čím bude priamo nastavená špeciálna premenná scale na hodnotu 20.

Pri druhom spôsobe rovnako platí pravidlo o zotrvaní v interaktívnom režime po vykonaní programu. Preto nezabudnite ako posledný riadok programu uviesť príkaz halt.

Výpis programu na výpočet trojuholníka tak bude mať nasledovnú podobu:
#!/usr/bin/bc -ql
print "Zadaj zakladnu trojuholnika: "
a=read()
print "Zadaj vysku trojuholnika: "
va=read()
print "Obsah trojuholnika je ", a*va/2, "\n"
halt
Poznámka: Jazyk bc obsahuje aj tzv. pseudo príkaz s názvom quit. Tento príkaz funguje podobne ako príkaz halt – ukončí bc procesor. Rozdiel je však v tom, že príkaz halt ukončí bc vtedy, keď bude vykonaný, ale príkaz quit ukončí bc vtedy, keď je riadok, na ktorom sa tento príkaz nachádza, prečítaný. Vyskúšajte si vo svojom programe tieto dva fragmenty kódu:
if (0 == 1) halt # bc nebude ukončený, pretože halt nebude vykonaný
if (0 == 1 ) quit # bc bude ukončený, pretože tento riadok bol dosiahnutý (prečítaný)

Zápis komentárov

Jazyk bc obsahuje jednoriadkové a viacriadkové komentáre. Jednoriadkové komentáre začínajú znakom '#'. Čokoľvek, čo sa nachádza za týmto riadkom, bude interpreter ignorovať až do konca riadku. Takýto riadok sme už videli skôr v predchádzajúcom texte – jednalo sa o prvý riadok skriptu, ktorý identifikuje umiestnenie interpretera jazyka bc. Viacriadkový komentár začína znakmi /* a končí kombináciou znakov */. Jedná sa teda o rovnakú syntax ako v C-čkových jazykoch.

Podmienené vykonávanie

Konečne sa v našom krátkom predstavení jazyka bc dostávame ku jazykovým konštrukciám, ktoré riadia tok programu. Začneme podmieneným vykonávaním a teda príkazom if. Jeho všeobecná syntax sa ani v jazyku bc nelíši od štandardných programovacích jazykov: if ( expression ) statement1 [else statement2] Príkaz if vyhodnotí výraz expression a pokiaľ je jeho výsledok nenulový, vykoná sa príkaz statement1. V opačnom prípade sa vykoná statement2 (ktorý je však nepovinný). Použitie ilustruje nasledovný príklad:
a = 12; b = 24;
if( a > b ) print "a je vacsie\n" else print "b je vasie\n"
Ako je na príklade vidieť, znak ';' sa používa na oddeľovanie príkazov. Príkazy statement1 a statement2 môžu byť samozrejme zloženými príkazmi. Zložený príkaz zapíšete podobne ako v C-čkových jazykoch medzi zložené zátvorky '{' a '}'. bc požaduje striktnejšie dodržiavanie sytanxe ako ste možno zvyknutí z iných jazykov. Pokiaľ totiž chcete použiť vetvu else, musí sa pred ňou priamo nachádzať statement1. V opačnom prípade dôjde k syntaktickej chybe. Podobne je to aj pri použití zloženého príkazu – pred kľúčovým slovom else sa musí nachádzať aspoň uzatváracia zložená zátvorka. Výraz expression môže byť samozrejme tvorený kompozíciou viacerých výrazov. Jazyk pozná štandardné relačné operátory <, >, <=, >=, !=, ==. Rovnako je vo výrazoch možné použiť boolean operácie !, && a ||. Priorita operátorov však v jazyku bc pracuje inak ako môžete byť zvyknutí z iných jazykov (viď manuálová stránka). Podľa odporúčania manuálovej stránky je vhodné najmä v prípade použitia relačných operátorov využiť zátvorky. Možný problém ilustruje nasledujúci príklad:
a=3<5
1
a
3
a=(3<5)
a
1

Tvorba vlastných funkcií

V jazyku bc je možné definovať aj vlastné funkcie, čím naozaj vieme vytvoriť „programovateľnú kalkulačku“. Funkcie v bc vždy vracajú hodnotu. Je ich možné definovať dynamicky, čo znamená, že funkcia začne existovať vtedy, keď na jej definíciu narazí pri vykonávaní interpreter. Funkcia tiež môže byť preddefinovaná neskôr, čo znamená, že jej nová definícia nahradí tú starú. Príklad definície funkcie na zistenie najväčšieho spoločného deliteľa pomocou Euklidovho algoritmu je nasledovný:
define gcd( a, b ){
   if( b == 0 )
       return a;
   return gcd( b, a%b );
}
Funkcia sa volá pomocou jej mena a uvedenia potrebných parametrov. Ak teda chceme volať práve zadefinovanú funkciu, môže volanie vyzerať nasledovne:
a=42;
b=56;
print "najvacsi spolocny delitel cisiel ", a, " a ", b, " je ", gcd(a,b), "\n";
najvacsi spolocny delitel cisiel 42 a 56 je 14
Pokiaľ má funkcia ako parameter prevziať pole, je potrebné pri jej definícii použiť notáciu názov[]. Jazyk bc rozpoznáva globálne a lokálne premenné v kontexte zadefinovanej funkcie. Ak chcete vo funkcii používať lokálne premenné (platné len v danej funkcii), je potrebné ich všetky hneď na prvom riadku v tele funkcie vymenovať. Tento riadok musí začať kľúčovým slovom auto, za ktorým sa bude nachádzať zoznam názvov týchto premenných oddelených čiarkami. V opačnom prípade je takáto premenná považovaná za globálnu.

Práca s cyklami

V jazyku bc je možné použiť použiť logické cykly while() a for(). Oba príkazy fungujú podobne ako v jazyku C. Rovnako tak je možné použiť príkazy break a continue na riadenie behu cyklu. Použitie cyklu ilustruje nasledujúci príklad na výpočet faktoriálu čísla x:
define fact (x) {
   auto result;
   result = 1;
   while(x>1)
       result *= x--;
   return (result);
}

Záver

Jazyk bc poskytuje naozaj možnosti, ktorými viete obohatiť funkcionalitu vašich bash skriptov. Otázkou už len zostáva, kde končí bc, a kde začína niečo komplexnejšie ako napr. Python alebo Octave. Základné znalosti použitia tohto jazyka sa však pri každodennom shell skriptingu naozaj zídu.

Použitá literatúra

    • RE: Programovateľná kalkulačka bc 11.01.2014 | 18:17
      Avatar skolak   Návštevník

      No zaujimave ze clovek chce spocitat trojhuolnik zo skoly, a pride sem ale na vypocet trojuholnika su krajsie kalkulačky.