Ubuntu Manpages

ÁTTEKINTÉS

bc [ -lws ] [ fájl ... ]

Ez a kézikönyv lap a GNU bc 1.03-as verzióját írja le.

bc 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 bc a megadott fájlokban levõ kódot a megadás sorrenjében dolgozza fel. Miután minden fájlt feldolgozott a bc 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 bc nem fog a szabványos bemenetrõl olvasni.

A bc 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.

Definiálja a standard matematikai könyvtárat.
Figyelmeztet a POSIX bc-hez képest használt kiterjesztésekre.
Csak a pontos POSIX bc nyelvet dolgozza fel.

A bc 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:

 .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.

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 bc-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.

Négy speciális változó van, scale, ibase, obase, és last. A scale azt definiálja, hogy néhány mûvelet a tizdes pont után hány számjegyet használjon. A scale alapértelmezett értéke 0. Az ibase és az obase 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 last (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.

A megjegyzések a bc-ben a /* karakterekkel kezdõdnek és a */ 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.

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 bc beolvassa. (A függvények, késõbb kerülnek leírásra, a beolvasás sorrendjében kerülnek definiálásra.)

Egy egyszerû kifejezés egy konstans. A bc a konstanst az ibase változóban megadott bemeneti számrendszer szerint decimális számmá konvertálja. (Kivétel a függvényeknél.) Az ibase érvényes értékei 2-tõl 16-ig terjednek. Ezen a határon túli értéket megadva az ibase 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 ibase változótól függetlenül (pl.: A = 10). A több számjegyû számoknál a bc az ibase-nél nagyobb számjegyeket bc - 1-re cseréli. Ezáltal, a FFF mindig a lehetó legnagyobb háromjegyû számot jelenti.

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 scale 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.

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

name
míg egy tömbre a
name[expr]
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.
Az eredmény a kifejezés negáltja.
++ var
A változó értéke eggyel nõ, és az eredmény a változó új értéke lesz.
A változó értéke eggyel csökken, és az eredmény a változó új értéke lesz.
A kifejezés eredménye a változó eredeti értéke, majd a változó értéke nõ eggyel.
A kifejezés eredménye a változó eredeti értéke, majd a változó értéke csökken eggyel.
Az eredmény a két kifejezés összege.
Az eredmény a két kifejezés különbsége.
Az eredmény a két kifejezés szorzata.
Az eredmény a két kifejezés hányadosa. Az eredmény pontosságát a scale változó értéke határozza meg.
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, scale számjegyre. Az eredmény a következõképpen adódik: a-(a/b)*b, a pontossága a scale+scale(b) és scale(a) közül a nagyobb lesz. Ha a scale egyenlõ nullával, vagy mindkét kifejezés egész, a maradék is egész lesz.
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 scale 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 scale változó értéke közül a nagyobb - közül a kisebb lesz. (Pl. scale(a^b) = min(scale(a)*b, max( scale, scale(a))).) Megjegyezendõ, hogy az expr^0 mindig 1 értékkel tér vissza.
( expr )
Ez megváltoztatja a kifejezés kiértékelésének standard precedenciáját.
A változó értéke a kifejezés lesz.
Ez ekvivalens a "var = var <op> 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.


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:

Az eredmény 1, ha az expr1 kisebb, mint az expr2.
Az eredmény 1, ha az expr1 kisebb, vagy egyenlõ, mint az expr2.
Az eredmény 1, ha az expr1 nagyobb, mint az expr2.
Az eredmény 1, ha az expr1 nagyobb, vagy egyenlõ, mint az expr2.
Az eredmény 1, ha az expr1 egyenlõ az expr2-vel.
Az eredmény 1, ha az expr1 nem egyenlõ az expr2-vel.

A boolean mûveletek is legálisak. ( A POSIX bc-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:

!expr
Az eredmény 1, ha a kifejezés 0.
Az eredmény 1, ha a mindkét kifejezés nem 0.
Az eredmény 1, ha a bármelyik kifejezés nem 0.

A kifejezések precedenciája a következõ (alacsonytól a magas felé):

|| 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

Ez a precedencia úgy van megválasztva, hogy a POSIX bc 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:

a = 3 < 5

A legtöbb C programozó ezt úgy értelmezi, hogy a "3 < 5" (az értéke 1) kerül az "a" változóba. A bc 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.

Van néhány egyéb speciális kifejezés, amelyet még a bc 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: name(parameters) 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:

A length függvény értéke a kifejezésben megadott szám értékes jegyeinek száma.
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 ibase változó értékét, mint számrendszert használva a konverzió alapjául.
A scale függvény értéke a kifejezés tizedespont mögött szereplõ számjegyeinek száma.
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.

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 bc-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 bc-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 "\<nl>" karaktersorozattal, ahol az <nl> az újsort jelenti, az újsor csak egy szóközként jelenik meg a bc-ben. Egy utasítás lista a pontosvesszõvel, vagy újsorral elválasztott utasítások sorozata. Itt következnek a bc 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.)

Ez az utasítás kétféle képpen is megjelenhet. Az egyik, mikor a kifejezés "<változó> <é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 obase változóban tárolt számrendszer alapján kerül kiírásra. Az obase 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 bc 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 "\" karakterrel. Az egy sorba kiírt karakterek maximális száma 70. A bc 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 last változó értékét kell elõszedni. A last 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 last változóra egy egyedüli ponttal ("."), amely nem része számnak, hivatkozzunk.)
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.
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 last 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 (\). 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 "\" (backslash). Minden más, a backslash után levõ karaktert figyelmen kívül hagy a program.
{ utasítás_lista }
Ez egy összetett utasítás. Ennek segítségével lehet több végrehajtandó utasítást egybekapcsolni.
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.)
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.
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:
kifejezés1;
while (kifejezés2) {
   utasítás;
   kifejezés3;
}

