Provided by: manpages-pl_4.26.0-1_all 

NAZWA
bc - język kalkulatora dowolnej precyzji
SKŁADNIA
bc [ -hlwsqv ] [długie-opcje] [ plik ... ]
OPIS
bc jest językiem obsługującym obliczenia na liczbach dowolnej dokładności z interaktywnym wykonywaniem
instrukcji. Istnieją pewne podobieństwa składni do języka programowania C. Przy pomocy opcji wiersza
poleceń dostępna jest standardowa biblioteka matematyczna. Na żądanie, biblioteka matematyczna jest
definiowana przed rozpoczęciem przetwarzania plików. bc rozpoczyna pracę przetwarzając kod z wszystkich
plików wymienionych w wierszu poleceń, zachowując ich kolejność. Po przetworzeniu wszystkich plików, bc
czyta ze standardowego wejścia. Całość kodu wykonywana jest w miarę czytania. (Jeśli plik zawiera
polecenie zatrzymania procesora, to bc nie będzie prowadził odczytu ze standardowego wejścia).
Omawiana wersja bc zawiera kilka rozszerzeń w stosunku do tradycyjnych realizacji bc i standardu POSIX.
Opcje wiersza poleceń mogą powodować, że rozszerzenia te będą wyświetlać ostrzeżenia lub będą odrzucane.
Niniejszy dokument opisuje język akceptowany przez ten procesor bc. Rozszerzenia są w nim wyraźnie
wyróżnione.
OPCJE
-h, --help
Wypisuje informację o sposobie wywołania i kończy działanie.
-i, --interactive
Wymusza tryb interaktywny.
-l, --mathlib
Definiuje standardową bibliotekę matematyczną.
-w, --warn
Ostrzega o rozszerzeniach w stosunku do POSIX bc.
-s, --standard
Przetwarza wyłącznie standardowy, POSIX-owy język bc.
-q, --quiet
Nie wyświetla zwykłego przywitania GNU bc.
-v, --version
Wypisuje numer wersji, informację o prawach autorskich i kończy działanie.
LICZBY
Najbardziej podstawowym elementem w bc jest liczba. Liczby są liczbami dowolnej dokładności. Dokładność
ta odnosi się zarówno do części całkowitej, jak i do ułamkowej. Wszystkie liczby są reprezentowane
wewnętrznie w postaci dziesiętnej i wszystkie obliczenia prowadzone są w układzie dziesiętnym. (Opisywana
wersja obcina wyniki operacji dzielenia i mnożenia). Liczby mają dwa atrybuty: długość i dokładność. [od
tłum.: (org.scale) - w tłumaczeniu używane będzie słowo „dokładność” w znaczeniu zbliżonym do znanego np.
z obsługi kalkulatorów] Długość jest całkowitą liczbą cyfr dziesiętnych liczby, używanej przez bc do jej
reprezentacji, zaś dokładność jest całkowitą liczbą cyfr dziesiętnych po kropce dziesiętnej. Na
przykład:
.000001 ma długość 6 i dokładność 6.
1935.000 ma długość 7 i dokładność 3.
ZMIENNE
Liczby przechowywane są w dwu rodzajach zmiennych, zmiennych prostych i tablicach. Zarówno zmienne
proste, jak i tablice mają nazwy. Nazwy zaczynają się od litery, po której następuje dowolna liczba
liter, cyfr i znaków podkreślenia. Wszystkie litery muszą być małe. (Nazwy w pełni alfanumeryczne są
rozszerzeniem. W POSIX-owym bc wszystkie nazwy są pojedynczymi małymi literami). Rodzaj zmiennej wynika z
kontekstu, gdyż po nazwie każdej zmiennej tablicowej wystąpią nawiasy ([]).
Istnieją cztery zmienne specjalne: scale, ibase, obase oraz last. scale określa, jak niektóre operacje
używają cyfr po kropce dziesiętnej. Domyślną wartością scale jest 0. ibase oraz obase określają podstawę
pozycyjnego systemu liczbowego przy konwersji wejścia i wyjścia. Domyślną podstawą zarówno dla wejścia,
jak i dla wyjścia jest 10. last (rozszerzenie standardu) jest zmienną, która przechowuje wartość ostatnio
wydrukowanej liczby. Zmienne te będą omówione szczegółowo później, w odpowiedniej części. Wszystkie z
nich mogą mieć przypisywane wartości, jak również mogą być używane w wyrażeniach.
KOMENTARZE
Komentarze w bc rozpoczynają się od znaków /*, a kończą znakami */. Komentarze mogą zaczynać się w
dowolnym miejscu i na wejściu pojawiają się jako pojedyncze spacje. (Powoduje to, że komentarze są
ogranicznikami innych elementów wejścia. Na przykład, komentarz nie może znajdować się w środku nazwy
zmiennej). Komentarze obejmują znaki nowej linii (końca linii) pomiędzy początkiem a końcem komentarza.
Do zapewnienia obsługi skryptów dla bc, jako rozszerzenie dodano komentarz w pojedynczym wierszu.
Komentarz jednowierszowy rozpoczyna się znakiem # i rozciąga się do końca wiersza. Znak końca linii nie
jest tu częścią komentarza i jest przetwarzany jak zwykle.
WYRAŻENIA
Liczbami posługują się wyrażenia i instrukcje. Ponieważ język został zaprojektowany jako interaktywny,
instrukcje i wyrażenia wykonywane są niezwłocznie. Nie ma żadnego programu „głównego” („main”). Zamiast
tego, kod jest wykonywany zaraz po jego napotkaniu. (Funkcje, omówione szczegółowo dalej, są zdefiniowane
po ich napotkaniu).
Proste wyrażenie jest po prostu stałą. bc zamienia stałe na wewnętrzne liczby dziesiętne przy użyciu
bieżącej podstawy systemu dla wprowadzania, podanej w zmiennej ibase. (Istnieje wyjątek dla funkcji).
Dopuszczalnymi wartościami ibase są 2 do 36 (wartości większe od 16 są rozszerzeniem). Przypisanie ibase
wartości spoza tego zakresu nada jej wartość 2 lub 36. Liczby wejściowe mogą zawierać znaki 0–9 oraz A–Z
(Uwaga: muszą to być wielkie litery. Małe litery są nazwami zmiennych). Liczby jednocyfrowe mają zawsze
wartość cyfry, bez względu na wartość ibase. (tj. A = 10). Dla liczb wielocyfrowych bc zamienia wszystkie
cyfry wejściowe większe bądź równe ibase na wartość ibase-1. Powoduje to, że liczba ZZZ będzie zawsze
największą trzycyfrową liczbą przy danej podstawie systemu dla wejścia.
Pełne wyrażenia są podobne do występujących w wielu językach wysokiego poziomu. Ponieważ występuje tylko
jeden rodzaj liczb, nie ma reguł określających użycie różnych typów. Zamiast tego istnieją reguły
dotyczące dokładności wyrażeń. Każde wyrażenie ma określoną dokładność. Zależy ona od dokładności
pierwotnych liczb, wykonywanego działania i, w wielu przypadkach, wartości zmiennej scale. Dopuszczalnymi
wartościami zmiennej scale są liczby od 0 aż do maksymalnej liczby, jaka może być reprezentowana jako
całkowita (integer) w języku C.
W podanych poniżej opisach dopuszczalnych wyrażeń, „wyrażenie” określa pełne wyrażenie a „zmienna”
określa zmienną prostą lub tablicową. Zmienną prostą jest po prostu
nazwa
a zmienna tablicowa jest określona jako
nazwa[wyrażenie]
Dokładność wyniku jest maksymalną z dokładności użytych w nim wyrażeń, chyba że podano inaczej.
- wyrażenie
Wynikiem jest wartość przeciwna do wyrażenia.
++ zmienna
Zmienna jest powiększana o jeden a wynikiem wyrażenia jest ta nowa wartość.
-- zmienna
Zmienna jest pomniejszana o jeden a wynikiem wyrażenia jest ta nowa wartość.
zmienna ++
Wynikiem wyrażenia jest wartość zmiennej, a następnie zmienna jest powiększana o jeden.
zmienna --
Wynikiem wyrażenia jest wartość zmiennej, a następnie zmienna jest pomniejszana o jeden.
wyrażenie + wyrażenie
Wynikiem tego wyrażenia jest suma obu wyrażeń.
wyrażenie - wyrażenie
Wynikiem tego wyrażenia jest różnica obu wyrażeń.
wyrażenie * wyrażenie
Wynikiem tego wyrażenia jest iloczyn obu wyrażeń.
wyrażenie / wyrażenie
Wynikiem tego wyrażenia jest iloraz obu wyrażeń. Liczba cyfr po kropce dziesiętnej wyniku jest
równa wartości zmiennej scale.
wyrażenie % wyrażenie
Wynikiem tego wyrażenia jest „reszta” z dzielenia obliczana w następujący sposób. W celu
obliczenia a%b, obliczane jest najpierw a/b z dokładnością do scale cyfr dziesiętnych. Wynik
używany jest do obliczenia a-(a/b)*b z dokładnością określoną jako maksymalna z scale+scale(b)
oraz scale(a). Jeżeli scale ustawiona jest na zero, zaś oba wyrażenia są całkowite to wyrażenie
to jest funkcją reszty całkowitej.
wyrażenie ^ wyrażenie
Wynikiem tego wyrażenia jest wartość pierwszego z wyrażeń podniesiona do potęgi określonej przez
drugie. Drugie wyrażenie musi być liczbą całkowitą. (Jeśli drugie wyrażenie nie jest całkowite,
to emitowane jest ostrzeżenie a wyrażenie jest obcinane tak, by otrzymać wartość całkowitą).
Liczba cyfr ułamkowych wyniku wynosi scale, jeśli wykładnik jest ujemny. Jeżeli jest on dodatni,
to dokładność (liczba cyfr po kropce dziesiętnej) wyniku stanowi minimum z dokładności pierwszego
wyrażenia przemnożonej przez wartość wykładnika i maksimum z scale i dokładności pierwszego
wyrażenia. To znaczy: scale(a^b) = min(scale(a)*b, max( scale, scale(a))). Należy pamiętać, że
wyrażenie^0 zawsze zwraca wartość 1.
( wyrażenie )
Nawiasy wymuszają zmianę standardowych priorytetów przy obliczaniu wyrażenia.
zmienna = wyrażenie
Zmiennej przypisywana jest wartość wyrażenia.
zmienna <op>= wyrażenie
jest to równoważne zapisowi „zmienna = zmienna <op> wyrażenie”, z wyjątkiem tego, iż część
„zmienna” jest wyliczana tylko raz. Może to być istotne, jeśli „zmienna” jest tablicą.
Wyrażenia relacyjne są specjalnym rodzajem wyrażeń, zwracającym zawsze wartość 0 lub 1: zero jeśli
relacja jest fałszywa, zaś 1 jeżeli jest prawdziwa. Mogą one występować w dowolnych dozwolonych
wyrażeniach. (POSIX bc wymaga, by wyrażenia relacyjne były używane wyłącznie w instrukcjach if, while i
for oraz aby było w nich użyte tylko jedno sprawdzenie relacji). Operatorami relacji są:
wyrażenie1 < wyrażenie2
Wynikiem jest 1, jeśli wyrażenie1 jest mniejsze niż wyrażenie2.
wyrażenie1 <= wyrażenie2
Wynikiem jest 1, gdy wyrażenie jest mniejsze bądź równe wyrażenie2.
wyrażenie1 > wyrażenie2
Wynikiem jest 1, jeśli wyrażenie1 jest większe niż wyrażenie2.
wyrażenie1 >= wyrażenie2
Wynikiem jest 1, gdy wyrażenie1 jest większe bądź równe wyrażenie2.
wyrażenie1 == wyrażenie2
Wynikiem jest 1, gdy wyrażenie1 jest równe wyrażenie2.
wyrażenie != wyrażenie2
Wynikiem jest 1, gdy wyrażenie1 nie jest równe wyrażenie2.
Dozwolone są także operacje logiczne. (POSIX bc NIE zawiera operacji logicznych). Wynikami wszystkich
operacji logicznych są 0 lub 1 (dla fałszu i prawdy), tak jak dla wyrażeń relacyjnych. Operatorami
logicznymi są:
!wyrażenie
Zaprzeczenie. Wynikiem jest 1, jeśli wyrażenie ma wartość 0.
wyrażenie && wyrażenie
Koniunkcja. Wynikiem jest 1, jeżeli oba wyrażenia są niezerowe.
wyrażenie || wyrażenie
Alternatywa. Wynikiem jest 1, jeśli dowolne z wyrażeń jest niezerowe.
Wyrażenia mają następujący priorytet (od najniższego do najwyższego):
operator ||, wiązanie lewe
operator &&, wiązanie lewe
operator !, niezwiązany
operatory relacji, wiązanie lewe
operator przypisania, wiązanie prawe
operatory + i -, wiązanie lewe
operatory *, / i %, wiązanie lewe
operator ^, wiązanie prawe
jednoargumentowy operator -, niezwiązany
operatory ++ i --, niezwiązane
Kolejność wykonywania została dobrana tak, by programy zgodne z POSIX bc działały poprawnie. Powoduje to,
że operatory relacyjne i logiczne, użyte w wyrażeniach przypisania, będą wykazywać niecodzienne
zachowywanie. Weźmy następujące wyrażenie:
a = 3 < 5
Większość programistów C uważałaby, że przypisze ono wynik operacji „3 < 5” (wartość 1) zmiennej „a”.
Tymczasem w bc nadaje ono wartość 3 zmiennej „a”, a następnie porównuje 3 z 5. Używając operatorów
relacji i operatorów logicznych z operatorami przypisania najlepiej jest posłużyć się nawiasami.
bc obsługuje jeszcze kilka innych wyrażeń specjalnych. Związane są one z funkcjami definiowanymi przez
użytkownika i funkcjami standardowymi. Wszystkie one mają postać „nazwa(parametry)”. Funkcje definiowane
przez użytkownika opisano w sekcji Funkcje. Funkcjami standardowymi są:
length ( wyrażenie )
Wynikiem funkcji length jest liczba cyfr znaczących w wyrażeniu.
read ( )
Funkcja ta, będąca rozszerzeniem, odczytuje liczbę ze standardowego wejścia, niezależnie od
miejsca użycia funkcji. Strzeż się -- może to spowodować kłopoty przy przeplataniu się danych i
programu ze standardowego wejścia. Najlepszym zastosowaniem tej funkcji jest użycie jej w
uprzednio napisanym programie, który wymaga wprowadzania danych przez użytkownika, ale nigdy nie
pozwala na wprowadzanie kodu programu. Wynikiem działania funkcji read jest liczba odczytana ze
standardowego wejścia z konwersją układu liczbowego według aktualnej wartości zmiennej ibase.
scale ( wyrażenie )
Wynikiem funkcji scale jest liczba cyfr po kropce dziesiętnej w wyrażeniu będącym jej parametrem.
sqrt ( wyrażenie )
Wynikiem funkcji sqrt jest pierwiastek kwadratowy z wyrażenia. Jeżeli wyrażenie ma wartość ujemną,
to generowany jest błąd wykonania.
INSTRUKCJE
Instrukcje (jak w większości języków algorytmicznych) umożliwiają sterowanie kolejnością wykonywania
wyrażeń. W bc instrukcje wykonywane są bezzwłocznie, „tak szybko jak to jest możliwe”. Wykonanie odbywa
się gdy napotkano znak nowej linii i istnieje jedna lub więcej pełna instrukcja. W związku z takim
natychmiastowym wykonaniem, znaki nowej linii są bardzo istotne w bc. W rzeczywistości, jako organiczniki
instrukcji używane są zarówno znaki nowej linii, jak i średniki. Nieprawidłowo umieszczony znak nowej
linii spowoduje błąd składni. Ponieważ znaki nowej linii rozdzielają instrukcje, możliwe jest ich ukrycie
(przed interpretacją) przy pomocy znaku odwrotnego ukośnika. Sekwencja „\<nl>”, gdzie <nl> jest znakiem
nowej linii postrzegana jest przez bc jako znak zwykłej spacji zamiast znaku nowej linii. Poniżej
umieszczono listę instrukcji bc i ich znaczenia (elementy umieszczone w nawiasach kwadratowych ([]) są
opcjonalnymi częściami instrukcji):
wyrażenie
Instrukcja ta wykonuje dwie rzeczy. Jeżeli wyrażenie rozpoczyna się od „<zmienna> <przypisanie>
...”, to jest traktowane jak instrukcja przypisania. Jeśli wyrażenie nie jest instrukcją
przypisania, to wyrażenie jest wyliczane i drukowane na standardowym wyjściu. Po wydrukowaniu
liczby drukowany jest znak nowej linii. Na przykład, „a=1” jest instrukcją przypisania, a „(a=1)”
jest wyrażeniem zawierającym przypisanie. Wszystkie liczby drukowane są przy użyciu systemu
pozycyjnego określonego zmienną obase. Dopuszczalnymi wartościami obase są 2 do BC_BASE_MAX.
(Patrz sekcja OGRANICZENIA). Dla podstaw systemu od 2 do 16 używana jest zwyczajowa metoda zapisu
liczb. Dla podstaw większych od 16 bc posługuje się metodą cyfr wieloznakowych wyświetlania liczb,
gdzie każda z kolejnych cyfr wyświetlana jest jako liczba dziesiętna. Cyfry wieloznakowe
oddzielane są odstępami. Każda z cyfr zawiera tyle znaków, ile jest niezbędnych do przedstawienia
dziesiętnego wartości „obase-1”. Ponieważ liczby mają dowolną dokładność, niektóre z liczb mogą
nie dać wydrukować się w pojedynczym wierszu. Takie długie liczby zostaną podzielone między
wiersze przy zastosowaniu „\” jako ostatniego znaku wiersza. Maksymalną liczbą znaków drukowanych
w wierszu jest 70. Z powodu interaktywnego charakteru bc drukowanie liczby ma efekt uboczny w
postaci przypisania wydrukowanej wartości do specjalnej zmiennej o nazwie last. Umożliwia to
użytkownikowi odtworzenie ostatnio wydrukowanej wartości bez potrzeby ponownego wpisywania
wyrażenia, które ją wydrukowało. Nadawanie wartości zmiennej last jest dozwolone; spowoduje ono
zastąpienie ostatnio wydrukowanej wartości wartością przypisaną. Nowo przypisana wartość
pozostanie aż do wydrukowania kolejnej liczby lub nadania last innej wartości. (Niektóre z
implementacji mogą dopuszczać użycie pojedynczej kropki (.), niebędącej częścią liczby, jako
skróconej notacji dla last).
łańcuch
Na wyjściu drukowany jest łańcuch znakowy. Łańcuchy rozpoczynają się znakiem cudzysłowu i
zawierają wszystkie znaki do następnego znaku cudzysłowu. Wszystkie znaki, włącznie ze znakami
nowej linii, traktowane są dosłownie. Po wydrukowaniu łańcucha nie jest drukowany znak nowej
linii.
print lista
Instrukcja print (rozszerzenie) umożliwia użycie innego sposobu wydruku wyników. „Lista” jest
listą łańcuchów i wyrażeń oddzielonych przecinkami. Każdy łańcuch czy wyrażenie drukowany jest w
kolejności występowania na liście. Nie jest drukowany kończący znak nowej linii (przejście do
następnego wiersza). Wyliczana jest wartość wyrażeń; jest ona drukowana i przypisywana zmiennej
last. Łańcuchy użyte w instrukcji print są drukowane na wyjściu i mogą zawierać znaki specjalne.
Znaki specjalne rozpoczynają się znakiem odwrotnego ukośnika (\). bc rozpoznaje następujące znaki
specjalne: „a” (dzwonek, bell), „b” (backspace), „f” (wysunięcie strony, form feed), „n” (nowa
linia, newline), „r” (powrót karetki, carriage return), „q” (cudzysłów, double quote), „t”
(tabulacja, tab) oraz „\” (odwrotny ukośnik, backslash). Inne znaki występujące po odwrotnym
ukośniku będą ignorowane.
{ lista_instrukcji }
Jest to instrukcja grupowania. Pozwala na grupowanie wielu instrukcji do wykonania.
if ( wyrażenie ) instrukcja1 [else instrukcja2]
Instrukcja if oblicza wyrażenie i wykonuje instrukcję1 bądź instrukcję2 w zależności od wartości
wyrażenia. Jeżeli wyrażenie jest niezerowe, wykonywana jest instrukcja1. Jeśli występuje
instrukcja2 a wartością wyrażenia jest 0, to wykonywana jest instrukcja2. (Klauzula else
instrukcji if jest rozszerzeniem).
while ( wyrażenie ) instrukcja
Instrukcja while powtarza wykonywanie danej instrukcji póki wyrażenie jest niezerowe. Oblicza ona
wartość wyrażenia przed każdym wykonaniem instrukcji. Przerwanie pętli powodowane jest zerową
wartością wyrażenia lub wykonaniem instrukcji break (przerwania).
for ( [wyr1] ; [wyr2] ; [wyr3] ) instrukcja
Instrukcja for kontroluje powtarzane wykonanie danej instrukcji. Przed pętlą obliczane jest
wyrażenie1. Wyrażenie2 jest obliczane przed każdym wykonaniem instrukcji. Jeśli jest niezerowe, to
wykonywana jest instrukcja. Jeśli ma ono wartość zero, to pętla jest przerywana. Po każdym
wykonaniu danej instrukcji wyliczana jest wartość wyrażenia3 przed ponownym wyliczeniem
wyrażenia2. Jeżeli pominięto wyrażenie1 lub wyrażenie3, to nic nie jest obliczane w chwili, gdy
powinna być określana ich wartość. Jeżeli pominięto wyrażenie2, to jest ono zastępowane wartością
1. (Wyrażenie opcjonalne stanowią rozszerzenie. bc w POSIXie wymaga wszystkich trzech wyrażeń).
Poniższy kod jest równoważny instrukcji for:
wyrażenie1;
while (wyrażenie2) {
instrukcja;
wyrażenie3;
}
break Instrukcja ta powoduje wymuszone zakończenie ostatniej obejmującej ją instrukcji while lub for.
continue
Instrukcja continue (rozszerzenie) powoduje rozpoczęcie kolejnej iteracji przez ostatnią
obejmującą ją instrukcję for.
halt Instrukcja halt (rozszerzenie) jest instrukcją nakazującą preprocesorowi bc zakończenie pracy (ale
tylko wtedy gdy instrukcja ta jest wykonywana). Na przykład, „if (0 == 1) halt” nie spowoduje
przerwania pracy bc, gdyż instrukcja halt nie będzie wykonana.
return Zwraca wartość zero jako wynik funkcji. (Patrz sekcja dotycząca funkcji).
return ( wyrażenie )
Zwraca wartość wyrażenia jako wynik funkcji. (Patrz sekcja dotycząca funkcji). Nawiasy nie są
wymagane, co jest rozszerzeniem GNU bc.
PSEUDOINSTRUKCJE
Te instrukcje nie są instrukcjami w tradycyjnym sensie tego terminu. Nie są one instrukcjami
wykonywanymi. Ich funkcja jest wykonywana podczas „kompilacji”.
limits Wypisuje lokalne ograniczenia narzucone przez lokalna wersję bc. Jest to rozszerzenie.
quit Po odczycie instrukcji quit procesor bc kończy pracę, niezależnie od tego, gdzie wystąpiła ta
instrukcja. Na przykład, „if (0 == 1) quitr” spowoduje zakończenie pracy bc.
warranty
Wypisuje dłuższą notkę na temat gwarancji. Jest to rozszerzenie.
FUNKCJE
Funkcje dostarczają sposobu definiowania obliczeń, które mogą być wykonane później. Funkcje w bc zawsze
obliczają wartość i zwracają ją do miejsca wywołania. Definicje funkcji są „dynamiczne” w tym sensie, że
funkcja pozostaje niezdefiniowana dopóki na wejściu nie zostanie odczytana jej definicja. Definicja ta
jest następnie używana dopóki nie zostanie napotkana inna definicja funkcji o tej samej nazwie. Wówczas
nowa definicja zastępuje starszą. Funkcja definiowana jest następująco:
define nazwa ( parametry ) { nowa_linia lista_auto lista_instrukcji }
Wywołanie funkcji jest po prostu wyrażeniem postaci „nazwa(parametry)”.
Parametry są liczbami lub tablicami (rozszerzenie). W definicji funkcji definiuje się równocześnie zero
lub więcej jej parametrów przez podanie ich nazw rozdzielonych przecinkami. Liczby są jedynymi
parametrami wywoływanymi przez wartość. Tablice podawane są w definicji parametrów przy pomocy notacji
„nazwa[]”. W wywołaniu funkcji parametry rzeczywiste dla parametrów numerycznych są pełnymi wyrażeniami.
Do przekazywania tablic używana jest ta sama notacja, co przy definiowaniu parametrów typu tablicowego.
Dana tablica przesyłana jest do funkcji przez wartość. Ponieważ definicje funkcji są dynamiczne, w
trakcie wywoływania funkcji sprawdzana jest liczba i typy jej parametrów. Niezgodność liczby parametrów
lub ich typów powoduje błąd wykonania. Błąd wykonania pojawi się także przy próbie wywołania
niezdefiniowanej funkcji.
lista_auto jest opcjonalną listą zmiennych, do użytku „lokalnego”. A oto składnia tej listy (jeśli
występuje): „auto nazwa, ... ;”. Średnik jest opcjonalny. Każda z nazw jest nazwą auto-zmiennej.
Tablice mogą być podane przy użyciu takiej samej składni jak w parametrach. Na początku funkcji wartości
tych zmiennych odkładane są na stosie. Następnie zmienne są inicjowane zerami i używane w czasie
wykonywania funkcji. Przy zakończeniu funkcji zmienne są zdejmowane ze stosu, tak że przywracana jest ich
pierwotna wartość (z momentu wywołania funkcji). Parametry te są faktycznie zmiennymi auto inicjowanymi
wartościami dostarczonymi w wywołaniu funkcji. Zmienne typu auto różnią się od tradycyjnych zmiennych
lokalnych, gdyż jeśli funkcja A woła funkcję B, to B może posługiwać się zmiennymi auto funkcji A po
prostu używając tych samych nazw, chyba że funkcja B traktuje je jako zmienne auto. Ponieważ zmienne auto
i parametry składowane są na stosie, to bc obsługuje funkcje rekurencyjne.
Ciało funkcji jest listą instrukcji bc. I znów, jak w części zasadniczej, instrukcje oddzielane są
średnikami lub znakami nowej linii. Instrukcje return (powrót) powodują zakończenie funkcji i zwrócenie
wartości. Istnieją dwa warianty instrukcji return. Pierwsza postać, „return”, zwraca wartość 0 do
wywołującego wyrażenia. Druga postać, „return ( wyrażenie )”, oblicza wartość wyrażenia i zwraca ją do
wyrażenia wołającego. Każda funkcja domyślnie kończy się niejawną instrukcją „return (0)”. Pozwala to na
funkcji na zakończenie działania i zwrócenie zera bez jawnej instrukcji powrotu.
Funkcje inaczej korzystają ze zmiennej ibase. Wszystkie stałe w obrębie ciała funkcji będą konwertowane
przy zastosowaniu wartości ibase w momencie wywołania funkcji. Zmiany ibase w czasie wykonywania funkcji
są ignorowane, z wyjątkiem funkcji standardowej read, która zawsze do konwersji liczb wykorzystuje
bieżącą wartość ibase.
GNU bc zawiera kilka rozszerzeń związanych z funkcjami. Pierwszym jest nieco luźniejszy format definicji
funkcji. Standard wymaga, by nawias otwierający znajdował się w tym samym wierszu, co słowo kluczowe
define, a wszystkie pozostałe części w kolejnych wierszach. Opisywana tu wersja bc zezwala na dowolną
liczbę znaków nowej linii przed i po nawiasie otwierającym funkcji. Na przykład, dozwolone są poniższe
definicje.
define d (n) { return (2*n); } define d (n) { return (2*n); }
Funkcje mogą być zdefiniowane jako void. Funkcja void nie zwraca wartości, więc nie może być używana w
miejscach, które wymagają wartości. Po wywołaniu funkcja void nie produkuje żadnego wyjścia. Słowo
kluczowe void występuje pomiędzy słowem kluczowym define a nazwą funkcji. Na przykład prosimy rozważyć
poniższy skrypt:
define py (y) { print "--->", y, "<---", "\n"; } define void px (x) { print "--->", x, "<---", "\n"; } py(1) --->1<--- 0 px(1) --->1<---
Ponieważ py nie jest funkcją void, to wywołanie py(1) wyświetla pożądane wyjście, a następnie wypisuje w
drugiej linii wartość tej funkcji. Ponieważ wartością funkcji, która nie zawiera instrukcji return, jest
zero, to właśnie zero zostanie wypisane. W przypadku funkcji px(1) zero nie jest wypisywane, ponieważ ta
funkcja jest funkcją void.
Także dodano wywoływanie tablic przez zmienną. Aby zadeklarować wywołanie przez zmienną tablicową, należy
zadeklarować parametr tablicowy w definicji funkcji jako „*nazwa[]”. Wywołanie funkcji jest takie samo,
jak w przypadku wywołania przez wartość.
BIBLIOTEKA MATEMATYCZNA
Jeżeli bc wywoływane jest z opcją -l, to wstępnie wczytywana jest biblioteka matematyczna (math library),
a domyślna liczba cyfr dziesiętnych (scale) ustawiana jest na 20. Funkcje matematyczne obliczają swe
wyniki z dokładnością określoną w momencie ich wywołania. Bibilioteka matematyczna definiuje następujące
funkcje:
s (x) Sinus x, x podawany jest w radianach.
c (x) Cosinus x, x w radianach.
a (x) Arcus tangens x; arcus tangens zwraca radiany.
l (x) Logarytm naturalny z x.
e (x) Funkcja wykładnicza - e do potęgi x.
j (n,x)
Funkcja Bessela rzędu n (całkowitego) z argumentem x.
PRZYKŁADY
W powłoce /bin/sh, poniższe polecenie przypisuje wartość liczby „Pi” zmiennej środowiska pi.
pi=$(echo "scale=10; 4*a(1)" | bc -l)
Poniżej podano definicję funkcji wykładniczej używanej w bibliotece matematycznej. Funkcja ta napisana
jest w bc standardu POSIX.
scale = 20
/* wykorzystuje fakt, że e^x = (e^(x/2))^2 Gdy x jest dostatecznie małe, używamy szeregu: e^x = 1 + x + x^2/2! + x^3/3! + ... */
define e(x) { auto a, d, e, f, i, m, v, z
/* Sprawdzenie znaku x. */ if (x<0) { m = 1 x = -x }
/* przewidywane x */ z = scale; scale = 4 + z + .44*x; while (x > 1) { f += 1; x /= 2; }
/* inicjowanie zmiennych */ 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 } }
Poniższy kod posługuje się rozszerzonymi cechami bc do uzyskania prostego programu liczącego salda
książeczki czekowej. Najlepiej byłoby zachować go w pliku, tak by mógł być wykorzystany wielokrotnie bez
potrzeby każdorazowego przepisywania.
scale=2 print "\nProgram książeczki czekowej!\n" print " Pamiętaj, wpłaty są transakcjami ujemnymi.\n" print " Koniec - transakcja zerowa.\n\n"
print "Saldo początkowe? "; bal = read() bal /= 1 print "\n" while (1) { "bieżące saldo = "; bal "transakcja? "; trans = read() if (trans == 0) break; bal -= trans bal /= 1 } quit
Poniżej zamieszczono definicję rekurencyjnej funkcji silni.
define f (x) { if (x <= 1) return (1); return (f(x-1) * x); }
OPCJE READLINE I LIBEDIT
GNU bc może zostać skompilowany (przez opcję konfiguracji) tak, by posługiwał się biblioteką GNU edytora
wejścia o nazwie readline lub też biblioteką BSD libedit. Umożliwia to użytkownikowi edycję wierszy przed
wysłaniem ich do bc. Pozwala też na wykorzystanie historii poprzednio wprowadzonych wierszy. Przy
wybraniu tej opcji bc zawiera dodatkową zmienną specjalną. Ta specjalna zmienna, history, przechowuje
liczbę zachowywanych wierszy historii. Dla readline, wartość -1 oznacza, że przechowywana jest
nieograniczona liczba wierszy historii. Ustawienie wartości history na liczbę dodatnią ogranicza liczbę
przechowywanych wierszy historii do podanej liczby. Wartość zero wyłącza funkcję historii wprowadzonych
wierszy. Wartością domyślną jest 100. Więcej informacji można znaleźć w podręcznikach użytkownika dla
bibliotek GNU readline i history oraz BSD libedit. Nie można równocześnie włączyć zarówno readline, jak i
libedit.
RÓŻNICE
Niniejsza wersja bc została zbudowana, bazując na projekcie POSIX P1003.2/D11 i zawiera kilka różnic i
rozszerzeń w stosunku do tego dokumentu i tradycyjnych realizacji. Nie jest wykonana w tradycyjny sposób,
wykorzystujący polecenie dc(1). Wersja ta jest pojedynczym procesem, analizującym i uruchamiającym kod
binarny będący tłumaczeniem programu. Istnieje „nieudokumentowana” opcja (-c) powodująca, że program
wyświetla kod binarny na standardowym wyjściu zamiast wykonywania go. Używana była ona głównie do
debugowania analizatora składni i przy przygotowaniu biblioteki matematycznej.
Głównym źródłem różnic są rozszerzenia, w których jakaś cecha, możliwość programu jest rozbudowana w celu
dodania funkcjonalności, oraz dodatki, gdzie dodano nowe możliwości. Poniżej podano listę różnic i
rozszerzeń.
Zmienna środowiska LANG
Niniejsza wersja nie spełnia standardu POSIX przetwarzania zmiennej środowiska LANG i wszystkich
zmiennych środowiska rozpoczynających się na LC_.
nazwy Tradycyjny i POSIXowy bc zawierają jednoliterowe nazwy funkcji, zmiennych i tablic. Zostały one
rozszerzone do nazw wieloznakowych, rozpoczynających się literą i mogących zawierać litery, cyfry
i znaki podkreślenia.
Łańcuchy znakowe
Łańcuchy nie mogą zawierać znaków NUL. POSIX stwierdza, że wszystkie znaki muszą być zawarte w
łańcuchach.
last POSIX bc nie zawiera zmiennej last. Niektóre implementacje bc używają kropki (.) w podobny sposób.
porównania
POSIX bc dopuszcza porównania wyłącznie w instrukcjach if, while oraz w drugim wyrażeniu
instrukcji for. Dodatkowo, w każdej z tych instrukcji dopuszczalna jest tylko jedna operacja
porównania (relacji).
instrukcja if, klauzula else
POSIX bc nie zawiera klauzuli else.
instrukcja for
POSIX bc wymaga, by w instrukcji for występowały wszystkie wyrażenia.
&&, ||, !
POSIX bc nie zawiera operatorów logicznych.
funkcja read
POSIX bc nie zawiera funkcji read.
instrukcja print
POSIX bc nie zawiera instrukcji print.
instrukcja continue
POSIX bc nie zawiera instrukcji continue.
instrukcja return
POSIX bc wymaga nawiasów wokół zwracanego wyrażenia.
parametry tablicowe
POSIX bc nie obsługuje (obecnie) w pełni parametrów tablicowych. Gramatyka POSIX zezwala na
użycie tablic w definicjach funkcji, ale nie zapewnia metody przekazania tablicy jako bieżącego
parametru. (Jest to najprawdopodobniej przeoczenie w zdefiniowanej gramatyce.) Tradycyjne
implementacje bc mają jedynie wywołanie parametrów tablicowych przez wartość.
format funkcji
POSIX bc wymaga, by nawias otwierający był w tym samym wierszu, co słowo kluczowe define,
instrukcja auto natomiast w następnym wierszu.
=+, =-, =*, =/, =%, =^
POSIX bc nie wymaga, by były zdefiniowane powyższe operatory przypisania „starego typu”. Niniejsza
wersja zezwala na takie przypisania w „starym stylu”. Należy skorzystać z instrukcji limits, by
stwierdzić, czy zainstalowana wersja je rozpoznaje. Jeżeli obsługuje ona przypisania w „starym
stylu”, to instrukcja „a =- 1” pomniejszy a o jeden zamiast przypisać a wartość -1.
spacje w liczbach
Inne implementacje bc dopuszczają występowanie spacji w liczbach. Na przykład, „x=1 3” przypisze
wartość 13 zmiennej x. Ta sama instrukcja spowoduje błąd składni w opisywanej tu wersji bc.
błędy i wykonanie
Opisywana implementacja różni się od innych sposobem, w jaki wykonywany jest kod w przypadku
znalezienia w programie błędów składniowych i innych. W przypadku napotkania błędu w definicji
funkcji, obsługa błędów próbuje odnaleźć początek instrukcji i kontynuować analizę składniową
funkcji. Po znalezieniu błędu w funkcji, nie jest ona możliwa do wywołania i staje się
niezdefiniowana. Błędy składniowe w interaktywnym wykonywaniu kodu unieważniają bieżący blok
wykonania. Blok wykonania jest zakończony końcem linii pojawiającym się po pełnej sekwencji
instrukcji. Na przykład,
a = 1
b = 2
ma dwa bloki wykonania a
{ a = 1
b = 2 }
ma jeden blok wykonania. Każdy z błędów wykonania przerywa wykonywanie bieżącego bloku wykonania.
Ostrzeżenie w trakcie wykonywania nie przerywa bieżącego bloku.
Przerwania
Podczas sesji interaktywnej sygnał SIGINT (zwykle generowany przez znak control-C z terminala)
spowoduje przerwanie bieżącego bloku wykonywania. Wyświetli on błąd wykonania („runtime”),
wskazujący która funkcja została przerwana. Po wyczyszczeniu wszystkich struktur (runtime
structures) wykonania, zostanie wyświetlony komunikat informujący użytkownika, że bc jest gotów do
przyjmowania kolejnych danych. Wszystkie uprzednio zdefiniowane funkcje pozostają zdefiniowane,
zaś wartości wszystkich zmiennych innych niż zmienne typu auto są wartościami sprzed przerwania.
Podczas procesu oczyszczania struktur danych usuwane są wszystkie zmienne typu auto oraz parametry
funkcji. W czasie sesji nieinteraktywnej sygnał SIGINT przerywa wykonanie całego bc.
OGRANICZENIA
Poniżej podano obecne ograniczenia opisywanego procesora bc. Niektóre z nich mogą być zmienione podczas
instalacji. Faktyczne ograniczenia można sprawdzić za pomocą instrukcji limits (ograniczenia).
BC_BASE_MAX
Maksymalna podstawa pozycyjnego układu, w którym wyprowadzane są wyniki obecnie ustawiona jest na
999. Maksymalną podstawą układu wejściowego jest 16.
BC_DIM_MAX
Obecnie ustawione jest arbitralne ograniczenie do 65535 (w wersji rozpowszechnianej). Twoja
instalacja może być inna.
BC_SCALE_MAX
Liczba cyfr po kropce dziesiętnej ograniczona jest do INT_MAX cyfr. Także liczba cyfr przed kropką
dziesiętną ograniczona jest do INT_MAX cyfr.
BC_STRING_MAX
Maksymalnie w łańcuchu może wystąpić INT_MAX znaków.
wykładnik
Wartość wykładnika w operacji potęgowania (^) ograniczona jest do LONG_MAX.
nazwy zmiennych
Obecnie nie może być więcej niż 32767 unikatowych nazw w każdym z rodzajów: zmiennych prostych,
tablic i funkcji.
ZMIENNE ŚRODOWISKOWE
bc przetwarza następujące zmienne środowiska:
POSIXLY_CORRECT
To samo, co opcja -s. Tryb zgodności z POSIX.
BC_ENV_ARGS
Inny sposób przekazywania argumentów do bc. Format jest taki sam, jak argumentów wiersza poleceń.
Argumenty te przetwarzane są na początku, więc pliki podane w argumentach środowiska przetwarzane
są przed plikami podanymi jako argumenty wiersza poleceń. Umożliwia to użytkownikowi ustawienie
„standardowych” opcji i plików, jakie będą przetwarzane przy każdym wywołaniu bc. Pliki podane w
zmiennych środowiska zawierają zwykle definicje funkcji, które użytkownik chce mieć zdefiniowane
przy każdym uruchomieniu bc.
BC_LINE_LENGTH
Powinna to być liczba całkowita (integer) podająca liczbę znaków w wierszu wynikowym. Obejmuje ona
znaki odwrotnego ukośnika i nowej linii dla długich liczb. Jako rozszerzenie GNU wartość zero
wyłącza wieloliniowe wyjście. Jakakolwiek inna wartość mniejsza od 3 ustawia długość linii na 70.
DIAGNOSTYKA
Jeżeli któryś z plików podanych w wierszu poleceń nie może zostać otwarty bc zgłosi, że plik ten jest
niedostępny i przerwie pracę. Istnieją też komunikaty diagnostyczne kompilacji i wykonania, które powinny
być zrozumiałe.
USTERKI
Obsługa błędów (error recovery) nie jest jeszcze bardzo dobra.
Błędy proszę zgłaszać (w jęz.angielskim) na adres bug-bc@gnu.org. Proszę się upewnić, że pole tematu
wiadomości zawiera gdzieś słowo „bc”.
AUTOR
Philip A. Nelson
philnelson@acm.org
PODZIĘKOWANIA
Autor chciałby podziękować Steve'owi Sommars (Steve.Sommars@att.com) za jego szeroką pomoc w testowaniu
tej implementacji. Podsunął on wiele cennych sugestii. Dzięki jego zaangażowaniu jest to o wiele lepszy
produkt.
TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Wojtek Kotwica <wkotwica@post.pl>,
Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ
ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-
list@lists.sourceforge.net.
Projekt GNU 11 czerwca 2006 r. bc(1)