Virgül operatörü - Comma operator

İçinde C ve C ++ programlama dilleri, virgül operatörü (temsil eden jeton ,) bir ikili operatör ilkini değerlendiren işlenen ve sonucu atar ve ardından ikinci işleneni değerlendirir ve bu değeri (ve türü) döndürür; var sıra noktası bu değerlendirmeler arasında.

Virgül belirtecinin bir Şebeke kullanımından farklıdır işlev çağrıları ve tanımları, değişken bildirimleri, enum bildirimleri ve benzer yapılar, burada bir ayırıcı.

Sözdizimi

Virgül operatörü ayırır ifade (değeri olan) bir şekilde noktalı virgül sona erer ifadeler ve ifade dizileri, ifade dizilerinin parantez içine alınmasına benzer bir şekilde parantez içine alınır:[1] (a, b, c) virgülle ayrılmış ve son ifadeyi değerlendiren bir ifade dizisidir c süre {a; b; c;} bir ifade dizisidir ve herhangi bir değerle değerlendirilmez. Virgül yalnızca iki ifade arasında bulunabilir - virgül ayrı ifadeler - (blok olmayan) bir ifadenin sonunda oluşan noktalı virgülden farklı olarak - noktalı virgül bitirmek ifadeler.

Virgül operatörü en düşük öncelik herhangi bir C operatörünün ve sıra noktası. Virgül ve noktalı virgül kombinasyonunda, noktalı virgüllerin önceliği virgülden daha düşüktür, çünkü noktalı virgüller ifadeleri ayırır, ancak virgüller ifadeler içinde yer alır ve bu da normal noktalama olarak kullanımlarına uygun olarak kullanılır: a, b; c, d olarak gruplanır (a, b); (c, d) çünkü bunlar iki ayrı ifadedir.

Örnekler

Bu örnekte, ikinci ve üçüncü satırlar arasındaki farklı davranış, virgül operatörünün atamadan daha düşük önceliğe sahip olmasından kaynaklanmaktadır. Son örnek de farklıdır çünkü fonksiyonun dönebilmesi için dönüş ifadesinin tam olarak değerlendirilmesi gerekir.

/** * Virgüller, operatör olarak değil, bu satırda ayırıcı görevi görür. * Sonuçlar: a = 1, b = 2, c = 3, i = 0 */int a=1, b=2, c=3, ben=0;/** * B'nin değerini i'ye atar. * Virgüller, ilk satırda ayırıcı, ikinci satırda ise işleç görevi görür. * Sonuçlar: a = 1, b = 2, c = 3, i = 2 */int a=1, b=2, c=3;              int ben = (a, b);                                 /** * A değerini i'ye atar. * Eşdeğeri: int (i = a), b; * Virgüller, her iki satırda ayırıcı görevi görür. * İkinci satırdaki parantezler aynı blokta değişken yeniden beyanlardan kaçınır, * derleme hatasına neden olur. * Bildirilen ikinci b'ye başlangıç ​​değeri verilmez. * Sonuçlar: a = 1, b = 2, c = 3, i = 1 */int a=1, b=2, c=3;                                { int ben = a, b; }/** * A'nın değerini 2 artırır, ardından sonuçta ortaya çıkan a + b işleminin değerini i'ye atar. * Virgüller, ilk satırda ayırıcı, ikinci satırda ise işleç görevi görür. * Sonuçlar: a = 3, b = 2, c = 3, i = 5 */int a=1, b=2, c=3;int ben = (a += 2, a + b);          /** * A'nın değerini 2 artırır, sonra a'dan i'ye değerini saklar ve kullanılmayanları atar * ortaya çıkan işlemin değerleri a + b. * Eşdeğeri: ((i = a) + = 2), a + b; * Virgüller, ilk satırda ayırıcı ve üçüncü satırda bir işleç görevi görür. * Sonuçlar: a = 3, b = 2, c = 3, i = 3 */int a=1, b=2, c=3;int ben;ben = a += 2, a + b;/** * A değerini i'ye atar. * Virgüller, her iki satırda ayırıcı görevi görür. * İkinci satırdaki parantezler aynı blokta değişken yeniden beyanlardan kaçınır, * derleme hatasına neden olur. * Bildirilen ikinci b ve c'ye başlangıç ​​değeri verilmez. * Sonuçlar: a = 1, b = 2, c = 3, i = 1 */int a=1, b=2, c=3;{ int ben = a, b, c; }/** * Virgüller, ilk satırda ayırıcı, ikinci satırda ise işleç görevi görür. * Kullanılmayan a ve b değerlerini atarak c'nin değerini i'ye atar. * Sonuçlar: a = 1, b = 2, c = 3, i = 3 */int a=1, b=2, c=3;int ben = (a, b, c);/** * Virgül operatör dizisi anahtar kelimeyi takip ettiği için 4 değil 6 döndürür  * dönüş, son rvalue için değerlendirilen tek bir ifade olarak kabul edilir  * alt ifade c = 6. * Virgüller, bu satırda operatör görevi görür. */dönüş a=4, b=5, c=6;/** * Önceki örnekle aynı nedenle 1 değil 3 değerini döndürür. * Virgüller, bu satırda operatör görevi görür. */dönüş 1, 2, 3;/** * Yukarıdaki ile aynı nedenden dolayı 1 değil 3 döndürür. Bu örnek olduğu gibi çalışıyor * çünkü return bir anahtar sözcüktür, işlev çağrısı değildir. Derleyiciler yapsa bile  * dönüş yapısına (değer) izin verin, parantezler yalnızca "değer" ile ilişkilidir * ve dönüş anahtar kelimesi üzerinde özel bir etkisi yoktur. * Dönüş basitçe bir ifade alır ve burada ifade "(1), 2, 3" dür. * Virgüller, bu satırda operatör görevi görür. */dönüş(1), 2, 3;