Ezzel az utasítással ki lehet lépni a legbelsõ while, vagy for utasításból.
Ez az utasítás (kiterjesztés) azt eredményezi, hogy a legbelsõ for utasítás egy új ciklust kezd.
Ez az utasítás (kiterjesztés), ha végrehajtódik, azt eredményezi, hogy a bc kilép.
Nulla értékkel tér vissza egy függvénybõl (lásd még a függvények fejezetet).
A kifejezés eredményével tér vissza a függvénybõl (lásd még a függvények fejezetet).

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.

Kiírja a bc adott verziója által használt határokat. Kiterjesztés.
Ha a quit utasítást beolvassa, a bc 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 bc.)
Kiírja a figyelmeztetõ üzenetet. Kiterjesztés.

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 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:

define name ( parameters ) { newline
    auto_list   statement_list }

A függvényhívás is egy kifejezés, a következõ formában: "name(parameters)".

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 "név[]" 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.

Az auto_list egy opcionális változó lista, amely "helyi" változókat tartalmazza. A szintaxisa: "auto név, ... ;". (A pontosvesszõ opcionális.) Minden név 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 bc kezeli a rekurzív függvényeket is.

A függvény törzse bc 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 "return", 0-át ad vissza a hívónak, míg a második, "return ( kifejezés )", 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 "return (0)", ez megkímél attól, hogy explicite ki kelljen írni a return utasítást.

A függvényeknél megváltozik az ibase változó használata is. A függvény törzsében szereplõ minden konstans, a függvény hívásakor használatos ibase alapján konvertálódik. Ha az ibase-t megváltoztatjuk egy függvényben, annak nem lesz hatása, kivéve a read standard függvényt, amely mindig az ibase aktuális értékét használja a számok konvertálásához.

Ha a bc-t a -l 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:

s (x)
Az x (radián) színusza.
Az x (radián) koszínusza.
Az x arkusz tangense.
l (x)
Az x természetes logaritmusa.
Az e x-edik hatványa.
Az n-ed rendû Bessel fuggvenye x-nek.

A /bin/sh-ban a következõ utasítás visszaadja a "pi" értékét a pi környezeti változóban.

pi=$(echo "scale=10; 4*a(1)" | bc -l)

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 bc nyelven íródott.


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
  }
}

A következõ kód a bc 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.


scale=2
print "\nCsekkfüzet program!\n"
print "  Emlékeztetõ, a letétek negatív tranzakciók.\n"
print "  Kilépés 0 összegû tranzakció bevitelével.\n\n"
print "Kezdeti egyenleg? "; bal = read()
bal /= 1
print "\n"
while (1) {
  "jelenlegi egyenleg = "; bal
  "tranzakció? "; trans = read()
  if (trans == 0) break;
  bal -= trans
  bal /= 1
}
quit

A következõ függvény a faktoriális rekurzív definíciója.


define f (x) {
  if (x <= 1) return (1);
  return (f(x-1) * x);
}

A 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 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.

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.

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.
A tradícionális és a POSIX 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.
A stringek nem tartalmazhatnak NUL (ASCII nulla) karaktert. A POSIX szerint bármilyen karakter lehet egy stringben.
A POSIX bc-ben nincs last változó. Néhány implementáció a pontot (.) használja erre a célra.
összehasonlítások
A POSIX bc 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.
A POSIX bc-ben nincs else ág.
A POSIX bc-ben minden kifejezésnek szerepelnie kell.
&&, ||, !
A POSIX bc-ben nincsenek logikai operátorok.
A POSIX bc-ben nincs read függvény.
A POSIX bc-ben nincs print utasítás.
A POSIX bc-ben nincs continue utasítás.
A POSIX bc-ben nincsenek tömb paraméterek. Más implementációkban lehetnek.
=+, =-, =*, =/, =%, =^
A POSIX bc-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 a értékét 1-gyel, egyébként pedig az a értékét beállítja -1-re.
A bc 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 bc-ben ugyanez az utasítás szintaktikai hibát ad.
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:
a = 1
b = 2

ez két végrehajtási blokk és
{ a = 1
  b = 2 }

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.

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 bc 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 bc futását megszakítja.

A következõ határok vannak beépítve ebbe a 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.

A legnagyobb kimeneti számrendszer, jelenleg 999. A maximum bemeneti számrendszer 16.
Ez a jelenlegi pontossági határ, 655535. Az ön installációjában más lehet.
A tizedes pont elõtti és utáni számjegyek számát az INT_MAX határozza meg.
A karakterek maximális száma egy stringben INT_MAX.
A hatványozás operátor (^) kitevõjének maximum értékét a LONG_MAX határozza meg.
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.
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.
A jelenlegi limit az egyedi nevekre 32767 mind az egyszerû változókra, mind a tömbökre és a függvényekre.

A legtöbb installációban a bc-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 bc 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.)

Ha egy a parancssorban szereplõ fájl nem nyitható meg, a bc ü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ó.

A hibakezelés még nem túl jó.

Philip A. Nelson
phil@cs.wwu.edu

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.

Csehi András <acsehi@flexum.hu>