.\" .\" bc.1 - the *roff document processor source for the bc manual .\" .\" This file is part of bc written initially for MINIX. .\" Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License , or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; see the file COPYING. If not, write to .\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. .\" .\" You may contact the author by: .\" e-mail: phil@cs.wwu.edu .\" us-mail: Philip A. Nelson .\" Computer Science Department, 9062 .\" Western Washington University .\" Bellingham, WA 98226-9062 .\" .\" .TH bc 1 .\" "Kézikönyv" v1.03 "Nov 2, 1994" .SH NÉV bc \- Lebegőpontos kalkulátor nyelv .SH ÁTTEKINTÉS \fBbc\fR [ \fB-lws\fR ] [ \fI fájl ...\fR ] .SH VERZIÓ Ez a kézikönyv lap a GNU bc 1.03-as verzióját írja le. .SH LEÍRÁS \fBbc\fR egy olyan nyelv, amely lebegőpontos számolást nyújt, interaktív végrehajtással. Van némi hasonlóság a C programozási nyelvvel. Egy standard matematikai könyvtár megadható parancssor paraméterként. Ha szükséges, a matematikai könyvtárat definiálni kell, mielőtt bármilyen más fájlt feldolgoznánk. A \fBbc\fR a megadott fájlokban levő kódot a megadás sorrenjében dolgozza fel. Miután minden fájlt feldolgozott a \fBbc\fR a szabványos bemenetről vár további utasításokat. Minden kódot a beolvasás pillanatában végrehajt. (Ha egy fájlban olyan utasítás található, amely megállítja a feldolgozót, a \fBbc\fR nem fog a szabványos bemenetről olvasni. .PP A \fBbc\fR ezen implementációja sok bővítéssel rendelkezik a POSIX standardhoz képest. Parancssor opcióval megadható, hogy a program ezeknél figyelmeztessen, vagy dobja vissza őket. Ez a dokumentum az ezen feldolgozó által elfogadott nyelvet írja le. A kiterjesztések természetesen jelölésre kerülnek. .SH OPCIÓK .IP -l Definiálja a standard matematikai könyvtárat. .IP -w Figyelmeztet a POSIX \fBbc\fR-hez képest használt kiterjesztésekre. .IP -s Csak a pontos POSIX \fBbc\fR nyelvet dolgozza fel. .SH SZÁMOK A \fBbc\fR legalapvetőbb eleme a szám. A számok pontossága bármekkora lehet. Ez a pontosság mind az egész, mind a tört részre vonatkozik. Minden szám belsőleg decimálisan tárolódik, és a számítások is decimálisan hajtódnak végre. (Ez a verzió az osztásnál és a szorzásnál csonkít.) A számoknak két jellemzője van, a hossz és a lépték. A hossz a szignifikáns decimális számjegyek számát jelenti, a lépték pedig a tizedspont után levőkét. Például: .nf .RS .000001 számnak a hossza és a léptéke is 6. míg az 1935.000 számnak a hossza 7, a léptéke 3. .RE .fi .SH VÁLTOZÓK A számokat két fajta változóban lehet tárolni, egyszerű változóban vagy tömbben. Mind az egyszerű, mind a tömbváltozónak van neve. A neveknek betűvel kell kezdődniük, ezt követhetik számok, betűk vagy aláhúzások. Minden betűnek kisbetűnek kell lennie. (A teljes alfanumerikus nevek már egy kiterjesztés. A POSIX \fBbc\fR-ben minden név egy kisbetűből áll.) A változó típusa a kontextusból tisztán kiderül, mivel minden tömb változót egy szögletes zárójel pár ([]) követ. .PP Négy speciális változó van, \fBscale, ibase, obase,\fR és \fBlast\fR. A \fBscale\fR azt definiálja, hogy néhány művelet a tizdes pont után hány számjegyet használjon. A \fBscale\fR alapértelmezett értéke 0. Az \fBibase\fR és az \fBobase\fR definiálja a bemeneti és a kimeneti számrendszer konverziót. Az alapértelmezett számrendszer mind a bemenetre, mind a kimenetre 10-es. A \fBlast\fR (kiterjesztés) változóban az utolsó kiírt érték szerepel. Ez később kerül részletezésre. Ezeknek vátlozóknak lehet értéket adni, de kifejezésben is használhatóak. .SH MEGJEGYZÉS A megjegyzések a \fBbc\fR-ben a \fB/*\fR karakterekkel kezdődnek és a \fB*/\fR karakterek jelzik a végét. A megjegyzések bárhol megjelenhetnek, és a bemenetben egy szóközt jelentenek. (Ez azt jelenti, hogy a megjegyzések elhatárolnak más objektumokat. Például, egy megjegyzés nem lehet egy változónév közepén.) A megjegyzésekben bármennyi újsor lehet (sor vége), a megjegyzés kezdete és vége között. .SH KIFEJEZÉSEK A számokat kifejezésekkel és utasításokkal lehet manipulálni. Mivel a nyelvet interaktívra készítették, az utasítások és a kifejezések rögtön végrehajtódnak. Nincs "fő" program (main függvény). A kód olyan sorrendben hajtódik végre, ahogy a \fBbc\fR beolvassa. (A függvények, később kerülnek leírásra, a beolvasás sorrendjében kerülnek definiálásra.) .PP Egy egyszerű kifejezés egy konstans. A \fBbc\fR a konstanst az \fBibase\fR változóban megadott bemeneti számrendszer szerint decimális számmá konvertálja. (Kivétel a függvényeknél.) Az \fBibase\fR érvényes értékei 2-től 16-ig terjednek. Ezen a határon túli értéket megadva az \fBibase\fR változónak, a változó értéke 2 vagy 16 lesz. A bemenő számok a 0-9-ig és az A-F-ig terjedő karaktereket tartalmazhatják. (Megjegyzés: Nagybetűknek kell lenniük. A kisbetűk a változóknak vannak fenntartva.) Az egy számjegyű számoknak mindig a számjegy az értéke, az \fBibase\fR változótól függetlenül (pl.: A = 10). A több számjegyű számoknál a \fBbc\fR az \fBibase\fR-nél nagyobb számjegyeket \fBbc\fR - 1-re cseréli. Ezáltal, a \fBFFF\fR mindig a lehetó legnagyobb háromjegyű számot jelenti. .PP A teljes kifejezések hasonlóak a többi magas szintű nyelvben levőkhöz. Mivel csak egyetlen típusú szám van, nincs szabály a típusok keverésének kezelésére. Minden kifejezésnek van egy pontossága. Ez az eredeti számokból, az elvégzett műveletekból és még sok egyébből tevődik össze, az értéke a \fBscale\fR változóban található. Ezen változó legális értékei a 0-tól a C nyelvben egész számnak megadható legnagyobb értékig terjednek. .PP Itt következik a legalis kifejezések leírása, az "expr" a teljes kifejezésre, a "var" pedig egy egyszerű, vagy egy tömb változóra vonatkozik. Egy egyszerű változóra a .RS \fIname\fR .RE míg egy tömbre a .RS \fIname\fR[\fIexpr\fR] .RE leírásával hivatkozhatunk. Hacsak másként nem specifikáljuk, az eredmény pontossága a kifejezések pontosságának a maximuma lesz. .IP "- expr" Az eredmény a kifejezés negáltja. .IP "++ var" A változó értéke eggyel nő, és az eredmény a változó új értéke lesz. .IP "-- var" A változó értéke eggyel csökken, és az eredmény a változó új értéke lesz. .IP "var ++" A kifejezés eredménye a változó eredeti értéke, majd a változó értéke nő eggyel. .IP "var --" A kifejezés eredménye a változó eredeti értéke, majd a változó értéke csökken eggyel. .IP "expr + expr" Az eredmény a két kifejezés összege. .IP "expr - expr" Az eredmény a két kifejezés különbsége. .IP "expr * expr" Az eredmény a két kifejezés szorzata. .IP "expr / expr" Az eredmény a két kifejezés hányadosa. Az eredmény pontosságát a \fBscale\fR változó értéke határozza meg. .IP "expr % expr" Az eredmény a "maradék", amely a következőképpen kerül kiszámolásra. Az a%b kiszámolásához először, kiszámolásra kerül az a/b, \fBscale\fR számjegyre. Az eredmény a következőképpen adódik: a-(a/b)*b, a pontossága a \fBscale\fR+scale(b) és scale(a) közül a nagyobb lesz. Ha a \fBscale\fR egyenlő nullával, vagy mindkét kifejezés egész, a maradék is egész lesz. .IP "expr ^ expr" Az eredmény az első kifejezés a másodikra emelve. A második kifejezésnek egésznek kell lennie. (Ha a második kifejezés nem egész, egy figyelmeztetés generálódik, és az érték egész értékre csonkolódik.) Az eredmény pontossága \fBscale\fR lesz, ha a kitevő negatív. Ha a kitevő pozitív, az eredmény pontossága az első kifejezés pontosságának és a kitevő értékének a szorzata és - az első kifejezés és a \fBscale\fR változó értéke közül a nagyobb - közül a kisebb lesz. (Pl. scale(a^b) = min(scale(a)*b, max( \fBscale,\fR scale(a))).) Megjegyezendő, hogy az expr^0 mindig 1 értékkel tér vissza. .IP "( expr )" Ez megváltoztatja a kifejezés kiértékelésének standard precedenciáját. .IP "var = expr" A változó értéke a kifejezés lesz. .IP "var = expr" Ez ekvivalens a "var = var expr" kifejezéssel, azzal a kivétellel, hogy a "var" rész csak egyszer értékelődik ki. Ez akkor okozhat különbséget, ha a "var" egy tömb. .PP A relációs kifejezések speciális kifejezés fajták, amelyek mindig 0-t, vagy 1-et adnak vissza, 0-át, ha a reláció hamis, és 1-et, ha igaz. Ezek bármilyen legális kifejezésben megjelenhetnek. (A bc POSIX változatában, hogy a relációs kifejezések csak if, while és for utasításokban szerepelhetnek, illetve csak egy tesztelésük lehetséges.) A relációs operátorok a következők: .IP "expr1 < expr2" Az eredmény 1, ha az expr1 kisebb, mint az expr2. .IP "expr1 <= expr2" Az eredmény 1, ha az expr1 kisebb, vagy egyenlő, mint az expr2. .IP "expr1 > expr2" Az eredmény 1, ha az expr1 nagyobb, mint az expr2. .IP "expr1 >= expr2" Az eredmény 1, ha az expr1 nagyobb, vagy egyenlő, mint az expr2. .IP "expr1 == expr2" Az eredmény 1, ha az expr1 egyenlő az expr2-vel. .IP "expr1 != expr2" Az eredmény 1, ha az expr1 nem egyenlő az expr2-vel. .PP A boolean műveletek is legálisak. ( A POSIX \fBbc\fR-ben nincsenek boolean műveletek.) Minden boolean műveletnek az értéke 0, vagy 1 (hamis, vagy igaz), mint a relációs műveleteknél. A boolean műveletek a következőek: .IP "!expr" Az eredmény 1, ha a kifejezés 0. .IP "expr && expr" Az eredmény 1, ha a mindkét kifejezés nem 0. .IP "expr || expr" Az eredmény 1, ha a bármelyik kifejezés nem 0. .PP A kifejezések precedenciája a következő (alacsonytól a magas felé): .nf .RS || operátor, balról asszociatív && operátor, balról asszociatív ! operátor, nem asszociatív Relációs operátorok, balról asszociatív Értékadó operátor, jobbról asszociatív + és - operátorok, balról associative *, / és % operátorok, balról asszociatív ^ operátor, jobbról asszociatív unáris - operátor, nem asszociatív ++ és -- operátorok, nem asszociatív .RE .fi .PP Ez a precedencia úgy van megválasztva, hogy a POSIX \fBbc\fR alá programok is korrekten fussanak. Emiatt, a relációs és logikai operátorokat az értékadó operátoroknál néha szokatlan eredmény is kijöhet. Lásd a következő kifejezést: .RS a = 3 < 5 .RE .PP A legtöbb C programozó ezt úgy értelmezi, hogy a "3 < 5" (az értéke 1) kerül az "a" változóba. A \fBbc\fR itt a következőt csinálja, hozzárendeli a 3-at az "a" változóhoz, majd a 3-at összehasonlítja az 5-tel. A legjobb, hogyha értékadó operátort használsz relációs, és logikai operátorokkal, akkor használsz zárójeleket. .PP Van néhány egyéb speciális kifejezés, amelyet még a \fBbc\fR nyújt. Ezek a felhasználó által definiálható függvények, és a standard függvények hívása. Ezek a következő alakban jelennek meg: \fIname\fB(\fIparameters\fB)\fR A függvényekhez lásd még a felhasználó által definiált függvények fejezetet. A standard függvények a következőek: .IP "length ( expression )" A length függvény értéke a kifejezésben megadott szám értékes jegyeinek száma. .IP "read ( )" A read függvény (kiterjesztés) beolvas egy számot a szabványos bemenetről, függetlenül attól, hogy a függvény hol található. Figyelmeztetés: ez problémát okozhat, ha mind a program, mind az adatok a standard bementről jönnek. A legjobb, ha ezt a függvényt csak előre megírt programoknál használjuk, amely adatokat kér a felhasználótól, de nem engedi meg, hogy a felhasználó program kódot is beírjon. A read függvény értéke a szabványos bemenetről beolvasott szám értéke, az \fBibase\fR változó értékét, mint számrendszert használva a konverzió alapjául. .IP "scale ( expression )" A scale függvény értéke a kifejezés tizedespont mögött szereplő számjegyeinek száma. .IP "sqrt ( expression )" Az sqrt függvény értéke a kifejezés értékének a négyzetgyökével egyenlő. Ha a kifejezés negatív, egy futási hiba generálódik. .SH UTASÍTÁSOK Az utasítások (mint a legtöbb algebrai nyelvnél) határozzák meg a kifejezések kiértékelésének sorrendjét. A \fBbc\fR-ben az utasítások akkor hajtódnak végre, amint "arra mód van". A végrehajtás akkor történik meg, mikor az interpreter új sor karakterrel találkozik, illetve, mikor egy, vagy több komplett utasítás felépül. Ezen azonnali végrehajtás miatt, az újsorok nagyon fontosak a \fBbc\fR-ben. Valójában, mind a pontosvessző, mind az újsor használható utasításelválasztóként. Egy rossz helyre rakott újsor szintaktikai hibát okoz. Mivel az újsorok utasítás elhatárolók, el lehet őket rejteni, a backslash karakter segítségével. A "\e" karaktersorozattal, ahol az az újsort jelenti, az újsor csak egy szóközként jelenik meg a \fBbc\fR-ben. Egy utasítás lista a pontosvesszővel, vagy újsorral elválasztott utasítások sorozata. Itt következnek a \fBbc\fR utasításai, és az, hogy mit csinálnak: (A szögletes zárójelbe ([]) zárt részek az utasításból elhagyhatóak.) .IP "expression" Ez az utasítás kétféle képpen is megjelenhet. Az egyik, mikor a kifejezés " <értékadás> ...", ez egy értékadási utasítás. Ha a kifejezés nem értékadási utasítás, akkor kiértékelése után kapott eredmény kiírásra kerül a szabványos kimenetre. A szám kiírása után egy újsor is kiírásra kerül. Például, az "a=l" egy értékadási utasítás, míg az "(a=l)" egy kifejezés, amelyben van egy értékadás. Minden szám az \fBobase\fR változóban tárolt számrendszer alapján kerül kiírásra. Az \fBobase\fR változó legális értékei 2-től a BC_BASE_MAX konstansban tárolt értékig mehetnek. (Lásd még a HATÁRÉRTÉKEK fejezetet.) A 2-estől a 16-os számrendszerig a számok kiírása a szokásos módon történik. 16-osnál nagyobb számrendszereknél a \fBbc\fR több karakterből álló számjegyeket használ, ahol minden magasabb számrendszerbeli számjegynek a tizes számrendszerbeli számképe íródik ki. A több karakteres számjegyeket egymástól a program szóközökkel választja el. Minden számjegy annyi karakterből áll, amennyi az "obase-1" szám kiírásához kell, 10-es számrendszerben. Mivel a számok változó pontosságúak, előfordulhat, hogy néhány szám kiírása nem fér ki egy sorba. Ezeket a hosszú számokat a program sorokra tördeli, a sorok végén egy-egy "\e" karakterrel. Az egy sorba kiírt karakterek maximális száma 70. A \fBbc\fR interaktivitása miatt, az utolsó kiírt számot eltárolja egy speciális változóban. Így az utoljára kiírt szám megkapásához nem szükséges újra leírni az egész kifejezést, hanem csak a \fBlast\fR változó értékét kell előszedni. A \fBlast\fR változónak értéket is lehet adni, ez esetben a benne tárolt utolsó érték egyszerűen felülíródik. Ez az érték addig marad meg benne, amíg a következő szám kiírásra nem kerül, vagy más értéket nem adnak neki. (Némelyik implementáció megengedi, hogy a \fBlast\fR változóra egy egyedüli ponttal ("."), amely nem része számnak, hivatkozzunk.) .IP "string" A string a kimenetre íródik ki. A stringek idézőjellel kezdődnek, és bármilyen karaktert tartalmazhatnak a következő idézőjelig. Egyetlen karakter sem kerül értelmezésre, még az újsor karakter sem. A string kiírása után nem íródik ki újsor karakter. .IP "\fBprint\fR list" A print utasítás (kiterjesztés), a kiírás egy újabb módozatát kínálja. A "list" egy string és kifejezés lista, vesszővel elválasztva. Minden string vagy kifejezés a lista sorrendjében íródik ki. Záró újsor nem íródik ki. A kifejezések kiértékelődnek, és az eredményük a \fBlast\fR változóban tárolásra kerül. A stringek pedig egyszerűen kiírásra kerülnek, speciális karaktereket is tartalmazhatnak. A speciális karakterek a backslalsh karakterrel kezdődnek (\e). A speciális karakterek a következőek: "a" (figyelmeztetés, vagy bip), "b" (backspace), "f" (lapdobás), "n" (újsor), "r" (kocsi vissza), "q" (idézőjel), "t" (tabulátor) és "\e" (backslash). Minden más, a backslash után levő karaktert figyelmen kívül hagy a program. .IP "{ utasítás_lista }" Ez egy összetett utasítás. Ennek segítségével lehet több végrehajtandó utasítást egybekapcsolni. .IP "\fBif\fR ( kifejezés ) \fBthen\fR utasítás1 [\fBelse\fR utasítás2]" Az if kiértékeli a kifejezést, és végrehajtja az utasítás1-et, vagy az utasítás2-t, a kifejezés értékétől függően. Ha a kifejezés eredménye nem nulla, az utasítás1 hajtódik végre. Ha az utasítás2 létezik, és a kifejezés eredménye nulla, az utasítás2 hajtódik végre. (Az else ág kiterjesztés.) .IP "\fBwhile\fR ( kifejezés ) utasítás" A while utasítás mindaddig végrehajtja az utasítást, amíg a kifejezés eredménye nem nulla. Az utasítás minden végrehajtása előtt kiértékeli a kifejezést. A ciklus akkor fejeződik be, ha a kifejezés eredménye nulla lesz, vagy ha végrehajtódik egy break utasítás. .IP "\fBfor\fR ( [kifejezés1] ; [kifejezés2] ; [kifejezés3] ) utasítás" A for utasítás egy utasítás ismételt végrehajtását vezérli. A kifejezés1 a ciklus előtt kiértékelődik. A kifejezés2 az utasítás minden végrehajtása előtt kiértékelődik. Ha nem nulla, az utasítás végrehajtódik, ha nulla, a ciklus véget ér. Az utasítás minden végrehajtása után, a kifejezés3 kiértékelődik, mielőtt a kifejezés2 kiszámolódna. Ha a kifejezés1 és a kifejezés3 hiányzik, a kiértékelődésük helyén semmi nem fog történni. Ha a kifejezés2 hiányzik, az olyan, mintha a kifejezés2 helyén egy olyan kifejezés lenne, amelynek az eredménye mindig 1. (Az opcionális kifejezések egy kiterjesztés.) A következő ekvivalens kódokat ad a for utasításra: .nf .RS kifejezés1; while (kifejezés2) { utasítás; kifejezés3; } .RE .fi .IP "\fBbreak\fR" Ezzel az utasítással ki lehet lépni a legbelső while, vagy for utasításból. .IP "\fBcontinue\fR" Ez az utasítás (kiterjesztés) azt eredményezi, hogy a legbelső for utasítás egy új ciklust kezd. .IP "\fBhalt\fR" Ez az utasítás (kiterjesztés), ha végrehajtódik, azt eredményezi, hogy a \fBbc\fR kilép. .IP "\fBreturn\fR" Nulla értékkel tér vissza egy függvényből (lásd még a függvények fejezetet). .IP "\fBreturn\fR ( expression )" A kifejezés eredményével tér vissza a függvényből (lásd még a függvények fejezetet). .SH PSZEUDO UTASÍTÁSOK Ezek az utasítások a tradicionális értelemben nem utasítások. Nem hajtódnak végre. Funkciójukat "fordítási" időben fejtik ki. .IP "\fBlimits\fR" Kiírja a \fBbc\fR adott verziója által használt határokat. Kiterjesztés. .IP "\fBquit\fR" Ha a quit utasítást beolvassa, a \fBbc\fR feldolgozó kilép. Nem számít, hogy az utasítás hol található (pl. az "if (0 == 1) quit" hatására is kilép a \fBbc\fR.) .IP "\fBwarranty\fR" Kiírja a figyelmeztető üzenetet. Kiterjesztés. .SH FÜGGVÉNYEK A függvényekkel definiálhatunk számításokat, amelyeket csak később kívánunk végrehajtani. A függvények a .B bc -ben mindig egy értéket számolnak, és azt visszaadják a hívónak. A függvény definíciója "dinamikus" abban az értelemben, hogy mindaddig definiálatlan, amíg a feldolgozó nem találkozik vele a bemeneten. Ez a definícó mindaddig használható, amíg egy ugyanezen névű függvény definicóval nem találkozik. Az új definíció felülírja a régit. Egy függvény definíciója a következőképpen néz ki: .nf .RS \fBdefine \fIname \fB( \fIparameters \fB) { \fInewline \fI auto_list statement_list \fB}\fR .RE .fi A függvényhívás is egy kifejezés, a következő formában: "\fIname\fB(\fIparameters\fB)\fR". .PP A paraméterek számok, vagy tömbök lehetnek (kiterjesztés). A függvény definícójában nulla, vagy több paraméter definiálható, vesszővel elválasztva. A számok csak érték szerinti átadással, a tömbök csak cím szerinti átadással hívódnak meg. A tömböket a paraméterek között a "\fInév\fB[]\fR" módon kell specifikálni. A függvényhívásnál a szám paraméterek teljes kifejezések lehetnek. A tömböknél ugyanaz a jelölés használandó, mint a definiáláskor. A nevesitett tömbök cím szerinti átadással kerülnek a függvényhez. Mivel a függvény definíciója dinamikus, a paraméterek száma és típusa csak a hívás pillanatában kerül ellenőrzésre. Ha ebben eltérés mutatkozik, egy futási-hiba váltódik ki. Futási-hiba váltódik ki akkor is, ha egy nem létező függvényt hívunk meg. .PP Az \fIauto_list\fR egy opcionális változó lista, amely "helyi" változókat tartalmazza. A szintaxisa: "\fBauto \fInév\fR, ... ;". (A pontosvessző opcionális.) Minden \fInév\fR egy auto változó neve. Tömbök is definiálhatóak így, a szokásos módon. Ezek a változók a vermen kapnak helyet, a függvény belépése után. A változók ezután inicializálásra kerülnek nulla kezdőértékkel, és a függvény végrehajtása során használhatóak. Amikor a függvény kilép, ezeket a változókat eltávolítja a veremből, így az eredeti értékük helyreállítódik. A paraméterek is auto változók, amelyek a függvény meghívásakor kapják meg értéküket. Az auto változók különböznek a tradícionális helyi változóktól a következő dologban: ha A meghívja a B függvényt, B látja az A auto változóit, hacsak B-ben nincs ugyanezen néven is auto változó definiálva. Azon tény miatt, hogy az auto változók és a paraméterek egy vermen kapnak helyet, a \fBbc\fR kezeli a rekurzív függvényeket is. .PP A függvény törzse \fBbc\fR utasítások listája. Az utasításokat pontosvesszők, vagy újsorok választják el. A return utasítás hatására a függvény végrehajtása véget ér, és visszatér egy értékkel. Az első forma, a "\fBreturn\fR", 0-át ad vissza a hívónak, míg a második, "\fBreturn ( \fIkifejezés \fB)\fR", kiértékeli a kifejezést, és az eredményt adja vissza. A függvény végén, ha mást nem írunk ki, mindig van egy "\fBreturn (0)\fR", ez megkímél attól, hogy explicite ki kelljen írni a return utasítást. .PP A függvényeknél megváltozik az \fBibase\fR változó használata is. A függvény törzsében szereplő minden konstans, a függvény hívásakor használatos \fBibase\fR alapján konvertálódik. Ha az \fBibase\fR-t megváltoztatjuk egy függvényben, annak nem lesz hatása, kivéve a \fBread\fR standard függvényt, amely mindig az \fBibase\fR aktuális értékét használja a számok konvertálásához. .SH MATEMATIKAI KÖNYVTÁR Ha a \fBbc\fR-t a \fB-l\fR opcióval indítjuk, a matematikai könyvtár betöltődik, és a pontosság 20-as lesz. A matematikai függvények azzal a pontossággal számolják ki az eredményt, amely a meghívásukkor be volt állítva. A matematikai könyvtár a következő függvényeket definiálja: .IP "s (\fIx\fR)" Az x (radián) színusza. .IP "c (\fIx\fR)" Az x (radián) koszínusza. .IP "a (\fIx\fR)" Az x arkusz tangense. .IP "l (\fIx\fR)" Az x természetes logaritmusa. .IP "e (\fIx\fR)" Az e x-edik hatványa. .IP "j (\fIn,x\fR)" Az n-ed rendű Bessel fuggvenye x-nek. .SH PÉLDÁK A /bin/sh-ban a következő utasítás visszaadja a "pi" értékét a \fBpi\fR környezeti változóban. .RS \f(CW pi=$(echo "scale=10; 4*a(1)" | bc -l) \fR .RE .PP Az itt következő példában a matematikai könyvtárban található hatvány függvény definícióját mutatjuk be. A függvény POSIX \fBbc\fR nyelven íródott. .nf .RS \f(CW scale = 20 /* Kihasználja a következó tényt: e^x = (e^(x/2))^2. Mikor az x elég kicsi, a következő sort használjuk: e^x = 1 + x + x^2/2! + x^3/3! + ... */ define e(x) { auto a, d, e, f, i, m, v, z /* Ellenőrzi az x előjelét. */ if (x<0) { m = 1 x = -x } /* Elófeltétel. */ z = scale; scale = 4 + z + .44*x; while (x > 1) { f += 1; x /= 2; } /* Inicializálja a változókat. */ v = 1+x a = x d = 1 for (i=2; 1; i++) { e = (a *= x) / (d *= i) if (e == 0) { if (f>0) while (f--) v = v*v; scale = z if (m) return (1/v); return (v/1); } v += e } } \fR .RE .fi .PP A következő kód a \fBbc\fR kiterjesztett szolgáltatásait használja, egy egyszerű csekkfüzet egyenleg kiszámolására. Legjobb, ha ezt a programot fájlba lementjük, hogy többször is használhassuk anélkül, hogy újra be kelljen gépelni. .nf .RS \f(CW scale=2 print "\enCsekkfüzet program!\en" print " Emlékeztető, a letétek negatív tranzakciók.\en" print " Kilépés 0 összegű tranzakció bevitelével.\en\en" print "Kezdeti egyenleg? "; bal = read() bal /= 1 print "\en" while (1) { "jelenlegi egyenleg = "; bal "tranzakció? "; trans = read() if (trans == 0) break; bal -= trans bal /= 1 } quit \fR .RE .fi .PP A következő függvény a faktoriális rekurzív definíciója. .nf .RS \f(CW define f (x) { if (x <= 1) return (1); return (f(x-1) * x); } \fR .RE .fi .SH ELTÉRÉSEK A .B bc ezen verziója a POSIX P1003.2/D11 tervezete alapján készült és a tervezethez és a tradícionális implementációhoz képest sok bővítést és különbséget tartalmaz. Ez nincs implementálva a tradícionális .I dc(1)-ben. Ez a verzió egy egyszerű feldolgozó, amely csak átfordítja a programot. Egy "nem dokumentált" kapcsoló (-c) kiírja az átfordított programot a szabványos kimenetre, és nem futtatja le. Ez főleg az értelmező nyomkövetésekor és a matematikai könyvtár előkészítésekor használatos. .PP A különbségek legfőbb forrásai a kiterjesztések, hol egy szolgáltatás lett kiterjesztve, hogy több lehetősége legyen, hol pedig új szolgáltatás lett létrehozva. A következó lista megmutatja a különbségeket és a kiterjesztéseket. .IP "LANG környezeti változó" Ez a verzió nem követi a POSIX szabványt a LANG környezeti változó használatában, és minden környezeti változó az "LC_" prefixszel kezdődik. .IP nevek A tradícionális és a POSIX .B bc -ben a funkciók, változók és tömbök nevei csak egy karakter hosszúak lehettek. Itt már több karaktert is használhatunk, de a neveknek betűvel kell kezdődni és csak betűket számokat és aláhúzásjeleket tartalmazhatnak. .IP Stringek A stringek nem tartalmazhatnak NUL (ASCII nulla) karaktert. A POSIX szerint bármilyen karakter lehet egy stringben. .IP last A POSIX \fBbc\fR-ben nincs \fBlast\fR változó. Néhány implementáció a pontot (.) használja erre a célra. .IP összehasonlítások A POSIX \fBbc\fR csak az if, vagy a while utasításban enged meg összehasonlításokat, vagy a for utasítás második kifejezésében. Továbbá, utasításonként csak egy relációs operátor van megengedve. .IP "if utasítás, else ág" A POSIX \fBbc\fR-ben nincs else ág. .IP "for utasítás" A POSIX \fBbc\fR-ben minden kifejezésnek szerepelnie kell. .IP "&&, ||, !" A POSIX \fBbc\fR-ben nincsenek logikai operátorok. .IP "read függvény" A POSIX \fBbc\fR-ben nincs read függvény. .IP "print utasítás" A POSIX \fBbc\fR-ben nincs print utasítás. .IP "continue utasítás" A POSIX \fBbc\fR-ben nincs continue utasítás. .IP "tömb paraméterek" A POSIX \fBbc\fR-ben nincsenek tömb paraméterek. Más implementációkban lehetnek. .IP "=+, =-, =*, =/, =%, =^" A POSIX \fBbc\fR-ben nincs szükség ezekre a "régi stílusú" értékadó operátorokra. Ez a verzió megengedi ezeket. Használd a limits utasítást, hogy megtudd, hogy az installált verzió megengedi-e ezeket. Ha igen, az "a =- 1" kifejezés csökkenti az \fBa\fR értékét 1-gyel, egyébként pedig az \fBa\fR értékét beállítja -1-re. .IP "szóközök a számokban" A \fBbc\fR más implementációi megengedik szóközök használatát a számokban. Például, az "x=1 3" kifejezés az x változóhoz hozzárendeli a 13-at. Ebben a \fBbc\fR-ben ugyanez az utasítás szintaktikai hibát ad. .IP "hibák és végrehajtás" Ez az impelmentáció különbözik a többitől abban, hogy mely kódokat hajtja végre, mikor egy szintaktikai, vagy más hibába belefut. Ha egy szintaktikai hibát talál a függvény definíciójában, a hibakezelő megpróbálja megtalálni az utasítás elejét, és folytatni a függvény feldolgozását. Ha a szintaktikai hiba a függvény törzsében következik be, a függvény nem lesz definiálva, és nem lehet meghívni sem. Az interaktív végrehajtási blokkokban levő szintaktikai hibák érvénytelenítik az egész blokkot. Egy végrehajtási blokknak minősül az az utasítássor, amely a következő soremelésig tart. Például: .nf .RS a = 1 b = 2 .RE .fi ez két végrehajtási blokk és .nf .RS { a = 1 b = 2 } .RE .fi ez egy. A futási-hibák hatására a jelenlegi blokk végrehajtása befejeződik. A futási-figyelmezetetés nem állítja meg a blokk végrehajtását. .IP "Megszakítások" Egy interaktív végrehajtás során, a SIGINT szignál (általában a terminálról érkező Control-C karakter generálja) hatására a jelenlegi blokk végrehajtása megszakad. Kijelzésre kerül egy "futási" hiba, hogy melyik függvény lett megszakítva. Miután minden futási struktúra kiürül, egy üzenet kerül kiírásra a felhasználó felé, hogy a \fBbc\fR kész további adatok fogadására. Minden korábban definiált függvény továbbra is definiálva marad, és minden nem-auto változóban a megszakításkori érték lesz. Minden auto változó (a függvények paraméterei is) törlésre kerül a kiürítési eljárás során. Nem-interaktív végrehajtáskor a SIGINT szignál az egész \fBbc\fR futását megszakítja. .SH HATÁROK A következő határok vannak beépítve ebbe a .B bc -be. Néhányuk egy installálással megváltoztatható. Az aktuális értékeik megszerzéséhez használd a limits utasítást. .IP BC_BASE_MAX A legnagyobb kimeneti számrendszer, jelenleg 999. A maximum bemeneti számrendszer 16. .IP BC_DIM_MAX Ez a jelenlegi pontossági határ, 655535. Az ön installációjában más lehet. .IP BC_SCALE_MAX A tizedes pont előtti és utáni számjegyek számát az INT_MAX határozza meg. .IP BC_STRING_MAX A karakterek maximális száma egy stringben INT_MAX. .IP exponens A hatványozás operátor (^) kitevőjének maximum értékét a LONG_MAX határozza meg. .IP szorzás A szorzó rutin inkorrekt eredményt adhat, ha a számnak (LONG_MAX / 90)-nél több számjegye van. 32-bites long-nál ez 23,860,929 számjegy. .IP "kód méret" Minden függvénynek és a "fő" programnak is limitálva van a mérete 16384 byte lefordított kódban. Ez a határ (BC_MAX_SEGS) könnyen túlléphető, ha több, mint 16 1024 byte-os szegmensünk van. .IP "változó nevek" A jelenlegi limit az egyedi nevekre 32767 mind az egyszerű változókra, mind a tömbökre és a függvényekre. .SH FÁJLOK A legtöbb installációban a \fBbc\fR-nek nincs szüksége egyéb fájlokra. Míg a végrehajtható program hossza fontos, illetve a C fordító nem tudja kezelni a nagyon hosszú stringeket, a \fBbc\fR a standard matematikai könyvtárat a /usr/local/lib/libmath.b fájlból olvassa be. (A fájl helye rendszerenként változhat, lehet /lib/libmath.b is.) .SH DIAGNOSZTIKA Ha egy a parancssorban szereplő fájl nem nyitható meg, a \fBbc\fR üzen, hogy a fájl nem elérhető, és kilép. Ugyanígy, a fordítási és a futási idejű diagnosztika is önmagyarázó. .SH HIBÁK A hibakezelés még nem túl jó. .SH SZERZŐ .nf Philip A. Nelson phil@cs.wwu.edu .fi .SH KÖSZÖNETNYILVÁNÍTÁSOK A szerző szeretné megköszönni Setve Sommars-nak (Steve.Sommars@att.com), hogy oly nagy mértékben segített az implementáció tesztelésében. Sok nagyon jó tanácsot adott. Segítségével egy sokkal jobb terméket sikerült létrehozni. .SH MAGYAR FORDÍTÁS Csehi András