Kullanımlar

Virgül operatörünün nispeten sınırlı kullanım durumları vardır. İlk işleneni attığı için, genellikle yalnızca ilk işlenenin istendiği durumlarda yararlıdır. yan etkiler bu olmalı daha önce sıralandı ikinci işlenen. Ayrıca, belirli deyimlerin dışında nadiren kullanıldığından ve diğer virgül veya noktalı virgülle kolayca karıştırıldığından, potansiyel olarak kafa karıştırıcı ve hataya meyillidir. Bununla birlikte, yaygın olarak kullanıldığı belirli durumlar vardır, özellikle döngülerde ve SFINAE.[2] Sınırlı hata ayıklama yeteneklerine sahip olabilen gömülü sistemler için, virgül operatörü, bir fonksiyon çağrısını sorunsuz bir şekilde geçersiz kılmak, fonksiyon çağrısından hemen önce kod eklemek için bir makro ile kombinasyon halinde kullanılabilir.

Döngüler için

En yaygın kullanım, birden çok Görev Bir blok deyimi kullanmadan, öncelikle bir a'nın başlatma ve artış ifadelerinde döngü için. Bu, temel C programlamadaki tek deyimsel kullanımdır. Aşağıdaki örnekte, döngünün başlatıcılarının sırası önemlidir:

geçersiz devir(kömür *s, size_t len){    kömür *ilk;    için (ilk = s, s += len; s >= ilk; --s) {        putchar(*s);    }}

Diğer dillerde bu soruna alternatif bir çözüm, paralel atama, tek bir ifadede birden çok atamanın gerçekleşmesine izin veren ve ayrıca farklı sözdizimi ve anlambilimle olsa da bir virgül kullanır. Bu kullanılır Git benzer for döngüsü içinde.[3]

For döngüsü başlatıcılarının (özel bir noktalı virgül kullanımına sahip olan) dışında, özellikle söz konusu ifadeler bir döngü artışına benzer şekilde çalıştığında (örneğin bir while döngüsünün sonunda) noktalı virgül yerine virgül kullanılabilir:

++p, ++q;++p; ++q;

Makrolar

Virgül, önişlemci makrolarında tek bir sözdizimsel ifade alanında birden çok işlem gerçekleştirmek için kullanılabilir.

Yaygın bir kullanım, başarısız iddialarda özel hata mesajları sağlamaktır. Bu, parantezli bir ifade listesinin iddia etmek makro, burada ilk ifade bir hata dizesidir ve ikinci ifade iddia edilen koşuldur. iddia etmek makrosu, bir onaylama başarısızlığı durumunda argümanını kelimesi kelimesine çıkarır. Aşağıda bir örnek verilmiştir:

#Dahil etmek <stdio.h>#Dahil etmek <assert.h>int ana ( geçersiz ){    int ben;    için (ben=0; ben<=9; ben++)    {        iddia etmek( ( "ben çok büyük!", ben <= 4 ) );        printf("i =% i n", ben);    }    dönüş 0;}

Çıktı:

