Aritmetik operatörler
ve kullanım şekilleri
Bilgisayarlar yapıları
gereği, çeşitli matematiksel hesaplamaları gerçekleştirirler. Bu
sebeple, C# ile temel matematiksel işlemlerin nasıl yapıldığını
inceleyelim. Temel matematiksel işlemler derken toplama, çıkarma,
çarpma ve bölme işlemlerini kastediyorum. Daha önceki bölümlerden,
toplama işleminin C#ta nasıl yapıldığını biliyoruz:
Bir tamsayıdan diğer
bir tamsayıyı çıkarmak da bu kadar kolaydır:
Yukarıda yaptığımız
işlemlerde kullandığımız artı ve eksi işaretlerinin her ikisi de
aritmetik işaretlerdir. Bu işaretlere aynı zamanda ikili operatör
de denilir. Bu durumda, bu işaretlere operatör, sağında ve solunda
bulunan ifadelere de operand denir. İkili operatör denmesi de,
işaretin sağında ve solunda iki tane operand bulunmasındandır.
Yukarıdaki iki örneği
incelersek, burada eksi işaretleri tekli operatördür. Çünkü bu
işaretler Bnin değerini işlem sırasında negatif yapmak için orada
bulunuyorlar ve sadece sağında bir operandı var.
Toplama işlemi için bir
ikili operatör olan artı işareti aynı zamanda tekli operatör
olarak da kullanılabilir.
Ama bu örnekte olduğu
gibi artı işaretinin değişkenin önünde olması hiçbir şeyi
değiştirmez. O yüzden sırf olabileceğini göstermek için yazdığım
bu tür bir ifadeyi daha sonra hiç yazmayacağım.
C#ta çarpma işlemi
yapmak istediğimizde çarpma için gerçek dünyada kullandığımız gibi
bir çarpı işaretinin olmadığını göreceksiniz. Bu işlemi asteriks
ile yapıyoruz. Asteriks işareti genelde bütün programlama
dillerinde çarpma için kullanılır.
Bazı programcılar
asteriks için yıldız kelimesini kullanır, ama Alan eşittir En
çarpı Boy demek istedikleri bellidir.
Klavyede bölme işlemi
için de, matematikteki bölme işareti yoktur. Bunun için bölü
işaretini kullanacağız.
Saat eşittir dakika
bölü altmış.
Bölme İşlemi ve Sıfıra
Bölünme Durumu
Dört temel matematiksel
işlemden kuşkusuz en zoru bölme işlemidir, çünkü tamsayılarla
bölme işlemi yaparken bir takım problemler ortaya çıkar.
Şimdi 3 tane ekmek var
ve bunu 2 kişi eşit paylaşacaklar diye düşünelim.
1 |
int ekmek, kisi, hak; |
2 |
ekmek = 3; |
3 |
kisi = 2; |
4 |
hak = ekmek / kisi; |
Bu örnekteki hak neye
eşittir? Kesinlikle 1.5 değil, çünkü hak değişkeni tamsayı olarak
tanımlanmış. ekmek ve kisi değişkenleri de tamsayı. Eğer gerçekten
1.5 çıksın istiyorsak o zaman başka yöntemler var, onları ilerde
tartışacağız.
Burada tamsayı olarak
sonuç çıkmasının nedeni, iki tane tamsayı arasında yapılacak
herhangi bir işlemin sonucunun yine tamsayı olması gerektiğidir.
Bu kuraldan dolayı C#, iki tamsayı arasında bölme işlemi
gerçekleştiğinde sonucun küsurat kısmını atar ve tamsayı kısmını
alır.
Küsurat kısmını atma
işlemi, negatif tamsayılarla işlem yaparken de gerçekleşir.
Aşağıdaki örnekte sonuç -1.5 değil, -1 olacaktır. Küsuratı atma
işlemine sıfıra yuvarlama da denir. Bir tamsayı bölme işleminde
sonuç, sıfıra en yakın olan bir sonraki tamsayıdır.
1 |
int ekmek, kisi, hak; |
2 |
ekmek = 3; |
3 |
kisi = 2; |
4 |
hak = ekmek / kisi; |
5 |
kalan = ekmek % kisi; |
İşlem sonucunda hak, 1
çıkacaktır. Her kişiye 1 tane ekmek düşüyor. kalan ise 1 ekmektir.
Kalanı bu şekilde elde edebiliriz. Negatif sayılarla yapılacak
kalan bulma işleminde ise sonuç her zaman % işaretinin solundaki
sayının işareti ile aynıdır.
Kalan operatörü ile
yapabileceğimiz güzel uygulamalar var. Bunlardan birkaçını
inceleyelim. Mesela 1995, 2005 gibi dört basamakla yazılan yılları
95, 05 gibi 2 basamaklı halde yazmak isteyebiliriz. Bu durumda
kalan operatörü işimize yarar.
1 |
IkiBasamakliYil = DortBasamakliYil % 100 ; |
Sonuç her zaman 00 ile
99 arasında olacaktır.
Sonuç her zaman 00 ile
99 arasında olacaktır.
Eğer bir işin sonucu
toplam dakika olarak verilmişse, bunu saat ve dakika olarak
ayırmak istersek, bunu kalan operatörü ile yapabiliriz.
Eğer bir işin sonucu
toplam dakika olarak verilmişse, bunu saat ve dakika olarak
ayırmak istersek, bunu kalan operatörü ile yapabiliriz.
1 |
Saat = ToplamSure / 60; |
2 |
Dakika = ToplamSure % 60; |
Bir sayının diğer bir
sayıya bölünüp bölünemeyeceği ile ilgili durumlarda da kalan
operatörü kullanılabilir. Artık yıl hesabı bu şeklide yapılır.
Eğer bir yıl dörde bölünebiliyorsa artık yıldır.
Eğer Yil % 4 ifadesi
sıfıra eşit olursa Yil sayısı dörde tam bölünüyor demektir ve
dolayısıyla artık yıldır.
Şimdi aşağıdaki ifadeyi
dikkatli inceleyelim. Bu işlemde bir problem var.
1 |
A
= 3; |
2 |
B
= 0; |
3 |
C
= A / B; |
Yukarıdaki bölme
işleminin sonucunda division by zero denilen istisna oluşur ve bu
işleme tamsayılarda izin verilmez. Şimdi aşağıdaki şekilde bu
örneği baştan yazalım ve sonucunu çalıştırıp görelim.
1 |
using System; |
2 |
class SifiraBolunme |
3 |
{ |
4 |
static void Main() |
5 |
{ |
6 |
|
7 |
int A, B, C; |
8 |
|
9 |
A = 3; |
10 |
B = 0; |
11 |
|
12 |
Console.WriteLine (A); |
13 |
Console.WriteLine (B); |
14 |
|
15 |
C = A / B; |
16 |
|
17 |
Console.WriteLine (C); |
18 |
} |
19 |
} |
Program çalıştığında
ekrana A ve B değişkenlerinin değerlerini yazar ve daha sonra
aşağıdaki pencere çıkar.
Eğer iptal seçersek
aşağıdaki pencere gelir.
Just In Time
Debugger penceresinden de no seçtikten sonra aşağıdaki ekran gelir
ve istisna, konsol ekranında görüntülenir.
C değişkenini ekrana
yazan Console.WriteLine ifadesi, program kesildiğinden dolayı
görüntülenmez.
Bir program, üç evreden
geçer. Yazma, derleme ve çalıştırma evreleri. Genelde program
hataları yazma evresinde yazım hataları olarak meydana gelir. Bu
örneğimizde ise çalıştırma evresinde ortaya çıkan bir istisna var.
Program çalışmaya başlıyor ve yarısına gelince kesiliyor.
Programı kesip ekrana
sebebini yazan sınıf ise System isim uzayındaki System.DivideByZeroException
sınıfıdır. Daha sonra, başka bir yazıda bu sınıfı kullanarak
oluşan istisna durumlarla başa çıkma yollarını inceleyeceğiz.
Eğer yukarıda
yazdığımız programda C = A / B ifadesini C = 3 / 0 haline getirip
yeniden derlersek derleyici aşağıdaki ekranda görülen hatayı
derleme evresinde algılayacak ve programı derlemeyecektir.
Şu ana kadar yaptığımız
aritmetik işlem örneklerinde hep iki tane sayı kullandık. Karmaşık
işlemleri de bir ifadede yazabiliriz.
1 |
using System; |
2 |
class IslemOnceligi1 |
3 |
{ |
4 |
static void Main() |
5 |
{ |
6 |
|
7 |
int A = 2, B = 4, C = 5; |
8 |
|
9 |
int D = A / B + C + 2*A; |
10 |
|
11 |
Console.WriteLine (D); |
12 |
} |
13 |
} |
Çarpma ve bölme
işlemlerinin toplama ve çıkarma işlemlerine göre önceliği vardır.
İşlemleri soldan sağa doğru incelersek, önce A/B işlemi meydana
gelir, 2*A işlemi hesaplanır ve sonuçta çıkan üç tane sayı
toplanır. Bölme ile çarpma işlemi aynı önceliğe sahiptir. Toplama
ile çıkarma da öyle. Eğer bunlardan ikisi, mesela bölme ve çarpma,
aynı ifadede yan yana gelirlerse, soldan sağa doğru bakılıp daha
solda olan daha önce yapılır.
Parantezin önceliği
çarpma ile bölme, toplama ile çıkarma işlemleri ile
kıyaslandığında daha yüksektir. O zaman, daha önce yapılmasını
istediğimiz işlemleri parantez içine almalıyız.
1 |
using System; |
2 |
class IslemOnceligi2 |
3 |
{ |
4 |
static void Main() |
5 |
{ |
6 |
|
7 |
int A = 2, B = 4, C = 5; |
8 |
|
9 |
int D = (A + B) + (C + 2*A C/(B A) ); |
10 |
|
11 |
Console.WriteLine (D); |
12 |
} |
13 |
} |
Yukarıdaki örnekte ilk
olarak en içteki parantez olan B A işlemi yapılır. Daha sonra
diğer parantezlerin içindeki işlemler, en sonunda da toplama ve
çıkarma yapılır.
Tekli artı ve eksi
operatörleri ise hem çarpma ile bölme, hem de toplama ile
çıkarmadan daha yüksek önceliğe sahiptir.
Eşittir operatörü ise
öncelik tablosunun en altındadır. Yaptığı iş, sağdaki ifadeyi
soldaki değişkene atamaktır. Bir ifade içerisinde birden fazla
eşittir operatörü kullanılabilir.
Yukarıdaki örnekte önce
C değişkeni 10 değerini alır, daha sonra B değişkeni C değişkenine
eşit olur, daha sonra da A değişkenine B değişkeni atanır.
Şimdi aşağıdaki ifadeyi
inceleyelim.
1 |
C
= (A = 10) + (B = 20); |
Önce A değişkeni 10, B
değişkeni de 20 değerlerini alır, daha sonra da C değişkenine
bunların toplamı atanır. Yukarıda görülen ifadeyi parantezleri
kullanmadan yazmak mümkün olmaz. Mümkün olamaması da toplama
işleminin atama işlemine göre önceliğinin olmasından kaynaklanır.
Çünkü, yukarıdaki ifadeyi aşağıdaki gibi yazdığımızda üçüncü
operand olan + işaretinin solundaki ifade değişken olmaz.
Yazmanın mümkün
olamayacağı diğer bir ifade de aşağıda görülen, hiçbir işlevi
olmayan ifadedir.
Programlama dillerinde,
bir değişkenin değerinin üzerine bir ilave yapmak, ya da bir
eksiltme yapmak ihtiyacı çok sık görülür.
1 |
ToplamOgrenciSayisi = KatilanOgrenciSayisi + IzinliOlanlar; |
Yukarıdaki ifadeyi
yazarken aynı değişken adını tekrar yazamktansa aşağıdaki gibi
yazmak mümkündür.
1 |
ToplamOgrenciSayisi += IzinliOlanlar; |
Bu örnekteki +=
operatörlerine birlikte, bitişik atama operatörü de denir. Bitişik
atama operatörünü diğer dört işlem operatörleri ile de yazmak
mümkündür.
1 |
Devamsizlar -= GecGelenler; |
Karmaşık ifadeler
yazarken de birleşik atama operatörü kullanabiliriz.
1 |
C
= (A += 4) / (B *= 7); |
Artırma ve Azaltma
Operatörleri
Programlamada bir
değişkenin değerini 1 artırmak ve bir azaltmak da çok yaygındır.
Bunu yapmak için aşağıdaki gibi bir ifade yazılabilir.
Bu ifadeyi daha kısa ve
kolay yazmak da C#ta mümkündür.
Şimdi bunu daha kolay
ve kısa yazalım.
++ operatörü artırma
operatörü olarak da söylenir, C tabanlı dillerde vardır ve yaygın
kullanılır. Tabiî ki eksiltme operatörü de vardır. Bu da --
operatörü. Operatörlerin bu şekilde yazılması sonek şeklinde
yazmaktır.
Artırma ve eksiltme
operatörleri, bu şekilde yapılabileceği gibi, önek olarak da
yazılabilir.
Önek ve sonek arasında
bir nüans vardır ve önemlidir. Aşağıdaki örneği çalıştırırsak
aradaki farkı görebiliriz.
1 |
using System; |
2 |
class ArtirmaEksiltme |
3 |
{ |
4 |
static void Main() |
5 |
{ |
6 |
|
7 |
int A = 2, B = 4, C, D; |
8 |
|
9 |
C = A++; |
9 |
D = ++A; |
10 |
|
11 |
Console.WriteLine (C); |
11 |
Console.WriteLine (D); |
12 |
} |
13 |
} |
A değişkeni başlangıçta
2 dir. Sonra 9. satırda C değişkeni, A değişkeninin 2 olan
değerini alır, daha sonra A, 1 artarak 3 olur. 10. satırda ise
önce A, 1 artırılıyor yani 4 oluyor, daha sonra da Anın değeri,
Dye atanıyor. Yani D, 4 oluyor.
17. ve 18. satırlarda
ise ekrana yazdırıp test ediyoruz