bc - Keyfî duyarlılıkta hesaplama dili
- bc
- [ -hlwsqv ] [ uzun-seçenekler ] [ dosya
... ]
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 bazı benzerlikler vardır. Komut
satırından belirtmek suretiyle kullanabileceğimiz
standart bir math kütüphanesine 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
bazı genişletmeler içermektedir. Komut
satırı seçenekleri, bu genişletmelerin bir
uyarı çıktılamasına veya reddedilmesine
neden olabilir. Bu belge, bu işlemci tarafından kabul edilen
dili açıklar. Genişletmeler yeri gelince
açıklanacaktır.
-
-h, --help
- Kullanım iletisi basar ve çıkar.
-
-i, --interactive
- Etkileşimli kipe geçilir.
-
-l, --mathlib
- Standart math kütüphanesini kullanıma
sokar.
-
-w, --warn
- POSIX bc’ye ek genişletmeler
için uyarılar verir.
-
-s, --standard
- Standart POSIX bc diline uygun olarak işlem
yapar.
-
-q, --quiet
- Normalde gelen, GNU bc hoş geldiniz iletisini
görüntülemez.
-
-v, --version
- 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 tabanda gerçekleştirilir. (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:
.000001 sayısının uzunluğu 6 ve bölüntüsü 6’dır.
1935.000 sayısının uzunluğu 7 ve bölüntüsü 3’tü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şken isimleri
bir harfle başlarlar ve sonrasında harfler, rakamlar ve
altçizgi karakteri içerebilirler. Tüm harfler
küçük harf olmak zorundadır. (Abece-sayısal
uzun isimler bir genişletmedir. Çünkü, POSIX
bc’de değişken isimleri tek bir
küçük harften ibaretttir.) Dizi
değişkenleri ise isimden sonra [] (köşeli
ayraç) alırlar.
bc’de dört tane özel değişken
vardır. Bunlar;
scale,
ibase,
obase ve
last’dır.
scale, işlemlerde 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, girdi ve çıktı
için sayı tabanlarını belirtir.
Örneğin,
ibase=10 ve
obase=2 olursa sayılar
onluk tabanda girilir ve sonuçlar ekrana ikilik tabanda
yazdırılır.
ibase ve
obase için
öntanımlı değer
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 olarak 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.)
Açıklamalar sınırlarını belirleyen
karakterler arasında satırsonu karakteri içerebilir.
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.
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şletilebilir.
bc’de
’
main’ yordam kavramı yoktur. Bunun yerine kod,
rastlandıkları sırayla hemen yorumlanarak
işletilir. (İşlevler, önce
tanımlanırlar ve sonradan kullanılabilir - ileride ele
alınacaktır).
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
36’ya kadardır (
16’dan sonrası
genişletmedir). Sayılar girilirken,
0-9 arası
rakamlar ve (ascii)
A-Z arası harfler ile kullanılabilir.
(Dikkat:
A-Z büyük harf olmalıdır.
Çünkü, küçük harfler
değişkenler için kullanılıyor.) Tek
rakamlı sayılar,
ibase ne olursa olsun, her zaman
rakamın ifade ettiği değere sahip olurlar (örn,
A = 9)).
bc çok rakamlı sayılarda,
ibase değerine eşit veya daha büyük
rakamları
ibase-1 değeriyle ele alarak
sayının değerini hesaplar. Bu
ZZZ
sayısını daima, girdi tabanındaki 3 haneli en
büyük sayı yapar.
İfadeler, diğer yüksek-düzeyli dillerdekilere
oldukça benzer.
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 için
kurallar vardır. Her ifadenin bir bölüntüsü
vardır. Bu, özgün 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 ile
C’deki tamsayı türü ile ifade edilebilen en
büyük tamsayı aralığındadır.
Aşağıdaki geçerli ifadelerin
açıklamalarında "
ifade" eksiksiz 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
şeklinde ve bir dizi değişkeni ise
aşağıdaki gibi belirtilir:
Özel olarak belirtilmemişse sonucun
bölüntüsü, ilgili ifadelerin azami
bölüntüsü olur.
-
- ifade
- Sonuç, ifade’nin negatifi olur.
-
++ değişken
-
değişken ’bir’
arttırılır ve yeni değer ifadenin sonucu olur.
-
-- değişken
-
değişken ’bir’
eksiltilir ve yeni değer ifadenin sonucu olur.
-
değişken ++
- İfadenin sonucu değişkenin
değerine atanır, sonra
değişken’in değeri ’bir’
artırılır.
-
değişken --
- İfadenin sonucu değişkenin
değerine atanır, sonra
değişken’in değeri ’bir’
eksiltilir.
-
ifade + ifade
- Sonuç, iki ifade’nin
toplamıdır.
-
ifade - ifade
- Sonuç, iki ifade’nin
farkıdır.
-
ifade * ifade
- Sonuç, iki ifade’nin
çarpımıdır.
-
ifade / ifade
- Sonuç, iki ifade’nin
bölümüdür. Sonucun
bölüntüsü scale
değişkeninin değeridir.
-
ifade % ifade
- 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.
-
ifade ^ ifade
- İfadenin sonucu, birinci üssü
ikincidir. İ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 sonuç, scale ile ilk ifadenin
bölüntüsünden büyük olanı
ile ilk ifadenin bölüntüsü çarpı
üs değerinden küçük
olanıdır, yani scale(a^b) = min(max(scale,
scale(a)), scale(a)*b)’dir. Unutulmamalıdır ki
ifade^0 ifadesinin sonucu her zaman "1" olur.
-
( ifade )
- Yaylı ayraçlar, ifadenin değeri
bulunurken standart önceliği değiştirir;
yaylı ayraçlar içine alınan ifade daha
önce hesaplanır.
-
değişken = ifade
- İfadenin sonucu değişkene
atanır.
-
değişken
<şlç> = ifade
- Bu, "değişken =
değişken <işlec>
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 alabilir. (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:
-
ifade1 < ifade2
- Sonuç, eğer ifade1,
ifade2’den küçükse 1
değilse 0 olur.
-
ifade1 <= ifade2
- Sonuç, eğer ifade1,
ifade2’den küçük ya da eşitse
1 değilse 0 olur.
-
ifade1 > ifade2
- Sonuç, eğer ifade1,
ifade2’den büyükse 1 değilse
0 olur.
-
ifade1 >= ifade2
- Sonuç, eğer ifade1,
ifade2’den büyük ya da eşitse 1
değilse 0 olur.
-
ifade1 == ifade2
- Sonuç, eğer ifade1,
ifade2’ye eşitse 1 değilse 0
olur.
-
ifade1 != ifade2
- Sonuç, eğer ifade1,
ifade2’den farklıysa 1 değilse 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 && ifade
-
ifade’lerin ikiside sıfırdan
farklıysa sonuç 1’dir. Aksi halde 0 olur.
-
ifade || ifade
-
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, soldan ilişkilendirmeli
&& işleci, soldan ilişkilendirmeli
! işleci, ilişkilendirme yok
İlişkisel işleçler, soldan ilişkilendirmeli
Atama işleci, sağdan ilişkilendirmeli
+ ve - işleci, soldan ilişkilendirmeli
*, / ve % işleci, soldan ilişkilendirmeli
^ işleci, sağdan ilişkilendirmeli
tek terimli - işleci, ilişkilendirme yok
++ ve -- işleci, ilişkilendirme yok
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:
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 yaylı ayraçları
kullanmaktır.
bc’de desteklenen biraz daha özel ifadeler vardır.
Bunlar, standart işlevler ve kullanıcı
tanımlı işlevlerde, "
isim(değişkenler )"
ş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 ( ifade )
-
length işlevinin değeri,
ifade’deki anlamlı hanelerin adedidir.
-
read ( )
-
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 sorunlara 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 ( ifade )
-
scale işlevinin değeri,
ifade’denin sonucu olan sayıdaki ondalık
hanelerin sayısıdır.
-
sqrt ( ifade )
-
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, çoğu cebirsel dilde olduğu gibi, ifadelerin
sırayla değerlendirilmelerini sağlarlar.
bc’de deyimler "mümkün olduğunca"
yürütülür. Yürütme, bir ya da daha
fazla tam deyimden sonra bir satır sonu karakteri girildiğinde
gerçekleşir. Yürütmenin anında
gerçekleşmesi bakımdan
bc’de satır
sonu karakterleri çok önemlidir. Aslında, deyimleri
ayırmak için bir noktalı virgül ve bir
satır sonu karakteri gerekir. Yanlış yerde
kullanılmış bir satır sonu karakteri bir
sözdizimi hatasına sebep olur. Satır sonu karakteri
deyimler için bir ayraç olduğundan, bir satırsonu
karakterini gizlemek için ters eğik çizgi
kullanılabilir. Ters eğik çizgiden sonra gelen bir
satır sonu karakterinden oluşan karakter çiftini
bc boşluk karakteri olarak değerlendirir. Bir deyim
listesi, noktalı virgül ve satır sonu 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 ayraçlar (
[ ]) arasına
alınanlar, deyimin isteğe bağlı
kısımlarıdır.):
- ifade
- Bir ifade iki şeyden birini yapar. Eğer ifade
" <değişken> <atama> ..."
şeklinde başlıyorsa, bir atama deyimi olduğu
kabul edilir. 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ır sonu karakteri
yazdırılır. Örneğin, a=1 ifadesi
bariz bir atama deyimidir; ve (a=1) ise 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ıda rakamdan oluşur. Örneğin,
obase=20 için 65 sayısı ekrana " 03
05" şeklinde yazdırılır.
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 durumda satırların sonuna
"\" (ters eğik çizgi) karakteri gelir. Her
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, böylece aynı
sayıyı bir daha elde etmek için bir önceki
ifade’yi tekrar yazmaya gerek kalmaz. last
değişkenine atama yapılabilir ve atanan değer
son yazılan değerin üzerine yazılır.
Yeni atanan değer, yeni bir değer ekrana 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
-
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ır. 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 liste
-
print deyimi (bu bir genişletmedir)
çıktıya birşeyler yazdırmak için
kullanılan başka bir yöntemdir. liste
zorunludur, aralarına virgül (,) konulmuş dizgelerden
ve ifadelerden oluşur. liste’deki her dizge veya
ifade, yazıldıkları sıraya göre ekrana
yazdırılır. Eğer belirtilmediyse
satırın sonunda satır sonu 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çerebilir. Özel karakterler ters
eğik çizgi karakteri ile başlar. bc
tarafından tanınan özel karakterler; "
a" (uyarı; bip sesi), " b" (geri
silme), " f" (sayfa ileri), "n"
(satır sonu), " q" (çift tırnak),
" t" (sekme) ve "\" (ters eğik
çizgi) karakterleridir. Bunların
dışındaki karakterler yok sayılır.
-
{ 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ır.
-
if ( ifade ) deyim1 [
else deyim2 ]
-
if deyimi ifade’nin değerini
bulur ve ifade’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 ( ifade ) deyim
-
whiledeyimi, 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 ( [ ifade1 ] ;
[ ifade2 ] ; [ ifade3 ]
) deyim
-
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 deyiminine eşdeğer kod şöyledir:
ifade1;
while ( ifade2 ) {
deyim;
ifade3;
}
-
- break
- İçinde yer aldığı son
while veya for döngüsünü
sonlandırır.
- continue
-
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
-
halt deyimi, (bir genişletmedir)
bc’yi sonladırır. quit’ten
farkı, halt deyimi kesinkes değil, koşul
sağlandığında
çalışır. Örneğin, " if
(0 == 1) halt" deyimi bc’yi hemen
sonladırmaz; çünkü koşul
sağlanmadığı için halt deyimi
işletilmez.
- return
- Bir işlevden 0 döndürerek
çıkar. (Ayrıntılı bilgi için
İŞLEVLER bölümüne
bakınız.)
-
return ( ifade )
- 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 yaylı
ayraçlar gerekli değildir.
Yardımcı deyimler, bildiğimiz klasik anlamda
işletilebilir deyimler değildirler. Bunlar "derleme"
sırasında ele alınırlar.
- limits
-
bc’nin yerel sürümü
tarafından zorlanan yerel sınırları basar. Bu
bir genişletmedir.
- quit
- 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.
- warranty
- Uzun bir garanti iletisi basar. Bu bir
genişletmedir.
İş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ı
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 ( değişkenler ) { satırsonu
auto_listesi deyim_listesi }
Bir işlev çağrısı ise "
isim( girdiler)" biçiminde bir
ifadedir.
girdiler sayı ya da dizi olabilir (dizi girdiler bir
genişletmedir). İşlev tanımında
sıfır ya da daha fazla sayıda girdi olabilir ve bunlar
aralarına virgül konularak ayrılmış
isimlerden oluşan bir liste olarak tanımlanır.
Sayılar sadece değerleriyle aktarılan girdilerdir.
Diziler ise sadece değişkenleriyle aktarılır. Dizi
değişkenleri "
isim[]" şeklinde
belirtilir. İşlev çağrısında
asıl girdiler, sayı türünde ifadelerdir.
Aynı yazım şekli, dizi değişkenleri
üzerinden dizilerin aktarılmasında da
kullanılır. Bir isimli dizi bir işleve
değişkeni ile aktarılır. İşlev
tanımları dinamik olduklarından, girdi
sayısı ve türleri işlev
çağrıldığında
değerlendirilir. Girdilerin 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 auto değişkenin ismidir. Diziler,
değişkenlerde kullanılan sözdizimi ile
belirtilebilir. Bu değişkenler 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. Bunlar
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
auto
değişkenler olarak bildirilmedikçe, B işlevi
aynı isimlerle erişebilir.
auto değişkenler
ve işlev değişkenleri yığıta
basıldıklarından dolayı
bc kendini
çağıran işlevleri destekler.
İşlevin gövdesi bir
bc deyimleri listesidir. Tekrar
belitelim, deyimler noktalı virgül ve satır sonu
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ı edilir.
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ü, ilk kaşlı ayraçın
öncesinde ya da sonrasında satır sonu karakteri
kullanabilmeyi mümkün kılar. Örneğin
aşağıdakiler geçerli tanımlardır:
define d (n) { return (2*n); }
define d (n)
{ return (2*n); }
İşlevler
void olarak tanımlanabilir. Void
işlevler değer döndürmediğinden
değer gerektiren yerlerde kullanılamaz. Void işlevler
girdi satırında kendisi tarafından
çağrıldığında herhangi bir
çıktı üretmez.
void
sözcüğü
define
sözcüğü ile işlev ismi arasına
yerleştirilir. Örneğin,
aşağıdakileri ele alalım:
define py (y) { print "--->", y, "<---", "\n"; }
define void px (x) { print "--->", x, "<---", "\n"; }
py(1)
--->1<---
0
px(1)
--->1<---
py void işlev olmadığından
py(1)
çağrısı isteneni bastıktan sonra
işlevin dönüş değerini basar.
İşlev bir
return deyimi içermediğinden
öntanımlı olan
return(0)’dan dolayı
0 değeri basılır.
px(1)) için void
işlev olduğundan
0 basılmaz.
Ayrıca, değişken dizisi içeren
çağrı da eklendi. Değişken dizisi
içeren çağrıyı bildirmek için
işlev tanımındaki dizi değişkeni "
* isim[]" sözdizimi ile
kullanılır. Dizideki değişkenlerin
değerleriyle çağrılması nedeniyle
işlev çağrısı aynı kalır.
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şlevleri,
ç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:
-
s (x)
- Radyan cinsinden x’in sinüsü.
-
c (x)
- Radyan cinsinden x’in kosinüsü.
-
a (x)
-
x’in arktanjantı; radyan cinsinden
döner.
-
l (x)
-
x’in doğal logaritması.
-
e (x)
-
e üssü x.
-
j (n, x)
-
x tamsayısına göre
n’inci dereceden Bessel işlevi.
/bin/sh’da aşağıdaki atama, kabuk
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 pozitif olmalı. */
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 bakiyelerini
hesaplayan basit bir yazılım verilmektedir.
Yazılım bir kez yazılıp bir dosyaya kaydedebilir
ve sonraları her seferinde yeniden yazmaksızın
gerektiği zaman kullanılabilir.
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 girdi düzenleme 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
öntanımlı 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 ve 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 yerine 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’den asıl farklılıklar, bir
özelliğin daha fazla işlevsellik eklemek için
genişletildiği genişletmeler ve yeni özelliklerin
eklendiği eklemelerdir. Aşağıda,eklemelerin ve
genişletmelerin bir listesi yer almaktadır:
- LANG
- Bu sürüm LANG ve LC_ ile
başlayan ortam değişkenlerinin işlenmesinde
POSIX standardına uyumlu değildir.
- isimler
- 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 ve
her isim bir harf ile başlar, harfler, rakamlar ile altçizgi
karakterini içerebilir.
- dizgeler
- Dizgelerde NUL karakter kullanılmasına izin
verilmez, POSIX’e göre dizgelerde tüm karakterler
kullanılabilmelidir.
- last
- POSIX bc’de bir last
değişkeni yoktur. bc’nin bazı
gerçeklemelerinde bunun yerine nokta (.) kullanılır.
- karşılaştırmalar
- 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.
-
if deyimi ve else
sözcüğü
- POSIX bc’de else
sözcüğü yoktur.
-
for deyimi
- POSIX bc’de tüm ifadelerin deyim
içinde kullanılması gerekir.
- &&, ||, !
- POSIX bc’de mantıksal
işleçler yoktur.
-
read işlevi
- POSIX bc’de read işlevi yoktur.
-
print deyimi
- POSIX bc’de print deyimi yoktur.
-
continue deyimi
- POSIX bc’de continue deyimi yoktur.
-
return deyimi
- POSIX bc, return ifadesinin yaylı
ayraç içine alınmasını gerektirir.
- diziler
- POSIX bc (şimdilik) dizi
değişkenlerini tamamen desteklememektedir. POSIX
sözdiziminde, işlev tanımlarında dizilere izin
veriliyor, ancak bir dizinin bir işleve değişken
olarak aktarılması desteklenmiyor. (Bu, aslında
gözden kaçan bir dikkatsizliğin sonucudur.)
Geleneksel bc gerçeklemelerinde, diziler sadece
değerleri ile aktarılabilmektedirler.
- işlev biçimi
- 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ı destekleyip
desteklemediğini öğrenebilirsiniz. Eğer
destekliyorsa, " a =- 1" atamasında a
değişkenine -1 atanmayacak, a
değişkeninin değeri bir eksiltilecektir.
- sayılardaki boşluklar
-
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ımlanırken 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 bir kez 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
küme geçersiz sayılır. İşletim
kümesi, yazılışı
tamamlanmış basit veya birleşik bir deyimden sonra
satırsonu karakteri bulunan yapıdır.
Örneğin,
- iki ayrı işletim kümesidir. Ancak,
- tek işletim kümesidir. Oluşan herhangi
bir çalışma anı hatası (error), o anki
işletim kümesini sonlandırır. Ancak,
oluşan herhangi bir çalışma anı
uyarısı (warning) işletim kümesini
sonlandırmaz.
- kesmeler
- Bir etkileşimli oturumda, SIGINT sinyali
(genelde klavyeden Ctrl-C’ye
basıldığında üretilir) o anda
işletilmekte olan kümenin 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"sinden sonra, bc’nin yeni girdiler
almak için hazır olduğunu yazan bir ileti 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
değişkenleri bu "temizleme" işlemi
esnasında silinirler. Etkileşimli olmayan bir oturumda ise
SIGINT sinyali, bc’nin
çalışmasını sonlandırır.
Aşağıda bu
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.
- BC_BASE_MAX
- Azami çıktı tabanı,
999’dur. Azami girdi tabanı ise 16’dır.
- BC_DIM_MAX
- Dizilerde indisleme sınırı, keyfi
olarak 65535 olarak belirlenmiştir. Kurulumunuzda farklı
olabilir.
- BC_SCALE_MAX
- 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.
- BC_STRING_MAX
- 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.
- değişken isimleri
- 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:
- POSIXLY_CORRECT
-
-s seçeneği ile aynıdır.
- BC_ENV_ARGS
- Bu, bc’nin girdi almak için
kullandığı diğer bir mekanizmadır.
Biçimi komut satırı girdileri ile
aynıdır. Bu ortam değişkenlerinde
listelenmiş dosyalar, komut satırında belirtilen
dosyalardan önce işlem görür. Bu,
kullanıcıya "standart" seçenekleri ve
dosyaları ayarlama imkanını sunar. Ortam
değişkenlerinde belirtilen dosyalar genellikle
içlerinde kullanıcının
tanımladığı işlevler olan ve
dosyalardır. Bu ayarlama ile artık, bc her
çalıştırıldığında
belirtilen dosyalar işleme sokulur.
- BC_LINE_LENGTH
- 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 \ (ters eğik çizgi) ve satırsonu
karakterleri bu miktara dahildir. Bu değişkene atanan
3’ten küçük değerler için
satır uzunluğu 70 yapılır.
Eğer komut satırında belirtilen dosyalardan biri
açılamazsa
bc bunu bildirir ve hemen sonlanır.
Ayrıca, derleme ve çalışma-anı
hatalarında bunlar ekrana hata numaraları ile birlikte
yazdırılır ve bu esnada
açıklayıcı bilgiler verilir.
Hata bulma/düzeltme henüz çok iyi değil.
Hataları bildirmek için konu alanına "bc" yazarak
<bug-bc (at) gnu.org> adresine e-posta atınız.
Philip A. Nelson tarafından yazılmıştır.
Telif hakkı © 2017 Free Software Foundation, Inc. Lisans GPLv3+:
GNU GPL sürüm 3 veya üstü
<
http://gnu.org/licenses/gpl.html> Bu bir özgür
yazılımdır: yazılımı
değiştirmek ve dağıtmakta
özgürsünüz. Yasaların izin verdiği
ölçüde HİÇBİR GARANTİ YOKTUR.
Yazar kodun sınanmasındaki geniş
yardımlarından dolayı Steve Sommars’a
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.
© 1999 Adem Güneş
© 2004, 2022 Nilgün Belma Bugüner
Bu çeviri özgür yazılımdır:
Yasaların izin verdiği ölçüde
HİÇBİR GARANTİ YOKTUR.
Lütfen, çeviri ile ilgili bildirimde bulunmak veya çeviri
yapmak için
https://github.com/TLBP/manpages-tr/issues adresinde
"New Issue" düğmesine tıklayıp yeni bir
konu açınız ve isteğinizi belirtiniz.