i = 0i = 1i = 2i = 3i = 4assert: assert.c: 6: test_assert: İddia `(" i çok büyük! ", i <= 4) 'başarısız oldu.

Bununla birlikte, onay makrosu genellikle üretim kodunda devre dışı bırakılır, bu nedenle onu yalnızca hata ayıklama amacıyla kullanın.

Durum

Virgül, yardımcı hesaplamalara izin vermek için (if, while, do while, veya for) bir koşul içinde, özellikle bir işlevi çağırmak ve sonucu kullanmak için kullanılabilir. blok kapsam belirleme:

Eğer (y = f(x), y > x) {    ... // x ve y içeren ifadeler}

Benzer bir deyim var Git, burada if ifadesinin sözdizimi, isteğe bağlı bir ifadeye açıkça izin verir.[4]

Karmaşık getiri

Virgül, global bir değişkene veya out parametresine atamak için dönüş ifadelerinde kullanılabilir (referansla iletilir). Bu deyim, atamaların gerçek dönüşle biten bir bloktaki yardımcı atamalar yerine geri dönüşün bir parçası olduğunu önerir. Örneğin, genel bir hata numarası ayarlarken:

Eğer (başarısızlık)    dönüş (errno = EINVAL, -1);

Bu daha ayrıntılı olarak şu şekilde yazılabilir:

Eğer (başarısızlık) {    errno = EINVAL;    dönüş -1;}

Bir bloktan kaçının

Kısaca virgül, aşağıdaki gibi bir bloktan ve ilişkili parantezlerden kaçınmak için kullanılabilir:

Eğer (x == 1) y = 2, z = 3;Eğer (x == 1)    y = 2, z = 3;

onun yerine:

Eğer (x == 1) {y = 2; z = 3;}Eğer (x == 1) {    y = 2; z = 3;}

Diğer diller

İçinde OCaml ve Yakut programlama dilleri için noktalı virgül (";") bu amaçla kullanılır. JavaScript[5] ve Perl[6] virgül operatörünü C / C ++ ile aynı şekilde kullanır. İçinde Java virgül, bir listedeki öğeleri çeşitli bağlamlarda ayırmak için kullanılan bir ayırıcıdır.[7] Bir operatör değildir ve listedeki son öğe olarak değerlendirilmez.[8]

Ayrıca bakınız

Referanslar

  1. ^ "Virgül İşleci:,". Microsoft geliştirme belgeleri. Arşivlenen orijinal (html) 1 Ağustos 2019. Alındı 1 Ağustos 2019. Virgülle ayrılmış iki ifade soldan sağa doğru değerlendirilir. Sol işlenen her zaman değerlendirilir ve tüm yan etkiler, sağ işlenen değerlendirilmeden önce tamamlanır.
  2. ^ http://en.cppreference.com/w/cpp/language/sfinae
  3. ^ Etkili Git: için, "Son olarak, Go'nun virgül operatörü yok ve ++ ve - ifadeler değil ifadelerdir. Bu nedenle, sizin için birden çok değişkeni çalıştırmak istiyorsanız paralel atamayı kullanmalısınız (bu, ++ ve --'yi engellemesine rağmen)."
  4. ^ Go Programlama Dili Spesifikasyonu: If ifadeleri
  5. ^ "Virgül operatörü". MDN Web Belgeleri. 17 Ocak 2020. Arşivlendi orijinal (html) 12 Temmuz 2014. Alındı 25 Ocak 2020. Tek bir ifade gerektiren bir konuma birden çok ifade eklemek istediğinizde virgül operatörünü kullanabilirsiniz.
  6. ^ https://perldoc.perl.org/perlop.html#Comma-Operator
  7. ^ "2.4. Dilbilgisi Gösterimi". Oracle Corporation. Arşivlenen orijinal (html) 22 Temmuz 2019. Alındı 25 Temmuz 2019.
  8. ^ https://stackoverflow.com/questions/38733508/is-comma-operator-or-separator-in-java

Kaynakça

  • Ramajaran, V. (1994), C'de Bilgisayar Programlama, Yeni Delhi: Hindistan Prentice Hall
  • Dixit J.B (2005), C'de bilgisayar ve programlamanın temelleri, Yeni Delhi: Laxmi Yayınları
  • Kernighan, Brian W .; Ritchie, Dennis M. (1988), C Programlama Dili (2. baskı), Englewood Cliffs, NJ: Prentice Hall

Dış bağlantılar