İşleç Öncelikleri
Kitabın başından beri yaptığımız gibi, ikiden fazla ifade birden fazla işleç ile bir araya getirilebilir. Örneğin, aşağıdaki satır üç işleç ile bağlanmış olan dört ifade içerir:
a = b + c * d // üç işleç: =, +, ve *
İşleçlerin öncelik kuralları, birden fazla işleç bulunan durumda o işleçlerin hangi sırada işletileceklerini ve hangi ifadeleri kullanacaklarını belirler. İşleçler önceliklerine göre işletilirler: önce yüksek öncelikli olanlar, sonra düşük öncelikli olanlar.
Aşağıdaki tablo D'nin işleç önceliklerini yüksek öncelikliden düşük öncelikliye doğru sıralanmış olarak verir. Aynı tablo satırında bulunan işleçler aynı önceliğe sahiptir. (Aynı tablo hücresi içindeki satırların önemi yoktur; örneğin, ==
ile !is
aynı önceliğe sahiptir.) Özellikle belirtilmediği sürece bütün işleçler sol birleşimlidir.
Tabloda kullanılan terimlerin bazıları aşağıda açıklanıyor.
İşleçler | Açıklama | Notlar |
---|---|---|
! |
Şablon gerçekleştirmesi | Zincirlenemez |
=> |
İsimsiz işlev tanımı | Gerçek bir işleç değildir; tabloda iki yerde bulunur; bu satır sol tarafıyla ilgilidir |
. ++ -- ( [ |
Sonek işleçler | ( ve [ parantezleri sırasıyla ) ve ] ile kapatılmalıdır
|
^^ |
Üs alma işleci | Sağ birleşimli |
++ -- * + - ! & ~ cast |
Tekli işleçler | |
* / % |
İkili işleçler | |
+ - ~ |
İkili işleçler | |
<< >> >>> |
Bit kaydırma işleçleri | |
== != > < >= <= in !in is !is |
Karşılaştırma işleçleri | Bit işleçleri ile aralarında öncelik tanımlı değildir; Zincirlenemezler |
& |
Bit işlemi ve | Karşılaştırma işleçleri ile aralarında öncelik tanımlı değildir |
^ |
Bit işlemi ya da | Karşılaştırma işleçleri ile aralarında öncelik tanımlı değildir |
| |
Bit işlemi veya | Karşılaştırma işleçleri ile aralarında öncelik tanımlı değildir |
&& |
Mantıksal ve | İkinci ifade işletilmeyebilir |
|| |
Mantıksal veya | İkinci ifade işletilmeyebilir |
?: |
Üçlü işleç | Sağ birleşimli |
= -= += = *= %= ^= ^^= ~= <<= >>= >>>=
|
Atamalı işleçler | Sağ birleşimli |
=> |
İsimsiz işlev tanımı | Gerçek bir işleç değildir; tabloda iki yerde bulunur; bu satır sağ tarafıyla ilgilidir |
, |
Virgül işleci | Ayraç olarak kullanılan virgül ile karıştırılmamalıdır |
.. |
Sayı aralığı | Gerçek bir işleç değildir; söz diziminin özel bir parçasıdır |
İşleç zincirleme
Bölümün başındaki ifadeye tekrar bakalım:
a = b + c * d
İkili *
işlecinin önceliği ikili +
işlecininkinden ve ikili +
işlecinin önceliği =
işlecininkinden yüksek olduklarından o ifade aşağıdaki parantezli eşdeğeri gibi işletilir:
a = (b + (c * d)) // önce *, sonra +, sonra =
Başka bir örnek olarak, sonek .
işlecinin önceliği tekli *
işlecininkinden yüksek olduğundan aşağıdaki ifade önce n
nesnesinin gösterge
üyesine erişir, sonra da onun gösterdiğine:
*n.gösterge // ← n.gösterge'nin gösterdiğine erişir *(n.gösterge) // ← üsttekinin eşdeğeri (*n).gösterge // ← üsttekinin eşdeğeri DEĞİL
Bazı işleçler zincirlenemezler:
if (a > b == c) { // ← derleme HATASI // ... }
Error: found '==' when expecting ')'
İşlem sırasını programcının örneğin parantezlerle belirtmesi gerekir:
if ((a > b) == c) { // ← derlenir // ... }
Birleşim
Aynı önceliğe sahip işleçler bulunduğunda hangisinin önce işletileceği işleç birleşimlerine göre belirlenir: ya soldaki ya da sağdaki.
Çoğu işleç sol birleşimlidir; önce soldaki işletilir:
10 - 7 - 3; (10 - 7) - 3; // ← üsttekinin eşdeğeri (== 0) 10 - (7 - 3); // ← üsttekinin eşdeğeri DEĞİL (== 6)
Bazı işleçler sağ birleşimlidir; önce sağdaki işletilir:
4 ^^ 3 ^^ 2; 4 ^^ (3 ^^ 2); // ← üsttekinin eşdeğeri (== 262144) (4 ^^ 3) ^^ 2; // ← üsttekinin eşdeğeri DEĞİL (== 4096)
Öncelikleri tanımsız işleç grupları
Bit işleçleriyle karşılaştırma işleçleri arasında öncelik tanımlı değildir:
if (a & b == c) { // ← derleme HATASI // ... }
Error: b == c must be parenthesized when next to operator &
İşlem sırasını programcının örneğin parantezlerle belirtmesi gerekir:
if ((a & b) == c) { // ← derlenir // ... }
=>
işaretinin önceliği
Aslında bir işleç olmayan =>
, solundaki ve sağındaki işleçlerle farklı önceliklere sahip olduğundan tabloda iki satırda yer alır.
l = a => a = 1;
Yukarıda =>
işaretinin her iki tarafında da =
işleci olduğu halde, =>
sol tarafta =
işlecinden daha öncelikli olduğundan soldaki a
'ya kendisi bağlanır ve sanki programcı aşağıdaki parantezleri yazmış gibi kabul edilir:
l = (a => a = 1);
Öte yandan, =>
sağ tarafta =
işlecinden daha düşük öncelikli olduğundan, sağdaki a
=
işlecine bağlanır ve sanki aşağıdaki parantezler de yazılmış gibi kabul edilir:
l = (a => (a = 1));
Dolayısıyla, isimsiz işlevin tanımı a => a
haline gelmez; ifadenin geri kalanını da içerir: a => a = 1
(anlamı: a'ya karşılık a = 1 değerini üret). O isimsiz işlev de sonuçta l
değişkenine atanmaktadır.
Not: Bunu yalnızca bir örnek olarak kabul edin. a = 1
ifadesi bir isimsiz işlevin içeriği olarak anlamlı değildir çünkü parametresine yapılan o atama normalde etkisizdir ve işlev hep 1 değerini üretir. (Burada "normalde" denmesinin nedeni, aslında a
'nın atama işlecinin yüklenmiş olabileceği ve işletildiğinde yan etki üretebileceğidir.)
Virgül işleci
Virgül işleci ikili bir işleçtir. Önce sol tarafındaki ifadeyi sonra sağ tarafındaki ifadeyi işletir. İfadelerin ürettikleri değerler göz ardı edilir.
int a = 1; foo(), bar(), ++a; assert(a == 2);
Virgül işlecinin en yaygın kullanımı, for
döngüsünün ilerletilmesi sırasında birden fazla değişkenin değiştirilmesi gereken durumdur:
for ({ int i; int j; } i < 10; ++i, ++j) { // ... }