?: Operatörü C'de tam olarak nasıl çalışır?


10

Bir soru var, derleyici aşağıdaki kod üzerinde nasıl çalışır:

#include<stdio.h>

int main(void)
{
  int b=12, c=11;
  int d = (b == c++) ? (c+1) : (c-1);
  printf("d = %i\n", d);
}

Sonucun neden emin değilim d = 11.


1
Neden emin değilsin? Başka ne beklersiniz ve neden?
Gerhardh

2
İlgili kesin anlambilimi hatırlamıyorum, ancak tanımlanmamış davranışları gözlemliyor olabilirsiniz.
chepner

3
Hayır, @chepner, üçlünün durumunu değerlendirdikten sonra, seçilen alternatifi değerlendirmeden önce bir dizi noktası vardır. Sanırım düşündüğünüz UB vektöründen kaçınır.
John Bollinger

Evet, derleyicinin nerede olacağını düşündüğümden emin değilim.
chepner

Yanıtlar:


6

İçinde int d = (b == c++) ? (c+1) : (c-1);:

  • Değeri , 11'in c++geçerli değeridir. cAyrı olarak, c12'ye çıkarılır.
  • b == 11yanlış, çünkü b12.
  • Beri (b == c++)yanlıştır, (c-1)kullanılır. Ayrıca, c12'ye kadar olan artış bu noktaya kadar tamamlanmalıdır.
  • Yana c12'dir c-111'dir.
  • d bu değere sıfırlanır, 11.

5

C Standardına göre (6.5.15 Koşullu operatör)

4 İlk işlenen değerlendirilir; değerlendirmesi ile ikinci veya üçüncü işlenenin değerlendirilmesi arasında (hangisi değerlendirilirse) bir sıralama noktası vardır. İkinci işlenen, yalnızca ilki 0 ile eşit değilse karşılaştırılır; üçüncü işlenen, yalnızca birinci işlenen 0'a eşitse değerlendirilir; sonuç, aşağıda açıklanan türe dönüştürülen ikinci veya üçüncü işlenenin (hangisi değerlendirilirse) değeridir.

Yani bu bildirimin ilk ifadesinde

int d = (b == c++) ? (c+1) : (c-1);

değişken b, değişkenin değeri ile karşılaştırılır, cçünkü artım sonrası operatör, onu arttırmadan önce işleneninin değerini döndürür.

Değerler birbirine eşit olmadığından ( 11'e ayarlanırken b12'ye cayarlanır), sonra alt ifade (c-1)değerlendirilir.

Alıntıya göre, operatörün durumunun değerlendirilmesinden sonra bir sıralama noktası vardır. Bu, durumun değerlendirilmesinden sonra, artış sonrası operatörünü değişkene uyguladıktan sonra cdeğere sahip olduğu anlamına gelir . Sonuç olarak, d değişkeni değer ( ) tarafından başlatılır .12c112 - 1


2
Tek doğru cevap - bu özel durum, sıralama noktası belirtilerek cevaplanmalıdır ?:. Çünkü normalde C'de, ++aynı işlenen üzerindeki diğer işlemlerle birleştirmek tanımsız bir davranıştır. Ve bu kod sadece tahmin edilebilir şekilde çalışır çünkü ?:çeşitli özel kar tanesi kuralları vardır.
Lundin

4

Koşul yanlışsa BEACUSE nedenle falsedava olur: c-1ama artırılır beri ctarafından durumda c++, bu nedenle cartık 12. Sonuç olarak 11 - 12 olan 1.

EDIT: OP yanlış anlama sonrası artış oldu.

Yani aslında olan şu:

#include<stdio.h>
int main(void)
{
  int b=12, c=11;
  int d;

  if (b == c) { // 12 == 11 ? -> false
    c = c + 1;
    d = c + 1;
  } else { // this executes since condition is false
    c = c + 1; // post increment -> c++ -> c = 12 now
    d = c - 1; // 12 - 1 = 11 -> d = 11
  }
  printf("d = %i\n", d);
}

1
Bence OP, c++koşulda verilen işlem sırasına atıfta bulunuyor . Koşul yanlıştır, ancak daha sonra özgün değeri, chesaplanan c - 1sürüm için değil, hesaplamak için kullanılır .
chepner

1
Samimi 12 == 11 + 1 doğru olduğunu düşündüm ...
J0S

Ama bu yeni c değeri kullanıldığından bu doğru değil mi?
Eraklon

Ben c++ve arasında bir yanlış anlama olabileceğini düşünüyorum++c
ChatterOne

N00b @ c++olduğu sonrası -increment operatör. Yapmanın c++yan etkisi ile değeri 11'dir c == 12. ++c12
chepner

4

Düzenli bir if ifadesine çevrildiğinde kodunuz şöyle görünecektir:

int b=12, c=11;
int d;

if (b == c++)
   d = c+1;
else
   d = c-1;

Buradaki ipucu , durum kontrol edildikten sonra c'nin artmasıdır. Böylece elsedevlete giriyorsunuz ama c zaten orada 12 değerine sahip.


1

Üçlü Operatör'e bakın .

Sözdizimi

durum ? value_if_true: value_if_false

Yani sen yazdın

int d = (b == c++) ? (c+1) : (c-1);

Bu durumda sonuç 11 olur, çünkü kontrollerden sonra 'c' değeri artar (c + 1 = 12) ve bundan sonra 'd' değerini 11 olan c (12) -1 olarak ayarlar.

Eğer kullandıysanız, örneğin:

int d = (b == ++c) ? (c+1) : (c-1);

İfadeyi kontrol etmeden önce "c" değeri artacaktır, bu yüzden doğru olur ve "d" değeri 13 olan c (12) +1 olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.