DOKK / manpages / debian 10 / manpages-tr / bc.1.tr
bc(1) Komut Kılavuzu bc(1)

İSİM

bc - Keyfî duyarlılıkta hesaplama dili

bc [ -hlwsqv ] [ uzun-seçenekler ] [ dosya ... ]

Bu kullanım kılavuzu, GNU bc sürüm 1.06'ya göre hazırlanmıştır.

bc, girilen deyimleri işleterek keyfi uzunlukta ve duyarlılıktaki sayılar üzerinde matematiksel işlemler yapmaya imkan sağlayan etkileşimli bir ortam ve bir yazılım geliştirme dilidir. Sözdizimi açısından C yazılım geliştirme dilini andıran benzerlikler sözkonusudur. Komut satırından belirtmek suretiyle kullanabileceğimiz standart bir math kütüphanesine de sahiptir. Eğer gerekli ise; math kütüphanesi, belirtilen dosyalardan daha önce ele alınır. bc işleme tabi tutarken dosyaları komut satırında belirtilen sıraya göre ele alır. Belirtilen dosyaların tümü ele alınıp işlendikten sonra, standart girdiden girişler okunmaya başlar. Kodlar nasıl okunuyorlarsa bu halleriyle işletilirler. (Eğer belirtilen dosyalardan herhangi birinde bc'yi sonlandıracak bir komut yer alırsa, bc sonlanır, bir daha standart girdiden okuyamaz.)

bc'nin bu sürümü, geleneksel bc uygulamalarına ve POSIX taslak standardına göre ilave oluşumlar içermektedir. Komut satırından belirtilecek bir seçenekle bu genişletmeler kullanıma dahil edilebilir veya edilmeyebilir. Bu kılavuzda GNU bc anlatılacak ve ek oluşumlar yeri gelince belirtilecektir.

Bir kullanım iletisi basar ve çıkar.

Etkileşimli kipe geçilir.

Standart math kütüphanesini kullanıma sokar.

POSIX bc'ye ek oluşumlar için uyarılar verir.

Standart POSIX bc diline uygun olarak işlem yapar.

Normalde gelen, GNU bc hoşgeldiniz iletisini görüntülemez.

Sürüm ve telif hakkı bilgilerini gösterir ve çıkar.

bc'deki en temel eleman sayılardır. Sayılar keyfi duyarlılıkta ifade edilirler. Yani bc'de bir sayı, tamsayı kısım ve ondalık kısım olarak ifade edilir. Tüm sayılar normalde iç hesaplamalarda onluk tabanda ele alınırlar ve tüm işlemler onluk taban üzerinden gerçekleştirilirler. (Bu sürüm, bölme ve çarpma işlemlerinde sayıların ondalık kısımlarını belli uzunluktan sonra kesmektedir.) bc'de sayıların iki özelliği vardır: uzunluk ve bölüntü. Uzunluk, sayıdaki tüm anlamlı rakamların, bölüntü ise ondalık noktadan sonraki rakamların adedidir.

Örneğin:

0.0000010 sayısının uzunluğu 7 ve bölüntüsü 6'dır.
01935.000 sayısının uzunluğu 7 ve bölüntüsü 3'tür.

Uzunluk açısından; en sağdaki sıfır anlamlı, en soldaki sıfır anlamsızdır.

Sayılar iki farklı türde değişken olarak saklanabilirler: basit değişkenler ve diziler. Her iki değişken türü için de değişkenlere birer ad verilir. Değişkenler bir harfle başlarlar ve sonrasında harfler, rakamlar ve altçizgi karakteri içerebilirler. Tüm harfler küçük harf olmak zorundadır. (Değişkenlere uzun isim verebilme bir genişletmedir. Çünkü, POSIX bc'de değişken isimleri tek bir küçük harftir.) Dizi değişkenleri ise isimden sonra [] (köşeli parantezler) alırlar.

bc'de dört tane özel değişken vardır. Bunlar; scale, ibase, obase ve last'dır. scale, işlemlerde sayılarda ondalık noktadan sonra kaç tane rakamın kullanılacağını belirtir. Öntanımlı scale değeri 0'dır. ibase (input base) ve obase (output base) değişkenleri, sayılarda girdi ve çıktı için tabanları belirtir. Örneğin, ibase=10 ve obase=2 olursa sayılar onluk tabanda girilir ve sonuçlar ekrana ikilik tabanda yazdırılırlar. Öntanımlı ibase ve obase değerleri 10'dur. last değişkeni (bu bir genişletmedir) ise, en son ekrana yazdırılan sayıyı içeren bir değişkendir. Bu değişkenlere yeni değerler atanabilir. Bunlar ileride daha ayrıntılı olarak ele alınacaktır.

bc'de açıklama satırları /* karakterleri ile başlar ve */ karakterleri ile biter. Açıklamalar herhangi bir yerde başlayabilir ve girdide tek bir boşluk gibi ele alınır. (Yani, bu da açıklamaların girdi elemanları arasında bir ayraç olarak yorumlandığını gösterir. Dolayısıyla, bir değişken ismi içerisinde açıklama yer alamaz anlamındadır.) Açıklamalar satırsonu karakteri içerebilirler.

Ayrıca bc'de betiklerin kullanılmasını sağlamak için tek satırlık açıklamalar desteklenmektedir ve bu bir genişletmedir. Tek satırlık açıklama # karakterinden sonra başlar ve satır sonuna kadar devam eder. Satırsonu karakteri açıklamaya dahil değildir ve normal karakter olarak ele alınır.

İFADELER

Sayılar, ifadelerle ve deyimlerle birlikte kullanılırlar. Bu dil, etkileşimli bir çalışma ortamı olarak tasarlandığı için deyimler ve ifadeler de etkileşimli olarak işletilebilirler. bc'de bir 'main' işlevi kavramı yoktur. Bunun yerine kod, olduğu haliyle hemen yorumlanarak işletilir. (İşlevler, önce tanımlanırlar ve sonradan kullanılabilirler -ileride ele alınacaklar-).

En basit ifade bir 'sabit'tir. bc, ibase değişkeniyle belirtilen o anki girdi tabanını kullanarak sayıyı dahili onluk tabana çevirir. (Ancak, işlevler için bir istisna vardır.) ibase değişkeninin geçerli değerleri 2'den 16'ya kadardır. Bu aralığın dışında değerler atanırsa kendiliğinden 2 veya 16 olarak yeniden ayarlanır. Sayılar girilirken, 0-9 arası rakamlar ve A-F arası harfler ile kullanılabilir. (Not: A-F büyük harf olmalıdır. Çünkü, küçük harfler değişkenler için kullanılıyorlar.) Tek rakamlı sayılar, ibase ne olursa olsun, her zaman rakamın ifade ettiği değere sahip olurlar (örn, A=10)). bc çok rakamlı sayılarda, ibase değerine eşit veya daha büyük rakamları derhal ibase-1 tabanında ele alarak sayının değerini hesaplar. Bu FFF sayısını daima, girdi tabanındaki en büyük 3 haneli sayı yapar.

İfadeler, diğer yüksek-düzeyli dillerdekilere oldukça benzerler. bc'de sayılar için farklı türler olmadığı için karışık türler için kurallar yoktur. Bunun yerine, sadece ifadelerin bölüntüleri üzerine kurallar vardır. Her ifadenin bir bölüntüsü vardır. Bu, orijinal sayıların bölüntülerinden, gerçekleştirilen işlemden ve çoğu durumda da scale değişkeninin değerinden elde edilir. scale değişkeninin alabileceği değerler, 0 (sıfır) ile C'deki tamsayı türü ile ifade edilebilen tamsayı aralığındadır.

Aşağıdaki geçerli ifadelerin açıklamalarında "ifade" komple bir ifadeyi ve "değişken" ise sıradan bir değişkeni veya bir dizi değişkenini göstermektedir. Bir basit değişken

isim

şeklinde ve bir dizi değişkeni ise aşağıdaki gibi belirtilir:

isim[ifade]

Özel olarak söz edilmediyse sonucun bölüntüsü, ilgili ifadelerin azami bölüntüsü olur.

Sonuç, ifade'nin negatifi olur.

++değişken
değişken'in değerine önce 'bir' eklenir ve yeni değer ifadenin sonucu olur.

değişken'in değeri önce 'bir' eksiltilir ve yeni değer ifadenin sonucu olur.

İfadenin sonucu değişkenin değerine göre hesaplanır, sonra değişken'in değeri 'bir' artırılır.

İfadenin sonucu değişkenin değerine göre hesaplanır, sonra değişken'in değeri 'bir' eksiltilir.

Sonuç, iki ifade'nin toplamıdır.

Sonuç, iki ifade'nin farkıdır.

Sonuç, iki ifade'nin çarpımıdır.

Sonuç, iki ifade'nin bölümüdür. Sonucun bölüntüsü scale değişkeninin değeridir.

Sonuç, "kalan"ı verir ve şu şekilde hesaplanır. a%b'yi hesaplarken, ilk önce a/b scale haneli olarak hesaplanır. scale+scale(b) ve scale(a)'dan hangisi daha büyükse bu bölüntüye göre a-(a/b)*b ifadesi sonucu hesaplamak için kullanılır. Eğer scale 0'a eşitlenirse ve her iki ifade de tamsayı ise, bu ifade tamsayı kalan işlevidir.

İfadenin sonucu, birincinin ikinciye göre üssüdür. İkinci ifade bir tamsayı olmalıdır. (Eğer ikinci ifade tamsayı değilse, önce ekrana bir uyarı gelir ve ifade tamsayı olacak şekilde kesilir, yani ikinci ifadenin tam kısmı alınır). Sonucun bölüntüsü ise, eğer üs negatif ise scale'dir. Üs pozitif ise scale(a^b) = min(scale(a)*b, max(scale, scale(a)))'dır. Unutulmamalıdır ki ifade^0 ifadesinin sonucu her zaman "1" olur.

( ifade )
Parantezler, ifadenin değeri bulunurken standart önceliği değiştirir ve parantez içine alınan ifade daha önce hesaplanır.

İfadenin sonucu değişkene atanır.

Bu, "değişken = değişken <işleç> ifade" ile eşdeğerdir ancak bir farkla; değişken'in değeri sadece bir kere elde edilir. Eğer değişken bir dizi ise, işlemin bir kere yapılacağı gözden uzak tutulmamalıdır.

İlişkisel ifadeler (karşılaştırma ifadeleri), sonuçları her zaman 0 veya 1 olan özel ifadelerdir. 0, yanlış (false) ve 1, doğru (true) olarak yorumlanır. Bunlar herhangi bir ifade içerisinde yer alabilirler. (POSIX bc'de ise ilişkisel ifadeler sadece if, while ve for deyimlerinde kullanılabilir ve sadece bir tane ilişkisel sınama olabilir.) İlişkisel işleçler şunlardır:

Sonuç, eğer ifade1, ifade2'den küçükse 1 olur. Aksi halde 0 olur.

Sonuç, eğer ifade1, ifade2'den küçük ya da eşitse 1 olur. Aksi halde 0 olur.

Sonuç, eğer ifade1, ifade2'den büyükse 1 olur. Aksi halde 0 olur.

Sonuç, eğer ifade1, ifade2'den büyük ya da eşitse 1 olur. Aksi halde 0 olur.

Sonuç, eğer ifade1, ifade2'ye eşitse 1 olur. Aksi halde 0 olur.

Sonuç, eğer ifade1, ifade2'den farklıysa 1 olur. Aksi halde 0 olur.

bc'de mantıksal (boolean) işlemler de geçerlidir. (POSIX bc'de mantıksal işlemler yoktur.) Mantıksal işlemlerin sonucu, ilişkisel işlemlerde olduğu gibi, 0 (false) yada 1 (true) olmaktadır. Mantıksal işleçler şunlardır:

!ifade
ifade 0 ise sonuç 1'dir. Aksi halde 0 olur.

ifade'lerin ikiside sıfırdan farklıysa sonuç 1'dir. Aksi halde 0 olur.

ifade'lerden biri sıfırdan farklıysa sonuç 1'dir. Aksi halde 0 olur.

İşleçlerin işlem öncelik sırası şöyledir (küçükten büyüğe):

|| işleci, önce sol taraf
&& işleci, önce sol taraf
! işleci, tarafsız
İlişkisel işleçler, önce sol taraf
Atama işleci, önce sağ taraf
+ and - işleci, önce sol taraf
*, / ve % işleci, önce sol taraf
^ işleci, önce sağ taraf
tek terimli - işleci
++ ve -- işleci

Bu önceliğin seçilmesinin nedeni, POSIX uyumlu bc yazılımlarının doğru çalışması içindir. Ancak, ilişkisel ve mantıksal işleçler, atama ifadelerinde kullanıldığında elverişsiz ve çok farklı bir durum ortaya çıkmaktadır. Aşağıdaki ifadeyi ele alalım:

a = 3 < 5

C programcıları bu ifadeyi ele alırken, önce 3<5 (sonuç 1'dir) ifadesini gerçekleştirir, ardından sonucu "a" değişkenine atarlar. bc'de ise önce "a"ya 3 atanır ve ardından 5 ile karşılaştırma yapılır. Buna dikkat etmek gerekir. En iyisi, ilişkisel ve mantıksal işleçler ile atama işleci aynı ifadede kullanıldığında karmaşayı önlemek için parantezleri kullanmaktır.

bc'de desteklenen biraz daha özel ifadeler vardır. Bunlar, standart işlevler ve kullanıcı tanımlı işlevlerde, "isim(parametreler)" şeklinde görülmektedirler. Ayrıntılı bilgi için İŞLEVLER bölümündeki kullanıcı tanımlı işlevlere bakınız. Yerleşik işlevler şunlardır:

length işlevinin değeri, ifade'deki anlamlı rakamların adedidir.

read işlevi (bu bir genişletmedir), nerede kullanıldığına bakılmaksızın, standart girdiden bir sayı okumak için kullanılır. Ancak, standart girdiden veri ve yazılım birlikte okunurken problemlere neden olabileceğinden dikkatli olmak gerekir. Bu işlevin en iyi kullanım şekli, asla kullanıcıdan kod girmeyi gerektiren yerlerde değil, evvelce geliştirilen bir yazılım için kullanıcıdan bir girdi bekleyen yerlerde kullanmaktır. read işlevinin değeri, standart girdiden okunan sayının ibase tabanındaki değeridir.

scale işlevinin değeri, ifade'denin sonucu olan sayıdaki ondalık hanelerin sayısıdır.

sqrt işlevinin değeri, ifade'nin kareköküdür. ifade'nin sonucu negatif bir sayı ise bir çalışma anı hatası üretilir.

Deyimler, birçok cebirsel dilde olduğu gibi, ifadelerin sırayla değerlendirilmelerini sağlarlar. bc'de deyimler "mümkün olduğunca" işletilirler. İşletim, bir ya da daha fazla tam deyimden sonra bir satırsonu karakteri girildiğinde gerçekleşir. Bu bakımdan bc'de satırsonu karakterleri çok önemlidir. Aslında, deyimleri ayırmak için bir satırsonu karakteri ve bir noktalı virgül gerekir. Yanlış yerde kullanılmış bir satırsonu karakteri bir sözdizimi hatasına sebep olur. Satır sonu karakteri deyimler için bir ayraç olduğundan, bir satır sonu karakterini gizlemek için ters bölü karakteri kullanılabilir. Tersbölü karakterinden sonra gelen bir satırsonu karakterinden oluşan karakter çiftini bc boşluk karakteri olarak değerlendirir. Bir deyim listesi, noktalı virgül ve satırsonu karakteri ile sonlandırımış deyimlerden oluşur. Aşağıdaki listede bc'deki deyimler ve bunların ne yaptıkları anlatılmaktadır (Köşeli parantezler ([ ]) arasına alınanlar, deyimin isteğe bağlı kısımlarıdır.):

Bu deyim iki şeyden birini yapar. Eğer ifade "<değişken> <atama> ..." şeklinde başlıyorsa, bunun bir atama deyimi olduğunu kabul eder. Eğer ifade bir atama deyimi değil ise, ifade'nin değeri bulunur ve çıktıya yazdırılır. Sayının ardından satırsonu karakteri yazdırılır. Örneğin, a=1 ifadesi bariz bir atama deyimidir; ve (a=1) içinde bir atama deyimi olan bir ifadedir. Çıktılanan tüm sayılar obase değişkeni ile belirtilen tabanda yazdırılırlar. obase değişkeninin alabileceği değerler 2 ile BC_BASE_MAX arasındadır. (Ayrıntılı bilgi için SINIRLAR bölümüne bakınız.)

2 ile 16 arasındaki tabanlar için çıktı bildiğimiz yöntemle yazdırılır. 16'dan daha büyük tabanlar için ise, bc her bir haneyi yazdırmak için 10'luk tabanda birden çok karakter kullanır ve haneler arasında boşluk bırakır. Her hane, obase-1 değerini 10'luk düzende yazmak için gereken sayı kadar rakamdan oluşur. Örneğin, obase=20 için 65 sayısı ekrana "03 05" şeklinde yazdırılır. Eğer obase=101 olsaydı, 25 sayısı ekrana "025" şeklinde yazdırılacaktı. Sayılar keyfi duyarlılıkta ele alındıkları için, bazı sayılar ekrana yazdırılırken tek bir satıra sığmayabilirler. Bu uzun sayılar yazdırılırken ekrana satırların sonuna "\" (tersbölü) karakteri gelir. Her bir satırda en fazla 70 karakter yazdırılabilir. bc'nin etkileşimli doğasından dolayı yazılan en son değer, özel last değişkeninde saklanır ki aynı sayıyı bir daha elde etmek için bir önceki ifade'yi tekrar yazmaya gerek kalmaz. last değişkenine atama yapılması da geçerlidir ve atanan değer son yazılan değerin üzerine yazılır. Yeni atanan değer, yeni bir değer yazılana kadar ya da last değişkenine yeni bir atama yapılana kadar geçerli kalır. (Bazı kurulumlar last için bir kısaltma olarak bir sayının parçası olmayan tek bir nokta (.) kullanımını mümkün kılabilir.)

dizge çıktıya yazdırılır. Çift tırnak "..." arasına alınan her şey (satırsonu karakteri de dahil) dizge olarak kabul edilir ve ekrana aynen yazdırılırlar. dizge yazdırıldıktan sonra satırsonu karakteri yazdırılmaz (yani aşağı satıra geçilmez, bu nedenle satırsonu karakteri dizge'nin içine yerleştirilmelidir).

print deyimi (bu bir genişletmedir) çıktıya birşeyler yazdırmak için kullanılan diğer bir yöntemdir. liste parametresi zorunludur, aralarına virgül (,) konularak dizgelerden ve ifadelerden oluşur. liste'deki her bir dizge veya ifade, yazıldıkları sıraya göre ekrana yazdırılır. Eğer belirtilmediyse satır sonunda satırsonu karakteri yazdırılmaz. İfadelerin değerleri bulunduktan sonra sonuçları ekrana yazdırılır. Bu esnada ekrana en son yazdırılan sayının değeri last değişkenine atanır. print deyimi içindeki dizgeler çıktıya yazdırılır ve özel anlamı olan karakterleri de içerebilirler. Özel karakterler tersbölü karakteri ile başlar. bc tarafından tanınan özel karakterler; "a" (uyarı; bip sesi), "b" (gerisilme), "f" (sayfa ileri), "n" (satırsonu), "q" (çift tırnak), "t" (sekme) ve "\" (tersbölü) karakterleridir. Bunların dışındaki karakterler gözardı edilir.

{ deyim_listesi }
Bu, bir birleşik deyimdir. Bu yapı, birden çok deyimi gruplandırarak birlikte çalıştırmak için kullanılır. Deyimler arasında yukarıda anlatılan ayraçlar yer alırlar.

if deyimi ifade'nin değerini bulur ve iifade'nin sonucuna göre deyim1'i veya deyim2'yi çalıştırır. ifade'nin sonucu sıfırdan farklı ise deyim1 işletilir. Eğer deyim2 belirtilmişse ve ifade'nin sonucu da sıfır ise, deyim2 işletilir (else sözcüğü bir genişletmedir).

while deyimi, ifade'nin değeri sıfırdan farklı olduğu müddetçe deyim'i tekrar tekrar işletir. Döngüde her yinelemede önce ifade'nin değeri bulunur, sonuç sıfırdan farklı ise deyim işletilir. ifade'nin sıfır olması durumunda veya çıkmak için break deyimi kullanıldığında döngü sonlanır.

for deyimi, deyim'in tekrar tekrar çalıştırılmasını sağlar. İlk başta (yani döngü başlamadan önce) ifade1 işletilir. Döngüde her yinelemede deyim işletilmeden önce ifade2'nin değeri bulunur. Eğer sonuç sıfırdan farklı ise deyim yerine getirilir, eğer sonuç sıfır ise döngü sonlandırılır. Döngüde deyim yerine getirildikten sonra ifade3 işletilir ve ardından ifade2'nin değeri tekrar bulunur. Ta ki ifade2'nin değeri sıfır oluncaya kadar... Döngüyü daha erken sonlandırmak için break deyimi kullanılabilir. Eğer ifade1 veya ifade3 kullanılmamışsa, bu noktada değerlendirilecek hiçbir şey olmadığından bir şey yapılmaz. Eğer ifade2 kullanılmamışsa, ifade2'nin değeri 1 olarak kabul edilir. (POSIX bc'de her üç ifadeyi de belirtmek mecburidir. Bunların seçimlik kullanılması, bir genişletmedir.) for deyimine karşılık gelen deyimler şunlardır:

ifade1;
while (ifade2) {
  deyim;
  ifade3;
}

İçinde yer aldığı son while veya for döngüsünü sonlandırır.

continue deyimi, (bir genişletmedir) içinde yer aldığı son for döngüsünü kendinden sonra gelen deyimler işletilmeden sonraki yinelemeden başlatır.

halt deyimi, (bir genişletmedir) bc'yi sonladırır. quit'ten farkı, halt deyimi kesinkes değil, şart sağlandığında çalışır. Örneğin, "if (0==1) halt" deyimi bc'yi sonladırmaz; çünkü şart sağlanmadığı için halt deyimi işletilmez.

Bir işlevden 0 (sıfır) döndürerek çıkar. (Ayrıntılı bilgi için İŞLEVLER bölümüne bakınız.)

Bir işlevden ifade'nin değerini döndürerek çıkar. (Ayrıntılı bilgi için İŞLEVLER bölümüne bakınız.) Bir genişletme olarak parantezler gerekli değildir.

Yardımcı deyimler, bildiğimiz klasik anlamda işletilebilir deyimler değildirler. Bunlar "derleme" zamanında ele alınırlar.

bc'nin yerel sürümü tarafından zorlanan yerel sınırları basar. Bu bir genişletmedir.

Her nerede ve her ne şekilde kullanılırsa kullanılsın, bc'yi kesinkes sonlandırır. Örneğin, "if (0==1) quit" deyimi, şart sağlanmasa da bc'yi sonlandıracaktır.

Uzun bir garanti iletisi basar. Bu bir genişletmedir.

İŞLEVLER

İşlevler, daha sonra çalıştırılmak üzere hesaplamaların tanımlandığı bir yöntem sunar. bc'deki işlevler daima bir değer hesaplayıp bunu çağrıcıya döndürürler. İşlev tanımları "özdevimli"dir; yani, girdide saptanana kadar bir işlev tanımsızdır. Bu tanımlama, aynı isimde yeni bir işlev tanımlanıncaya kadar geçerlidir. Yeni işlev tanımı eskisinin yerine geçer. Bir işlev aşağıdaki gibi tanımlanır.

define isim ( parametreler ) { satırsonu
      auto_listesi   deyim_listesi }

Bir işlev çağrısı ise "isim(parametreler)" biçiminde bir ifadedir.

Parametreler sayılar ya da dizilerdir (dizi parametreler bir genişletmedir). İşlev tanımında sıfır ya da daha fazla sayıda parametre verilebilir ve bunlar aralarına virgül konularak ayrılmış isimlerden oluşan bir liste olarak tanımlanır. Sayılar sadece değerleriyle çağrılan parametrelerdir. Diziler ise sadece değişkenleriyle çağrılırlar. Diziler, parametre tanımında "isim[]" şeklinde belirtilir. İşlev çağrısında asıl parametreler, sayı türünde ifadelerdir. Aynı yazım şekli, dizi parametrelerin tanımı olarak dizilerin aktarılmasında da kullanılır. Bir isimli dizi bir işleve değişkeni ile aktarılır. İşlev tanımları özdevimli olduklarından, parametre sayısı ve türleri işlev çağrıldığında kontrol edilir. Parametrelerin sayısı ve türlerindeki herhangi bir uyumsuzluk bir çalışma anı hatasına sebep olur. Ayrıca, tanımsız bir işlevin çağrılması da bir çalışma anı hatasına sebep olacaktır.

auto_listesi, "yerel" kullanım için isteğe bağlı bir değişken listesidir. auto_listesi'nin (eğer varsa) sözdizimi "auto isim, ... ;" şeklindedir (Sondaki noktalı virgül isteğe bağlıdır). Her isim bir auto değişkenin ismidir. Diziler, parametrelerde kullanılan sözdizimi ile belirtilebilir. Bu değişkenlerin sıfır ile ilklendirilerek, değerleri, işlevin başlangıcında yığıta basılır ve işlevin icrası boyunca kullanılır. İşlevden çıkışta bu değerler yığıttan çekilir, böylece değişkenler işlevin başlangıcındaki ilk değerlerine dönmüş olur. Parametreler gerçekte, işlev çağrısı sırasında ilklendirilen auto değişkenlerdir. auto değişkenler, geleneksel yerel değişkenlerden farklıdır. A işlevi, B işlevini çağırdığında, A işlevinin auto değişkenlerine, B işlevinde onlar auto değişkenler olarak çağrılmadıkça, B işlevi aynı isimlerle erişebilir. auto değişkenler ve parametreler yığıta basıldıklarından dolayı bc kendini çağrılan işlevleri destekler.

İşlevin gövdesi bir bc deyimleri listesidir. Tekrar belitelim ki, deyimler noktalı virgül ve satırsonu karakterleri ile birbirlerinden ayrılır. return deyimi işlevin sonlandırılmasına sebep olur ve bir değer döndürür. return deyiminin iki sürümü vardır. ilk şeklinde "return" ifadesi işlevi çağıran ifadeye sıfır değerini döndürür. İkinci şeklinde, "return ( ifade )", ifade'nin değeri hesaplanıp çağıran ifadeye sonucu döndürülür. Her işlevin sonunda kendiliğinden bir return(0) vardır. Böylece bir işlevin sonunda açıkça bir return deyimi kullanmaya gerek kalmaksızın işlev sıfır değeri döndürerek sonlanır.

İşlevler ayrıca, ibase değişkeninin kullanımını da değiştirir. İşlev gövdesindeki tüm sabitler, işlev çağrısı sırasında ibase değişkeninin değeri kullanılarak dönüştürülür. Sayıların dönüşümü için daima ibase'in o anki değerini kullanan yerleşik read işlevi dışında, işlev icrası sırasında ibase değişiklikleri gözardı edilecektir.

Bir geliştirme olarak, tanım biçimi pek az esnektir. Standart, işlev gövdesini oluşturan ilk kuyruklu ayracın define ile aynı satırda olmasını ve kalan her şeyin alt satırlarda olmasını gerektirir. bc'nin bu sürümünde ilk kaşlı ayraçın öncesinde ya da sonrasında satırsonu karakteri kullanabilmeyi mümkün kılar. Örneğin aşağıdaki tanımlar geçerli tanımlardır:

define d (n) { return (2*n); }
define d (n)
  { return (2*n); }

bc, -l seçeneği ile çalıştırıldığında math kütüphanesini yükler ve öntanımlı bölüntü 20 yapılır. math işlvleri, çağrıldıkları sırada geçerli olan bölüntüye göre sonuç döndürürler. math kütüphanesi aşağıdaki işlevleri tanımlar:

Radyan cinsinden verilen x'in sinüsü.

Radyan cinsinden verilen x'in kosinüsü.

x'in arktanjantı; radyan cinsinden döner.

x'in tabii logaritması.

e üssü x.

x tamsayısına göre n. dereceden Bessel işlevi.

ÖRNEKLER

/bin/sh'da aşağıdaki atama, kabul değişkeni pi'ye pi değerini atar.

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

Aşağıdaki örnekte, math kütüphanesinde kullanılan üstel işlevin tanımı vardır. Bu işlev POSIX bc'de yazılmıştır.

scale = 20
/* e^x = (e^(x/2))^2 formülü kullanılıyor
  x yeterinde küçükse, bu seriyi kullanabiliriz:
    e^x = 1 + x + x^2/2! + x^3/3! + ...
*/
define e(x) {
  auto  a, d, e, f, i, m, v, z
  /* x'in işaretine bakalım. */
  if (x<0) {
    m = 1
    x = -x
  }
  /* x için önkoşul. */
  z = scale;
  scale = 4 + z + .44*x;
  while (x > 1) {
    f += 1;
    x /= 2;
  }
  /* Değişkenleri ilklendirelim. */
  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şağıdaki örnekte, çek defteri (checkbook) bakiyelerini hesaplayan basit bir yazılım verilmektedir. Yazılımı bir kez yazarak bir dosyaya kaydedebilirsiniz ve sonraları her seferinde yeniden yazmaksızın istediğiniz zaman kullanabilirsiniz.

scale=2
print "\nÇek defteri yazılımı!\n"
print "  Hatırlatma: Depozitolar negatif miktarlardır.\n"
print "  Çıkış için 0 yazın.\n\n"
print "Başlangıçtaki bakiye? "; bal = read()
bal /= 1
print "\n"
while (1) {
  "şu anki bakiye = "; bal
  "çekilecek miktar? "; trans = read()
  if (trans == 0) break;
  bal -= trans
  bal /= 1
}
quit

Aşağıdaki örnekte ise, kendi kendini çağıran bir faktöriyel hesaplama işlevi tanımlanmaktadır.

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

GNU bc (bir yapılandırma seçeneği ile), GNU readline kütüphanesini ya da BSD libedit kütüphanesini kullanacak şekilde derlenebilir. Bu ise kullanıcıya, bc'ye göndermeden önce birden çok satır üzerinde düzenleme yapma imkanı sunar. Ayrıca, daha önceden girilen satırlar için bir geçmiş de tutar. Bu seçenek seçilirse, bc bir özel değişkene daha sahip olur. Bu özel history değişkeni, bellekte tutulacak satır sayısını tutar. -1 değeri sınırsız (bellek yettiği müddetçe) sayıda eski komut tutulacağını belirtir ve varsayılan değeri 100'dür. Eğer pozitif bir tamsayı belirtilirse, liste bu belirtilen sayı ile sınırlandırılmış olur. 0 değeri ise liste tutulmayacağını belirtir.

Daha ayrıntılı bilgi için, GNU readline, history kütüphanesi ile BSD libedit kütüphanesi hakkındaki belgeleri okuyunuz. bc, readline ve libedit kütüphaneleri aynı anda etkin olacak şekilde derlenemez.

bc'nin bu sürümü, POSIX P1003.2/D11 taslağından uyarlanmıştır ve taslağa göre ve geleneksel bc uygulamalarına göre bir takım farklılıklar sözkonusudur. dc(1)kullanılan geleneksel yolla gerçekleştirilmemiştir. Bu sürüm, yazılımın kodlarını ayrıştırarak bayt koda çevirdikten sonra tek bir süreç olarak çalıştırır. Komut satırından verilen ve belgelendirilmemiş -c seçeneği ile, yazılım çalıştırılmaz, onun yerinee bayt kodları ekrana listelenir. Bu, aslında etkileşimli olarak ayrıştırıcının hatalarını görmek/gidermek ve math kütüphanesini hazırlamak için kullanılır.

POSIX bc'deki farklılıkların yanında bir de yeni özellikler eklenmiştir, bunlara da genişletmeler demekteyiz. Aşağıda, bahsedilen farklılıkların ve genişletmelerin bir listesi yer almaktadır:

Bu sürüm LANG ve LC_ ile başlayan ortam değişkenlerinin işlenmesinde POSIX standardına uyumlu değildir.

Geleneksel ve POSIX bc değişkenler, diziler ve işlevler için sadece tek harften oluşan isimleri mümkün kılar. GNU bc'de bu isimler için çok karakterli isimler kullanılabilir. Bir isim bir harf ile başlar ve harfler, rakamlar ile altçizgi karakterini içerebilir.

Dizgelerde boş karakter kullanılmasına izin verilmez, POSIX'e göre dizgelerde tüm karakterler kullanılabilmelidir.

POSIX bc'de bir last değişkeni yoktur. bc'nin bazı gerçeklemelerinde bunun yerine nokta (.) kullanılır.

POSIX bc'de karşılaştırmalar sadece if, while deyimlerinde ve for deyiminin ikinci ifadesinde kullanılabilir. Ayrıca bu deyimlerde sadece bir ilişkisel işleme izin verilir.

POSIX bc'de else sözcüğü yoktur.

POSIX bc'de tüm ifadelerin deyim içinde kullanılması gereklidir.

&&, ||, !
POSIX bc'de mantıksal işleçler yoktur.

POSIX bc'de read işlevi yoktur.

POSIX bc'de print deyimi yoktur.

POSIX bc'de continue deyimi yoktur.

POSIX bc, return ifadesinin parantez içine alınmasını gerektirir.

POSIX bc'de (şimdilik) dizi parametreler tamamen desteklenmemektedir. POSIX sözdiziminde, işlev tanımlarında dizilere izin veriliyor, ancak bir dizinin bir işleve parametre olarak aktarılması desteklenmiyor. (Bu, aslında gözden kaçan bir dikkatsizliğin sonucudur.) Geleneksel bc gerçeklemeleri, dizileri sadece elemanlarının değerleri ile çağırabilmektedirler.

POSIX bc ilk kaşlı ayracın define anahtar sözcüğünün bulunduğu satırda, auto anahtar sözcüğünün de alt satırında olmasını gerektirir.

=+, =-, =*, =/, =%, =^
POSIX bc bu "eski tarz" atama işleçlerinin tanımlanmasını gerektirmez. Bu sürüm bu "eski tarz" atamalara izin verebilir. limits deyimini kullanarak kurulu sürümün bu atamaları desekleyip desteklemediğini öğrenebilirsiniz. Eğer destekliyorsa, "a =- 1" atamasında a değişkenine -1 atanmayacak, a değişkeninin değeri bir eksiltilecektir.

bc'nin diğer gerçeklemeleri sayıların içinde boşluklara izin verir. "x=1 3" ataması, "x=13" olarak değerlendirilecektir. Aynı ifade bu sürümde bir sözdizimi hatasına sebep olacaktır.

çalıştırma ve hatalar
Bu bc, yazılım içerinde sözdizimi ve diğer hataların bulunması durumunda kodun işletilmesi konusunda diğer gerçeklemelere göre oldukça farklılıklar içermektedir. Eğer bir işlev tanımlarken bir sözdizimi hatası yapılmışsa, hata düzeltme mekanizması deyimin başlangıcını bulmaya çalışır, ilk hatalı satırı bulur ve satır numarasını ekrana yazar; sonra yine de işlevin geri kalan kısımlarını ayrıştırmaya devam eder. İşlev içinde birkez bile hata yapılmışsa, o işlev 'çağrılamaz' addedilir ve tanımsız olur.

Etkileşimli ortamda çalışırken bir sözdizimi hatası yapılırsa, bir uyarı gelir ve çalıştırılacak olan o anki blok geçersiz sayılır. İşletim bloğu, yazılışı tamamlanmış basit veya birleşik bir deyimden sonra satırsonu karakteri bulunan yapıdır. Örneğin,

a = 1
b = 2

iki ayrı işletim bloğudur. Ancak,

{ a = 1
  b = 2 }

tek işletim bloğudur. Oluşan herhangi bir çalışma anı hatası (error), o anki işletim bloğunu sonlandırır. Ancak, oluşan herhangi bir çalışma anı uyarısı (warning) işletim bloğunu sonlandırmaz.

Bir etkileşimli oturumda, SIGINT sinyali (genelde klavyeden Ctrl-C'ye basıldığında üretilir) o anda işletilmekte olan bloğun yarıda kesilmesine neden olur. Hangi işlevin yarıda kesildiğini belirten bir çalışma anı hatası ekrana yazdırılır. Ardından, tüm çalışma anı yapılarının "temizlenme"sinin ardından, bc'nin yeni girdiler almak için hazır olduğunu yazan bir mesaj belirir. Önceden tanımlanmış olan tüm işlevler ve auto-olmayan değişkenler bu noktadan önceki değerleriyle aynen kalırlar. Tüm auto değişkenler ve işlev parametreleri bu "temizleme" işlemi esnasında silinirler. Etkileşimli olmayan bir oturumda ise SIGINT sinyali,bc'nin çalışmasını sonlandırarak kontrolü sisteme devredecektir.

Aşağıda bc'nin işlem yapabileceği sınırlar verilmiştir. Bunlardan bazıları aslında her bir kurulum için farklı farklı olabilir. Bunların geçerli değerlerini öğrenmek için limits deyimini kullanın.

Azami çıktı tabanı, 999 dur. Azami girdi tabanı ise 16 dır.

Dizilerde indisleme sınırı, keyfi olarak 65535 olarak belirlenmiştir. Kurulumunuzda farklı olabilir.

Sayılarda ondalık noktadan sonraki hane sayısı INT_MAX ile sınırlanmıştır. Ayrıca ondalık noktadan önceki hane sayısı da INT_MAX ile sınırlanmıştır.

Dizgelerin içerebileceği karakter sayısı INT_MAX ile sınırlanmıştır.

üs
Üstel değerlerde üssün sınırı LONG_MAX'tır.

Basit değişken, dizi ve işlev isimlerinin her biri için eşsiz isim sayısı 32767 ile sınırlanmıştır.

bc tarafından tanınan ortam değişkenleri şunlardır:

-s seçeneği ile aynıdır.

Bu, bc'nin argümanları almak için kullandığı diğer bir mekanizmadır. Biçimi komut satırı argümanlarında olduğu gibidir. Bu argümanlar, belirtilen dosyalardan önce işlem görürler. Bu, kullanıcıya "standart" seçenekleri ayarlama imkanını sunar. Ortam değişkenlerinde belirtilen dosyalar tipik olarak içlerinde kullanıcının tanımladığı işlevler olan dosyalardır. Bu ayarlama ile artık, bc her çalıştırıldığında belirtilen dosyalar işleme sokulurlar.

Bu, sayılar ekrana yazdırılırken bir satırda kaç karakter olacağını belirten bir tamsayıdır. Uzun (yani, tek satıra sığmayan) sayılar için \ (tersbölü) ve satırsonu karakterleri bu miktara dahildir.

Eğer komut satırında belirtilen dosyalardan biri açılamazsa bc bunu raporlar ve hemen sonlanır. Ayrıca, derleme ve çalışma-anı hatalarında bunlar ekrana hata numaraları ile birlikte yazdırılırlar ve bu esnada açıklayıcı bilgiler verilir.

Hata bulma/düzeltme henüz çok iyi değil.

Hataları rapor etmek için konu alanına "bc" yazarak <bug-bc (at) gnu.org> adresine e-posta atınız.

Philip A. Nelson <philnelson (at) acm.org>

Yazar kodun sınanmasındaki geniş yardımlarından dolayı Steve Sommars'a <Steve.Sommars (at) att.com> teşekkürlerinin kabulünü rica ediyor. Bir çok öneride bulundu ve onun katılımıyla bu çok daha iyi bir ürün oldu.

ÇEVİRENLER

Adem Güneş <adem (at) alaeddin.cc.selcuk.edu.tr>, Eylül 1999, v1.04
Nilgün Belma Bugüner <nilgun (at) belgeler·gen·tr>, Ocak 2004, v1.06

12 Eylül 2000 bc v1.06