bc(1) General Commands Manual bc(1) NAZWA bc - jezyk kalkulatora dowolnej precyzji SKLADNIA bc [ -hlwsqv ] [dlugie-opcje] [ plik ... ] OPIS bc jest jezykiem obslugujacym obliczenia na liczbach dowolnej dokladnosci z interaktywnym wykonywaniem instrukcji. Istnieja pewne podobienstwa skladni do jezyka programowania C. Przy pomocy opcji wiersza polecen dostepna jest standardowa biblioteka matematyczna. Na zadanie, biblioteka matematyczna jest definiowana przed rozpoczeciem przetwarzania plikow. bc rozpoczyna prace przetwarzajac kod z wszystkich plikow wymienionych w wierszu polecen, zachowujac ich kolejnosc. Po przetworzeniu wszystkich plikow, bc czyta ze standardowego wejscia. Calosc kodu wykonywana jest w miare czytania. (Jesli plik zawiera polecenie zatrzymania procesora, to bc nie bedzie prowadzil odczytu ze standardowego wejscia). Omawiana wersja bc zawiera kilka rozszerzen w stosunku do tradycyjnych realizacji bc i standardu POSIX. Opcje wiersza polecen moga powodowac, ze rozszerzenia te beda wyswietlac ostrzezenia lub beda odrzucane. Niniejszy dokument opisuje jezyk akceptowany przez ten procesor bc. Rozszerzenia sa w nim wyraznie wyroznione. OPCJE -h, --help Wypisuje informacje o sposobie wywolania i konczy dzialanie. -i, --interactive Wymusza tryb interaktywny. -l, --mathlib Definiuje standardowa biblioteke matematyczna. -w, --warn Ostrzega o rozszerzeniach w stosunku do POSIX bc. -s, --standard Przetwarza wylacznie standardowy, POSIX-owy jezyk bc. -q, --quiet Nie wyswietla zwyklego przywitania GNU bc. -v, --version Wypisuje numer wersji, informacje o prawach autorskich i konczy dzialanie. LICZBY Najbardziej podstawowym elementem w bc jest liczba. Liczby sa liczbami dowolnej dokladnosci. Dokladnosc ta odnosi sie zarowno do czesci calkowitej, jak i do ulamkowej. Wszystkie liczby sa reprezentowane wewnetrznie w postaci dziesietnej i wszystkie obliczenia prowadzone sa w ukladzie dziesietnym. (Opisywana wersja obcina wyniki operacji dzielenia i mnozenia). Liczby maja dwa atrybuty: dlugosc i dokladnosc. [od tlum.: (org.scale) - w tlumaczeniu uzywane bedzie slowo ,,dokladnosc" w znaczeniu zblizonym do znanego np. z obslugi kalkulatorow] Dlugosc jest calkowita liczba cyfr dziesietnych liczby, uzywanej przez bc do jej reprezentacji, zas dokladnosc jest calkowita liczba cyfr dziesietnych po kropce dziesietnej. Na przyklad: .000001 ma dlugosc 6 i dokladnosc 6. 1935.000 ma dlugosc 7 i dokladnosc 3. ZMIENNE Liczby przechowywane sa w dwu rodzajach zmiennych, zmiennych prostych i tablicach. Zarowno zmienne proste, jak i tablice maja nazwy. Nazwy zaczynaja sie od litery, po ktorej nastepuje dowolna liczba liter, cyfr i znakow podkreslenia. Wszystkie litery musza byc male. (Nazwy w pelni alfanumeryczne sa rozszerzeniem. W POSIX-owym bc wszystkie nazwy sa pojedynczymi malymi literami). Rodzaj zmiennej wynika z kontekstu, gdyz po nazwie kazdej zmiennej tablicowej wystapia nawiasy ([]). Istnieja cztery zmienne specjalne: scale, ibase, obase oraz last. scale okresla, jak niektore operacje uzywaja cyfr po kropce dziesietnej. Domyslna wartoscia scale jest 0. ibase oraz obase okreslaja podstawe pozycyjnego systemu liczbowego przy konwersji wejscia i wyjscia. Domyslna podstawa zarowno dla wejscia, jak i dla wyjscia jest 10. last (rozszerzenie standardu) jest zmienna, ktora przechowuje wartosc ostatnio wydrukowanej liczby. Zmienne te beda omowione szczegolowo pozniej, w odpowiedniej czesci. Wszystkie z nich moga miec przypisywane wartosci, jak rowniez moga byc uzywane w wyrazeniach. KOMENTARZE Komentarze w bc rozpoczynaja sie od znakow /*, a koncza znakami */. Komentarze moga zaczynac sie w dowolnym miejscu i na wejsciu pojawiaja sie jako pojedyncze spacje. (Powoduje to, ze komentarze sa ogranicznikami innych elementow wejscia. Na przyklad, komentarz nie moze znajdowac sie w srodku nazwy zmiennej). Komentarze obejmuja znaki nowej linii (konca linii) pomiedzy poczatkiem a koncem komentarza. Do zapewnienia obslugi skryptow dla bc, jako rozszerzenie dodano komentarz w pojedynczym wierszu. Komentarz jednowierszowy rozpoczyna sie znakiem # i rozciaga sie do konca wiersza. Znak konca linii nie jest tu czescia komentarza i jest przetwarzany jak zwykle. WYRAZENIA Liczbami posluguja sie wyrazenia i instrukcje. Poniewaz jezyk zostal zaprojektowany jako interaktywny, instrukcje i wyrazenia wykonywane sa niezwlocznie. Nie ma zadnego programu ,,glownego" (,,main"). Zamiast tego, kod jest wykonywany zaraz po jego napotkaniu. (Funkcje, omowione szczegolowo dalej, sa zdefiniowane po ich napotkaniu). Proste wyrazenie jest po prostu stala. bc zamienia stale na wewnetrzne liczby dziesietne przy uzyciu biezacej podstawy systemu dla wprowadzania, podanej w zmiennej ibase. (Istnieje wyjatek dla funkcji). Dopuszczalnymi wartosciami ibase sa 2 do 36 (wartosci wieksze od 16 sa rozszerzeniem). Przypisanie ibase wartosci spoza tego zakresu nada jej wartosc 2 lub 36. Liczby wejsciowe moga zawierac znaki 0-9 oraz A-Z. (Uwaga: musza to byc wielkie litery. Male litery sa nazwami zmiennych). Liczby jednocyfrowe maja zawsze wartosc cyfry, bez wzgledu na wartosc ibase. (tj. A = 10). Dla liczb wielocyfrowych bc zamienia wszystkie cyfry wejsciowe wieksze badz rowne ibase na wartosc ibase-1. Powoduje to, ze liczba ZZZ bedzie zawsze najwieksza trzycyfrowa liczba przy danej podstawie systemu dla wejscia. Pelne wyrazenia sa podobne do wystepujacych w wielu jezykach wysokiego poziomu. Poniewaz wystepuje tylko jeden rodzaj liczb, nie ma regul okreslajacych uzycie roznych typow. Zamiast tego istnieja reguly dotyczace dokladnosci wyrazen. Kazde wyrazenie ma okreslona dokladnosc. Zalezy ona od dokladnosci pierwotnych liczb, wykonywanego dzialania i, w wielu przypadkach, wartosci zmiennej scale. Dopuszczalnymi wartosciami zmiennej scale sa liczby od 0 az do maksymalnej liczby, jaka moze byc reprezentowana jako calkowita (integer) w jezyku C. W podanych ponizej opisach dopuszczalnych wyrazen, ,,wyrazenie" okresla pelne wyrazenie a ,,zmienna" okresla zmienna prosta lub tablicowa. Zmienna prosta jest po prostu nazwa a zmienna tablicowa jest okreslona jako nazwa[wyrazenie] Dokladnosc wyniku jest maksymalna z dokladnosci uzytych w nim wyrazen, chyba ze podano inaczej. - wyrazenie Wynikiem jest wartosc przeciwna do wyrazenia. ++ zmienna Zmienna jest powiekszana o jeden a wynikiem wyrazenia jest ta nowa wartosc. -- zmienna Zmienna jest pomniejszana o jeden a wynikiem wyrazenia jest ta nowa wartosc. zmienna ++ Wynikiem wyrazenia jest wartosc zmiennej, a nastepnie zmienna jest powiekszana o jeden. zmienna -- Wynikiem wyrazenia jest wartosc zmiennej, a nastepnie zmienna jest pomniejszana o jeden. wyrazenie + wyrazenie Wynikiem tego wyrazenia jest suma obu wyrazen. wyrazenie - wyrazenie Wynikiem tego wyrazenia jest roznica obu wyrazen. wyrazenie * wyrazenie Wynikiem tego wyrazenia jest iloczyn obu wyrazen. wyrazenie / wyrazenie Wynikiem tego wyrazenia jest iloraz obu wyrazen. Liczba cyfr po kropce dziesietnej wyniku jest rowna wartosci zmiennej scale. wyrazenie % wyrazenie Wynikiem tego wyrazenia jest ,,reszta" z dzielenia obliczana w nastepujacy sposob. W celu obliczenia a%b, obliczane jest najpierw a/b z dokladnoscia do scale cyfr dziesietnych. Wynik uzywany jest do obliczenia a-(a/b)*b z dokladnoscia okreslona jako maksymalna z scale+scale(b) oraz scale(a). Jezeli scale ustawiona jest na zero, zas oba wyrazenia sa calkowite to wyrazenie to jest funkcja reszty calkowitej. wyrazenie ^ wyrazenie Wynikiem tego wyrazenia jest wartosc pierwszego z wyrazen podniesiona do potegi okreslonej przez drugie. Drugie wyrazenie musi byc liczba calkowita. (Jesli drugie wyrazenie nie jest calkowite, to emitowane jest ostrzezenie a wyrazenie jest obcinane tak, by otrzymac wartosc calkowita). Liczba cyfr ulamkowych wyniku wynosi scale, jesli wykladnik jest ujemny. Jezeli jest on dodatni, to dokladnosc (liczba cyfr po kropce dziesietnej) wyniku stanowi minimum z dokladnosci pierwszego wyrazenia przemnozonej przez wartosc wykladnika i maksimum z scale i dokladnosci pierwszego wyrazenia. To znaczy: scale(a^b) = min(scale(a)*b, max( scale, scale(a))). Nalezy pamietac, ze wyrazenie^0 zawsze zwraca wartosc 1. ( wyrazenie ) Nawiasy wymuszaja zmiane standardowych priorytetow przy obliczaniu wyrazenia. zmienna = wyrazenie Zmiennej przypisywana jest wartosc wyrazenia. zmienna = wyrazenie jest to rownowazne zapisowi ,,zmienna = zmienna wyrazenie", z wyjatkiem tego, iz czesc ,,zmienna" jest wyliczana tylko raz. Moze to byc istotne, jesli ,,zmienna" jest tablica. Wyrazenia relacyjne sa specjalnym rodzajem wyrazen, zwracajacym zawsze wartosc 0 lub 1: zero jesli relacja jest falszywa, zas 1 jezeli jest prawdziwa. Moga one wystepowac w dowolnych dozwolonych wyrazeniach. (POSIX bc wymaga, by wyrazenia relacyjne byly uzywane wylacznie w instrukcjach if, while i for oraz aby bylo w nich uzyte tylko jedno sprawdzenie relacji). Operatorami relacji sa: wyrazenie1 < wyrazenie2 Wynikiem jest 1, jesli wyrazenie1 jest mniejsze niz wyrazenie2. wyrazenie1 <= wyrazenie2 Wynikiem jest 1, gdy wyrazenie jest mniejsze badz rowne wyrazenie2. wyrazenie1 > wyrazenie2 Wynikiem jest 1, jesli wyrazenie1 jest wieksze niz wyrazenie2. wyrazenie1 >= wyrazenie2 Wynikiem jest 1, gdy wyrazenie1 jest wieksze badz rowne wyrazenie2. wyrazenie1 == wyrazenie2 Wynikiem jest 1, gdy wyrazenie1 jest rowne wyrazenie2. wyrazenie != wyrazenie2 Wynikiem jest 1, gdy wyrazenie1 nie jest rowne wyrazenie2. Dozwolone sa takze operacje logiczne. (POSIX bc NIE zawiera operacji logicznych). Wynikami wszystkich operacji logicznych sa 0 lub 1 (dla falszu i prawdy), tak jak dla wyrazen relacyjnych. Operatorami logicznymi sa: !wyrazenie Zaprzeczenie. Wynikiem jest 1, jesli wyrazenie ma wartosc 0. wyrazenie && wyrazenie Koniunkcja. Wynikiem jest 1, jezeli oba wyrazenia sa niezerowe. wyrazenie || wyrazenie Alternatywa. Wynikiem jest 1, jesli dowolne z wyrazen jest niezerowe. Wyrazenia maja nastepujacy priorytet (od najnizszego do najwyzszego): operator ||, wiazanie lewe operator &&, wiazanie lewe operator !, niezwiazany operatory relacji, wiazanie lewe operator przypisania, wiazanie prawe operatory + i -, wiazanie lewe operatory *, / i %, wiazanie lewe operator ^, wiazanie prawe jednoargumentowy operator -, niezwiazany operatory ++ i --, niezwiazane Kolejnosc wykonywania zostala dobrana tak, by programy zgodne z POSIX bc dzialaly poprawnie. Powoduje to, ze operatory relacyjne i logiczne, uzyte w wyrazeniach przypisania, beda wykazywac niecodzienne zachowywanie. Wezmy nastepujace wyrazenie: a = 3 < 5 Wiekszosc programistow C uwazalaby, ze przypisze ono wynik operacji ,,3 < 5" (wartosc 1) zmiennej ,,a". Tymczasem w bc nadaje ono wartosc 3 zmiennej ,,a", a nastepnie porownuje 3 z 5. Uzywajac operatorow relacji i operatorow logicznych z operatorami przypisania najlepiej jest posluzyc sie nawiasami. bc obsluguje jeszcze kilka innych wyrazen specjalnych. Zwiazane sa one z funkcjami definiowanymi przez uzytkownika i funkcjami standardowymi. Wszystkie one maja postac ,,nazwa(parametry)". Funkcje definiowane przez uzytkownika opisano w sekcji Funkcje. Funkcjami standardowymi sa: length ( wyrazenie ) Wynikiem funkcji length jest liczba cyfr znaczacych w wyrazeniu. read ( ) Funkcja ta, bedaca rozszerzeniem, odczytuje liczbe ze standardowego wejscia, niezaleznie od miejsca uzycia funkcji. Strzez sie -- moze to spowodowac klopoty przy przeplataniu sie danych i programu ze standardowego wejscia. Najlepszym zastosowaniem tej funkcji jest uzycie jej w uprzednio napisanym programie, ktory wymaga wprowadzania danych przez uzytkownika, ale nigdy nie pozwala na wprowadzanie kodu programu. Wynikiem dzialania funkcji read jest liczba odczytana ze standardowego wejscia z konwersja ukladu liczbowego wedlug aktualnej wartosci zmiennej ibase. scale ( wyrazenie ) Wynikiem funkcji scale jest liczba cyfr po kropce dziesietnej w wyrazeniu bedacym jej parametrem. sqrt ( wyrazenie ) Wynikiem funkcji sqrt jest pierwiastek kwadratowy z wyrazenia. Jezeli wyrazenie ma wartosc ujemna, to generowany jest blad wykonania. INSTRUKCJE Instrukcje (jak w wiekszosci jezykow algorytmicznych) umozliwiaja sterowanie kolejnoscia wykonywania wyrazen. W bc instrukcje wykonywane sa bezzwlocznie, ,,tak szybko jak to jest mozliwe". Wykonanie odbywa sie gdy napotkano znak nowej linii i istnieje jedna lub wiecej pelna instrukcja. W zwiazku z takim natychmiastowym wykonaniem, znaki nowej linii sa bardzo istotne w bc. W rzeczywistosci, jako organiczniki instrukcji uzywane sa zarowno znaki nowej linii, jak i sredniki. Nieprawidlowo umieszczony znak nowej linii spowoduje blad skladni. Poniewaz znaki nowej linii rozdzielaja instrukcje, mozliwe jest ich ukrycie (przed interpretacja) przy pomocy znaku odwrotnego ukosnika. Sekwencja ,,\", gdzie jest znakiem nowej linii postrzegana jest przez bc jako znak zwyklej spacji zamiast znaku nowej linii. Ponizej umieszczono liste instrukcji bc i ich znaczenia (elementy umieszczone w nawiasach kwadratowych ([]) sa opcjonalnymi czesciami instrukcji): wyrazenie Instrukcja ta wykonuje dwie rzeczy. Jezeli wyrazenie rozpoczyna sie od ,, ...", to jest traktowane jak instrukcja przypisania. Jesli wyrazenie nie jest instrukcja przypisania, to wyrazenie jest wyliczane i drukowane na standardowym wyjsciu. Po wydrukowaniu liczby drukowany jest znak nowej linii. Na przyklad, ,,a=1" jest instrukcja przypisania, a ,,(a=1)" jest wyrazeniem zawierajacym przypisanie. Wszystkie liczby drukowane sa przy uzyciu systemu pozycyjnego okreslonego zmienna obase. Dopuszczalnymi wartosciami obase sa 2 do BC_BASE_MAX. (Patrz sekcja OGRANICZENIA). Dla podstaw systemu od 2 do 16 uzywana jest zwyczajowa metoda zapisu liczb. Dla podstaw wiekszych od 16 bc posluguje sie metoda cyfr wieloznakowych wyswietlania liczb, gdzie kazda z kolejnych cyfr wyswietlana jest jako liczba dziesietna. Cyfry wieloznakowe oddzielane sa odstepami. Kazda z cyfr zawiera tyle znakow, ile jest niezbednych do przedstawienia dziesietnego wartosci ,,obase-1". Poniewaz liczby maja dowolna dokladnosc, niektore z liczb moga nie dac wydrukowac sie w pojedynczym wierszu. Takie dlugie liczby zostana podzielone miedzy wiersze przy zastosowaniu ,,\" jako ostatniego znaku wiersza. Maksymalna liczba znakow drukowanych w wierszu jest 70. Z powodu interaktywnego charakteru bc drukowanie liczby ma efekt uboczny w postaci przypisania wydrukowanej wartosci do specjalnej zmiennej o nazwie last. Umozliwia to uzytkownikowi odtworzenie ostatnio wydrukowanej wartosci bez potrzeby ponownego wpisywania wyrazenia, ktore ja wydrukowalo. Nadawanie wartosci zmiennej last jest dozwolone; spowoduje ono zastapienie ostatnio wydrukowanej wartosci wartoscia przypisana. Nowo przypisana wartosc pozostanie az do wydrukowania kolejnej liczby lub nadania last innej wartosci. (Niektore z implementacji moga dopuszczac uzycie pojedynczej kropki (.), niebedacej czescia liczby, jako skroconej notacji dla last). lancuch Na wyjsciu drukowany jest lancuch znakowy. Lancuchy rozpoczynaja sie znakiem cudzyslowu i zawieraja wszystkie znaki do nastepnego znaku cudzyslowu. Wszystkie znaki, wlacznie ze znakami nowej linii, traktowane sa doslownie. Po wydrukowaniu lancucha nie jest drukowany znak nowej linii. print lista Instrukcja print (rozszerzenie) umozliwia uzycie innego sposobu wydruku wynikow. ,,Lista" jest lista lancuchow i wyrazen oddzielonych przecinkami. Kazdy lancuch czy wyrazenie drukowany jest w kolejnosci wystepowania na liscie. Nie jest drukowany konczacy znak nowej linii (przejscie do nastepnego wiersza). Wyliczana jest wartosc wyrazen; jest ona drukowana i przypisywana zmiennej last. Lancuchy uzyte w instrukcji print sa drukowane na wyjsciu i moga zawierac znaki specjalne. Znaki specjalne rozpoczynaja sie znakiem odwrotnego ukosnika (\). bc rozpoznaje nastepujace znaki specjalne: ,,a" (dzwonek, bell), ,,b" (backspace), ,,f" (wysuniecie strony, form feed), ,,n" (nowa linia, newline), ,,r" (powrot karetki, carriage return), ,,q" (cudzyslow, double quote), ,,t" (tabulacja, tab) oraz ,,\" (odwrotny ukosnik, backslash). Inne znaki wystepujace po odwrotnym ukosniku beda ignorowane. { lista_instrukcji } Jest to instrukcja grupowania. Pozwala na grupowanie wielu instrukcji do wykonania. if ( wyrazenie ) instrukcja1 [else instrukcja2] Instrukcja if oblicza wyrazenie i wykonuje instrukcje1 badz instrukcje2 w zaleznosci od wartosci wyrazenia. Jezeli wyrazenie jest niezerowe, wykonywana jest instrukcja1. Jesli wystepuje instrukcja2 a wartoscia wyrazenia jest 0, to wykonywana jest instrukcja2. (Klauzula else instrukcji if jest rozszerzeniem). while ( wyrazenie ) instrukcja Instrukcja while powtarza wykonywanie danej instrukcji poki wyrazenie jest niezerowe. Oblicza ona wartosc wyrazenia przed kazdym wykonaniem instrukcji. Przerwanie petli powodowane jest zerowa wartoscia wyrazenia lub wykonaniem instrukcji break (przerwania). for ( [wyr1] ; [wyr2] ; [wyr3] ) instrukcja Instrukcja for kontroluje powtarzane wykonanie danej instrukcji. Przed petla obliczane jest wyrazenie1. Wyrazenie2 jest obliczane przed kazdym wykonaniem instrukcji. Jesli jest niezerowe, to wykonywana jest instrukcja. Jesli ma ono wartosc zero, to petla jest przerywana. Po kazdym wykonaniu danej instrukcji wyliczana jest wartosc wyrazenia3 przed ponownym wyliczeniem wyrazenia2. Jezeli pominieto wyrazenie1 lub wyrazenie3, to nic nie jest obliczane w chwili, gdy powinna byc okreslana ich wartosc. Jezeli pominieto wyrazenie2, to jest ono zastepowane wartoscia 1. (Wyrazenie opcjonalne stanowia rozszerzenie. bc w POSIXie wymaga wszystkich trzech wyrazen). Ponizszy kod jest rownowazny instrukcji for: wyrazenie1; while (wyrazenie2) { instrukcja; wyrazenie3; } break Instrukcja ta powoduje wymuszone zakonczenie ostatniej obejmujacej ja instrukcji while lub for. continue Instrukcja continue (rozszerzenie) powoduje rozpoczecie kolejnej iteracji przez ostatnia obejmujaca ja instrukcje for. halt Instrukcja halt (rozszerzenie) jest instrukcja nakazujaca preprocesorowi bc zakonczenie pracy (ale tylko wtedy gdy instrukcja ta jest wykonywana). Na przyklad, ,,if (0 == 1) halt" nie spowoduje przerwania pracy bc, gdyz instrukcja halt nie bedzie wykonana. return Zwraca wartosc zero jako wynik funkcji. (Patrz sekcja dotyczaca funkcji). return ( wyrazenie ) Zwraca wartosc wyrazenia jako wynik funkcji. (Patrz sekcja dotyczaca funkcji). Nawiasy nie sa wymagane, co jest rozszerzeniem GNU bc. PSEUDOINSTRUKCJE Te instrukcje nie sa instrukcjami w tradycyjnym sensie tego terminu. Nie sa one instrukcjami wykonywanymi. Ich funkcja jest wykonywana podczas ,,kompilacji". limits Wypisuje lokalne ograniczenia narzucone przez lokalna wersje bc. Jest to rozszerzenie. quit Po odczycie instrukcji quit procesor bc konczy prace, niezaleznie od tego, gdzie wystapila ta instrukcja. Na przyklad, ,,if (0 == 1) quitr" spowoduje zakonczenie pracy bc. warranty Wypisuje dluzsza notke na temat gwarancji. Jest to rozszerzenie. FUNKCJE Funkcje dostarczaja sposobu definiowania obliczen, ktore moga byc wykonane pozniej. Funkcje w bc zawsze obliczaja wartosc i zwracaja ja do miejsca wywolania. Definicje funkcji sa ,,dynamiczne" w tym sensie, ze funkcja pozostaje niezdefiniowana dopoki na wejsciu nie zostanie odczytana jej definicja. Definicja ta jest nastepnie uzywana dopoki nie zostanie napotkana inna definicja funkcji o tej samej nazwie. Wowczas nowa definicja zastepuje starsza. Funkcja definiowana jest nastepujaco: define nazwa ( parametry ) { nowa_linia lista_auto lista_instrukcji } Wywolanie funkcji jest po prostu wyrazeniem postaci ,,nazwa(parametry)". Parametry sa liczbami lub tablicami (rozszerzenie). W definicji funkcji definiuje sie rownoczesnie zero lub wiecej jej parametrow przez podanie ich nazw rozdzielonych przecinkami. Liczby sa jedynymi parametrami wywolywanymi przez wartosc. Tablice podawane sa w definicji parametrow przy pomocy notacji ,,nazwa[]". W wywolaniu funkcji parametry rzeczywiste dla parametrow numerycznych sa pelnymi wyrazeniami. Do przekazywania tablic uzywana jest ta sama notacja, co przy definiowaniu parametrow typu tablicowego. Dana tablica przesylana jest do funkcji przez wartosc. Poniewaz definicje funkcji sa dynamiczne, w trakcie wywolywania funkcji sprawdzana jest liczba i typy jej parametrow. Niezgodnosc liczby parametrow lub ich typow powoduje blad wykonania. Blad wykonania pojawi sie takze przy probie wywolania niezdefiniowanej funkcji. lista_auto jest opcjonalna lista zmiennych, do uzytku ,,lokalnego". A oto skladnia tej listy (jesli wystepuje): ,,auto nazwa, ... ;". Srednik jest opcjonalny. Kazda z nazw jest nazwa auto-zmiennej. Tablice moga byc podane przy uzyciu takiej samej skladni jak w parametrach. Na poczatku funkcji wartosci tych zmiennych odkladane sa na stosie. Nastepnie zmienne sa inicjowane zerami i uzywane w czasie wykonywania funkcji. Przy zakonczeniu funkcji zmienne sa zdejmowane ze stosu, tak ze przywracana jest ich pierwotna wartosc (z momentu wywolania funkcji). Parametry te sa faktycznie zmiennymi auto inicjowanymi wartosciami dostarczonymi w wywolaniu funkcji. Zmienne typu auto roznia sie od tradycyjnych zmiennych lokalnych, gdyz jesli funkcja A wola funkcje B, to B moze poslugiwac sie zmiennymi auto funkcji A po prostu uzywajac tych samych nazw, chyba ze funkcja B traktuje je jako zmienne auto. Poniewaz zmienne auto i parametry skladowane sa na stosie, to bc obsluguje funkcje rekurencyjne. Cialo funkcji jest lista instrukcji bc. I znow, jak w czesci zasadniczej, instrukcje oddzielane sa srednikami lub znakami nowej linii. Instrukcje return (powrot) powoduja zakonczenie funkcji i zwrocenie wartosci. Istnieja dwa warianty instrukcji return. Pierwsza postac, ,,return", zwraca wartosc 0 do wywolujacego wyrazenia. Druga postac, ,,return ( wyrazenie )", oblicza wartosc wyrazenia i zwraca ja do wyrazenia wolajacego. Kazda funkcja domyslnie konczy sie niejawna instrukcja ,,return (0)". Pozwala to na funkcji na zakonczenie dzialania i zwrocenie zera bez jawnej instrukcji powrotu. Funkcje inaczej korzystaja ze zmiennej ibase. Wszystkie stale w obrebie ciala funkcji beda konwertowane przy zastosowaniu wartosci ibase w momencie wywolania funkcji. Zmiany ibase w czasie wykonywania funkcji sa ignorowane, z wyjatkiem funkcji standardowej read, ktora zawsze do konwersji liczb wykorzystuje biezaca wartosc ibase. GNU bc zawiera kilka rozszerzen zwiazanych z funkcjami. Pierwszym jest nieco luzniejszy format definicji funkcji. Standard wymaga, by nawias otwierajacy znajdowal sie w tym samym wierszu, co slowo kluczowe define, a wszystkie pozostale czesci w kolejnych wierszach. Opisywana tu wersja bc zezwala na dowolna liczbe znakow nowej linii przed i po nawiasie otwierajacym funkcji. Na przyklad, dozwolone sa ponizsze definicje. define d (n) { return (2*n); } define d (n) { return (2*n); } Funkcje moga byc zdefiniowane jako void. Funkcja void nie zwraca wartosci, wiec nie moze byc uzywana w miejscach, ktore wymagaja wartosci. Po wywolaniu funkcja void nie produkuje zadnego wyjscia. Slowo kluczowe void wystepuje pomiedzy slowem kluczowym define a nazwa funkcji. Na przyklad prosimy rozwazyc ponizszy skrypt: define py (y) { print "--->", y, "<---", "\n"; } define void px (x) { print "--->", x, "<---", "\n"; } py(1) --->1<--- 0 px(1) --->1<--- Poniewaz py nie jest funkcja void, to wywolanie py(1) wyswietla pozadane wyjscie, a nastepnie wypisuje w drugiej linii wartosc tej funkcji. Poniewaz wartoscia funkcji, ktora nie zawiera instrukcji return, jest zero, to wlasnie zero zostanie wypisane. W przypadku funkcji px(1) zero nie jest wypisywane, poniewaz ta funkcja jest funkcja void. Takze dodano wywolywanie tablic przez zmienna. Aby zadeklarowac wywolanie przez zmienna tablicowa, nalezy zadeklarowac parametr tablicowy w definicji funkcji jako ,,*nazwa[]". Wywolanie funkcji jest takie samo, jak w przypadku wywolania przez wartosc. BIBLIOTEKA MATEMATYCZNA Jezeli bc wywolywane jest z opcja -l, to wstepnie wczytywana jest biblioteka matematyczna (math library), a domyslna liczba cyfr dziesietnych (scale) ustawiana jest na 20. Funkcje matematyczne obliczaja swe wyniki z dokladnoscia okreslona w momencie ich wywolania. Bibilioteka matematyczna definiuje nastepujace 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 wykladnicza - e do potegi x. j (n,x) Funkcja Bessela rzedu n (calkowitego) z argumentem x. PRZYKLADY W powloce /bin/sh, ponizsze polecenie przypisuje wartosc liczby ,,Pi" zmiennej srodowiska pi. pi=$(echo "scale=10; 4*a(1)" | bc -l) Ponizej podano definicje funkcji wykladniczej uzywanej w bibliotece matematycznej. Funkcja ta napisana jest w bc standardu POSIX. scale = 20 /* wykorzystuje fakt, ze e^x = (e^(x/2))^2 Gdy x jest dostatecznie male, uzywamy 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 } } Ponizszy kod posluguje sie rozszerzonymi cechami bc do uzyskania prostego programu liczacego salda ksiazeczki czekowej. Najlepiej byloby zachowac go w pliku, tak by mogl byc wykorzystany wielokrotnie bez potrzeby kazdorazowego przepisywania. scale=2 print "\nProgram ksiazeczki czekowej!\n" print " Pamietaj, wplaty sa transakcjami ujemnymi.\n" print " Koniec - transakcja zerowa.\n\n" print "Saldo poczatkowe? "; bal = read() bal /= 1 print "\n" while (1) { "biezace saldo = "; bal "transakcja? "; trans = read() if (trans == 0) break; bal -= trans bal /= 1 } quit Ponizej zamieszczono definicje rekurencyjnej funkcji silni. define f (x) { if (x <= 1) return (1); return (f(x-1) * x); } OPCJE READLINE I LIBEDIT GNU bc moze zostac skompilowany (przez opcje konfiguracji) tak, by poslugiwal sie biblioteka GNU edytora wejscia o nazwie readline lub tez biblioteka BSD libedit. Umozliwia to uzytkownikowi edycje wierszy przed wyslaniem ich do bc. Pozwala tez na wykorzystanie historii poprzednio wprowadzonych wierszy. Przy wybraniu tej opcji bc zawiera dodatkowa zmienna specjalna. Ta specjalna zmienna, history, przechowuje liczbe zachowywanych wierszy historii. Dla readline, wartosc -1 oznacza, ze przechowywana jest nieograniczona liczba wierszy historii. Ustawienie wartosci history na liczbe dodatnia ogranicza liczbe przechowywanych wierszy historii do podanej liczby. Wartosc zero wylacza funkcje historii wprowadzonych wierszy. Wartoscia domyslna jest 100. Wiecej informacji mozna znalezc w podrecznikach uzytkownika dla bibliotek GNU readline i history oraz BSD libedit. Nie mozna rownoczesnie wlaczyc zarowno readline, jak i libedit. ROZNICE Niniejsza wersja bc zostala zbudowana, bazujac na projekcie POSIX P1003.2/D11 i zawiera kilka roznic i rozszerzen w stosunku do tego dokumentu i tradycyjnych realizacji. Nie jest wykonana w tradycyjny sposob, wykorzystujacy polecenie dc(1). Wersja ta jest pojedynczym procesem, analizujacym i uruchamiajacym kod binarny bedacy tlumaczeniem programu. Istnieje ,,nieudokumentowana" opcja (-c) powodujaca, ze program wyswietla kod binarny na standardowym wyjsciu zamiast wykonywania go. Uzywana byla ona glownie do debugowania analizatora skladni i przy przygotowaniu biblioteki matematycznej. Glownym zrodlem roznic sa rozszerzenia, w ktorych jakas cecha, mozliwosc programu jest rozbudowana w celu dodania funkcjonalnosci, oraz dodatki, gdzie dodano nowe mozliwosci. Ponizej podano liste roznic i rozszerzen. Zmienna srodowiska LANG Niniejsza wersja nie spelnia standardu POSIX przetwarzania zmiennej srodowiska LANG i wszystkich zmiennych srodowiska rozpoczynajacych sie na LC_. nazwy Tradycyjny i POSIXowy bc zawieraja jednoliterowe nazwy funkcji, zmiennych i tablic. Zostaly one rozszerzone do nazw wieloznakowych, rozpoczynajacych sie litera i mogacych zawierac litery, cyfry i znaki podkreslenia. Lancuchy znakowe Lancuchy nie moga zawierac znakow NUL. POSIX stwierdza, ze wszystkie znaki musza byc zawarte w lancuchach. last POSIX bc nie zawiera zmiennej last. Niektore implementacje bc uzywaja kropki (.) w podobny sposob. porownania POSIX bc dopuszcza porownania wylacznie w instrukcjach if, while oraz w drugim wyrazeniu instrukcji for. Dodatkowo, w kazdej z tych instrukcji dopuszczalna jest tylko jedna operacja porownania (relacji). instrukcja if, klauzula else POSIX bc nie zawiera klauzuli else. instrukcja for POSIX bc wymaga, by w instrukcji for wystepowaly wszystkie wyrazenia. &&, ||, ! POSIX bc nie zawiera operatorow 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 nawiasow wokol zwracanego wyrazenia. parametry tablicowe POSIX bc nie obsluguje (obecnie) w pelni parametrow tablicowych. Gramatyka POSIX zezwala na uzycie tablic w definicjach funkcji, ale nie zapewnia metody przekazania tablicy jako biezacego parametru. (Jest to najprawdopodobniej przeoczenie w zdefiniowanej gramatyce.) Tradycyjne implementacje bc maja jedynie wywolanie parametrow tablicowych przez wartosc. format funkcji POSIX bc wymaga, by nawias otwierajacy byl w tym samym wierszu, co slowo kluczowe define, instrukcja auto natomiast w nastepnym wierszu. =+, =-, =*, =/, =%, =^ POSIX bc nie wymaga, by byly zdefiniowane powyzsze operatory przypisania ,,starego typu". Niniejsza wersja zezwala na takie przypisania w ,,starym stylu". Nalezy skorzystac z instrukcji limits, by stwierdzic, czy zainstalowana wersja je rozpoznaje. Jezeli obsluguje ona przypisania w ,,starym stylu", to instrukcja ,,a =- 1" pomniejszy a o jeden zamiast przypisac a wartosc -1. spacje w liczbach Inne implementacje bc dopuszczaja wystepowanie spacji w liczbach. Na przyklad, ,,x=1 3" przypisze wartosc 13 zmiennej x. Ta sama instrukcja spowoduje blad skladni w opisywanej tu wersji bc. bledy i wykonanie Opisywana implementacja rozni sie od innych sposobem, w jaki wykonywany jest kod w przypadku znalezienia w programie bledow skladniowych i innych. W przypadku napotkania bledu w definicji funkcji, obsluga bledow probuje odnalezc poczatek instrukcji i kontynuowac analize skladniowa funkcji. Po znalezieniu bledu w funkcji, nie jest ona mozliwa do wywolania i staje sie niezdefiniowana. Bledy skladniowe w interaktywnym wykonywaniu kodu uniewazniaja biezacy blok wykonania. Blok wykonania jest zakonczony koncem linii pojawiajacym sie po pelnej sekwencji instrukcji. Na przyklad, a = 1 b = 2 ma dwa bloki wykonania a { a = 1 b = 2 } ma jeden blok wykonania. Kazdy z bledow wykonania przerywa wykonywanie biezacego bloku wykonania. Ostrzezenie w trakcie wykonywania nie przerywa biezacego bloku. Przerwania Podczas sesji interaktywnej sygnal SIGINT (zwykle generowany przez znak control-C z terminala) spowoduje przerwanie biezacego bloku wykonywania. Wyswietli on blad wykonania (,,runtime"), wskazujacy ktora funkcja zostala przerwana. Po wyczyszczeniu wszystkich struktur (runtime structures) wykonania, zostanie wyswietlony komunikat informujacy uzytkownika, ze bc jest gotow do przyjmowania kolejnych danych. Wszystkie uprzednio zdefiniowane funkcje pozostaja zdefiniowane, zas wartosci wszystkich zmiennych innych niz zmienne typu auto sa wartosciami sprzed przerwania. Podczas procesu oczyszczania struktur danych usuwane sa wszystkie zmienne typu auto oraz parametry funkcji. W czasie sesji nieinteraktywnej sygnal SIGINT przerywa wykonanie calego bc. OGRANICZENIA Ponizej podano obecne ograniczenia opisywanego procesora bc. Niektore z nich moga byc zmienione podczas instalacji. Faktyczne ograniczenia mozna sprawdzic za pomoca instrukcji limits (ograniczenia). BC_BASE_MAX Maksymalna podstawa pozycyjnego ukladu, w ktorym wyprowadzane sa wyniki, to co najmniej 10^9. Maksymalna podstawa ukladu wejsciowego jest 16. BC_DIM_MAX Obecnie ustawione jest arbitralne ograniczenie do 65535 (w wersji rozpowszechnianej). Twoja instalacja moze byc inna. BC_SCALE_MAX Liczba cyfr po kropce dziesietnej ograniczona jest do INT_MAX cyfr. Takze liczba cyfr przed kropka dziesietna ograniczona jest do INT_MAX cyfr. BC_STRING_MAX Maksymalnie w lancuchu moze wystapic INT_MAX znakow. wykladnik Wartosc wykladnika w operacji potegowania (^) ograniczona jest do LONG_MAX. nazwy zmiennych Obecnie nie moze byc wiecej niz 32767 unikatowych nazw w kazdym z rodzajow: zmiennych prostych, tablic i funkcji. ZMIENNE SRODOWISKOWE bc przetwarza nastepujace zmienne srodowiska: POSIXLY_CORRECT To samo, co opcja -s. Tryb zgodnosci z POSIX. BC_ENV_ARGS Inny sposob przekazywania argumentow do bc. Format jest taki sam, jak argumentow wiersza polecen. Argumenty te przetwarzane sa na poczatku, wiec pliki podane w argumentach srodowiska przetwarzane sa przed plikami podanymi jako argumenty wiersza polecen. Umozliwia to uzytkownikowi ustawienie ,,standardowych" opcji i plikow, jakie beda przetwarzane przy kazdym wywolaniu bc. Pliki podane w zmiennych srodowiska zawieraja zwykle definicje funkcji, ktore uzytkownik chce miec zdefiniowane przy kazdym uruchomieniu bc. BC_LINE_LENGTH Powinna to byc liczba calkowita (integer) podajaca liczbe znakow w wierszu wynikowym. Obejmuje ona znaki odwrotnego ukosnika i nowej linii dla dlugich liczb. Jako rozszerzenie GNU wartosc zero wylacza wieloliniowe wyjscie. Jakakolwiek inna wartosc mniejsza od 3 ustawia dlugosc linii na 70. DIAGNOSTYKA Jezeli ktorys z plikow podanych w wierszu polecen nie moze zostac otwarty bc zglosi, ze plik ten jest niedostepny i przerwie prace. Istnieja tez komunikaty diagnostyczne kompilacji i wykonania, ktore powinny byc zrozumiale. USTERKI Obsluga bledow (error recovery) nie jest jeszcze bardzo dobra. Bledy prosze zglaszac (w jez.angielskim) na adres bug-bc@gnu.org. Prosze sie upewnic, ze pole tematu wiadomosci zawiera gdzies slowo ,,bc". AUTOR Philip A. Nelson philnelson@acm.org PODZIEKOWANIA Autor chcialby podziekowac Steve'owi Sommars (Steve.Sommars@att.com) za jego szeroka pomoc w testowaniu tej implementacji. Podsunal on wiele cennych sugestii. Dzieki jego zaangazowaniu jest to o wiele lepszy produkt. TLUMACZENIE Tlumaczenie niniejszej strony podrecznika: Wojtek Kotwica , Robert Luberda i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Projekt GNU 10 stycznia 2025 r. bc(1)