virgül işleci (comma operator)

Virgül iki terimli (operand) ara ek (infix) konumlu bir işleçtir.

gibi bir ifadede exp1 virgül işlecinin sol terimi exp2 ise virgül işlecinin sağ terimidir.
Virgül işlecinin birinci teriminden sonra bir yan etki noktası (sequence point) vardır. İşlecin ikinci terimi olan ifade, birinci terimin değerlendirilmesinden sonra ele alınır. İşlecin sağ terimi ele alındığında sol terimi olan ifadenin doğurduğu tüm yan etkiler (side effects) gerçekleşmiş durumdadır. Aşağıdaki koda bakalım:

Yukarıdaki kodda

ifadesinde kullanılan virgül işlecinin sol terimi

ifadesi, sağ terimi ise

ifadesidir. func işlevinin değişkeninin artmış değeri olan 15 ile çağrılması garanti altındadır.

virgül işlecinin önceliği

virgül C dilinin en düşük önceliğe sahip işlecidir. Aşağıdaki ifadeye bakalım:

Bu ifadede virgül işlecinin sol terimi

sağ terimi ise

ifadesidir. x değişkenine virgül işlecinin ürettiği değeri atamak için öncelik parantezi kullanılmalıydı:

virgül işlecinin ürettiği değer

Virgül işlecinin ürettiği değer sağ terimin değeridir. Aşağıdaki koda bakalım:

Bir gerçek sayı sabitini yazarken nokta karakteri yerine yanlışlıkla virgül işlecinin kullanılması sık yapılan kodlama hatalarındandır:

Yukarıdaki kodda

ifadesinde nokta karakteri yerine yanlışlıkla virgül karakteri yazılmış. Bu durumda virgül işlecinin ürettiği değer 0 olacağından koşul ifadesi lojik “yanlış” olarak yorumlanacak ve döngü gövdesindeki deyim hiç yürütülmeyecek.

virgül işlecinin kullanılmasına ilişkin temalar

Virgül işlecinin kullanılmasıyla birden fazla ifade deyimi (expression statement) tek bir ifade deyimine dönüştürülebilir. Mantıksal ilişki içinde kullanılan aşağıdaki gibi üç deyim olsun:

Bu üç ifade deyimi yerine aşağıdaki ifade deyimini yazabiliriz:

Virgül işleci bir yan etki noktası oluşturduğundan, yukarıda yazılan deyimin daha önce yazılan 3 ayrı deyimden sonuç olarak bir farkı yoktur.
Peki neden birden fazla ifade deyimi yazmak yerine tek bir ifade deyimi yazmak isteyelim? Kodlayıcıyı buna teşvik eden birden fazla neden olabilir:
i) Birden fazla ifade deyimi arasındaki mantıksal ilişki daha iyi vurgulanabilir.
ii) Tek bir deyim yazmanın sentaks açısından zorunlu olduğu yerlerde yani birden fazla deyim yazmanın geçersiz olduğu durumlarda yaptırılacak işlemler virgül işlecinin kullanılması ile tek bir deyim ile ifade edilebilir.
iii) Blok kullanımından kaçınılabilir.

Aşağıdaki kodda bir yazıyı ters çeviren strrev isimli bir işlevin tanımı yer alıyor. İşlev ters çevirdiği yazının adresiyle geri dönüyor:

İşlevimiz virgül işlecinin kullanımına ilişkin temaları vurguluyor. for parantezinin birinci ve üçüncü kısmında virgül işlecinin kullanıldığını görüyorsunuz. for deyiminin bloklanmamış gövdesinde, virgül işleçlerinin kullanıldığı ifade deyimi ile döngünün her turunda yazının iki karakteri takas ediliyor.

if deyiminin koşul ifadelerinde ya da while döngü deyiminin kontrol ifadelerinde virgül işlecinin kullanılması bazı kodlayıcıların tercih ettiği idiyomatik bir yapıdır:

Yukarıdaki if deyiminin parantezi içindeki

ataması if deyiminden önce ayrı bir deyim olarak yazılabilirdi. Kodlayıcımız bu atamanın if deyimi ile mantıksal ilişkisini vurgulamak için virgül işlecini kullanarak atamayı if parantezi içine almış.

assert makrosunun kullanımında virgül işleci ile oluşturulan bir ifade ile kullanıcı ekranına hatayı açıklayan bir yazı yazdırılabilir:

Virgül işleci return deyiminin ifadelerinde de karşımıza çıkabilir. Bir işlev tanımında aşağıdaki gibi bir if deyimi olsun:

error_flag değişkeni 0′dan farklı bir değerde ise global errno değişkenine hatanın kimşliğini ifade eden EPIPE değeri atanıyor ve işlev bir hata değeri olarak -1 değerini döndürüyor. Şimdi de yukarıdakine eşdeğer olan aşağıdaki koda bakalım:

if deyiminin doğru kısmında tek bir deyim olduğu için artık if deyiminin doğru kısmı bloklanmak zorunda değil. return ifadesinde virgül işlecinin kullanımına dikkat edin. Önce errno değişkenine atama yapılacak. İşlevin geri dönüş değeri virgül işlecinin ürettiği -1 değeri olacak.

işleç olan virgül ile ayıraç olan virgülün birbirinden ayrılması

Virgül atomu bazı yerlerde bir ayıraç olarak kullanılır. Bu durumda sentaksa ilişkin öğeler virgül atomuyla birbirinden ayrılarak bir liste oluşturulur. Bu yapıya ingilizcede “coma separated list” (virgüllerle ayrılan liste) denir. Virgül atomunun bu biçimde kullanılması işleç olarak kullanımından tamamen ayrıdır.

Yukarıdaki kodda x, y ve z isimli değişkenler tanımlanıyor. Burada kullanılan virgül atomu işleç değildir.

Yukarıdaki kodda ise func işlevine a ve b ifadeleri argüman olarak gönderiliyor. Buradaki virgül de bir işleç değildir.

Yukarıdaki kodda ismi a olan 5 öğeli bir diziye ilk değer veriliyor. Burada kullanılan virgül atomları da işleç değildir.

Sentaksın gerektirdiği virgül atomu yerine işleç olan virgül kullanmak için ifade öncelik parantezi içine alınmalıdır:

Yukarıdaki kodda ise foo işlevi virgül işlecinin ürettiği değerle çağrılıyor. Virgül işlevinin yan etki noktası oluşturduğunu hatırlayalım. İşlev 3 değeri ile çağrılıyor. Şimdi de aşağıdaki kodu derleyip çalıştırın:
a dizisine ilk değer vermekte kullanılan virgül bir işleç değilken b dizisine ilk değer verilirken kullanılan virgül atomları işleç görevindeler. Programın çıktısı şu şekilde olacak:

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Kod Eklemek İçin Okuyun