Co robi '?' zrobić w C ++?

80
int qempty()
{
    return (f == r ? 1 : 0);
}

Co w powyższym fragmencie oznacza „ ? ”? Czym możemy to zastąpić?

Thaier Alkhateeb
źródło
22
W tym konkretnym przypadku możesz oczywiście zamienić go na return f == r;
Eclipse
6
@Eclipse: Nie polegałbym na niejawnej konwersji bool-> int, jeśli mógłbym tego uniknąć.
Daniel Daranas
2
@DanielDaranas, czemu nie? (To jest rodzaj pytania dla początkujących - wyjaśnienie twoich komentarzy dla początkujących byłoby bardzo pomocne i mile widziane.)
Michael Hoffmann
4
@MichaelHoffmann Zachowanie niejawnej konwersji w tym przypadku jest dobrze zdefiniowane, więc użycie jej jest całkowicie poprawne; zobacz tę odpowiedź jako odniesienie do normy. Osobiście unikam niejawnych konwersji typów, ponieważ uważam, że kod jest bardziej czytelny i łatwiejszy w utrzymaniu, a bez nich jest mniej podatny na błędy. Bardziej szczegółowo opisałem to w tym wpisie na blogu .
Daniel Daranas,

Odpowiedzi:

136

Jest to powszechnie określane jako operator warunkowy i używane w ten sposób:

condition ? result_if_true : result_if_false

... jeśli conditionszacuje się na true, wyrażenie oblicza na result_if_true, w przeciwnym razie zwraca result_if_false.

To jest cukier syntaktyczny iw tym przypadku można go zastąpić

int qempty()
{ 
  if(f == r)
  {
      return 1;
  } 
  else 
  {
      return 0;
  }
}

Uwaga: Niektórzy ludzie nazywają ?:go „ operatorem trójskładnikowym ”, ponieważ jest to jedyny operator trójskładnikowy (tj. Operator, który przyjmuje trzy argumenty) w języku, którego używają.

Daniel LeCheminant
źródło
4
W zwykłym kodzie jest to cukier składniowy, ale umożliwia warunkową inicjalizację na liście inicjalizacyjnej konstruktu.
JohnMcG
Foo (Bar * y) pMember (y == NULL? NULL: y-> pMember) - Tutaj inicjalizujemy pMember na pMember y lub NULL, jeśli go tam nie ma. Nie można umieścić if-else w inicjalizacji konstruktora, więc operator trójskładnikowy to umożliwia.
JohnMcG
@JohnMcG: Cóż, w C ++ 11 można by rozważyć a? b : ccukier syntaktyczny [&]() -> Type { if (a) return b; else return c; }().
celtschk,
1
Prawdopodobnie, ale pytanie, odpowiedź i komentarz zostały napisane w 2009 roku.
JohnMcG
15

To jest operator trójskładnikowy, w zasadzie jest to instrukcja wbudowana if

x ? y : z

działa jak

if(x) y else z

z wyjątkiem, zamiast instrukcji masz wyrażenia; więc możesz go użyć w środku bardziej złożonej instrukcji.

Jest to przydatne do pisania zwięzłego kodu, ale może być nadużywane do tworzenia trudnego do utrzymania kodu.

Richard
źródło
4
Warto wiedzieć, że w znaku „?” znajduje się punkt sekwencji. Oznacza to, że ważne jest: ++ x? x: y;
Johannes Schaub - litb
1
@Daniel, właśnie to miałem na myśli, mówiąc, że mam wyrażenia, a nie stwierdzenia. Prawdopodobnie nie byłem wystarczająco jasny na temat różnicy, więc dziękuję za dodanie pewnych wyjaśnień.
Richard
6

Możesz po prostu przepisać to jako:

int qempty(){ return(f==r);}

Który robi to samo, co powiedział w innych odpowiedziach.


źródło
spowoduje to niejawną konwersję z wartości logicznej na int
Don Cheadle
6

Tylko uwaga, jeśli kiedykolwiek to zobaczysz:

a = x ? : y;

Jest to rozszerzenie standardu GNU (patrz https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals ).

To jest to samo co

a = x ? x : y;
Nick Kossifidis
źródło
w CLang (przynajmniej w najnowszych wersjach) to rozszerzenie jest również dostępne. Jest dostępny nawet z wyłączoną flagą C ++ 11 w projekcie qmake. Czyli wyrażenie takie jak int x = 1+1 ? : 0 ; poprawnie zwraca 2 , w moim kompilatorze i to nic nie narzekało.
Vinícius A. Jorge
3

To operator warunkowy.

a? pne

To skrót do IF / THEN / INNE.

oznacza: jeśli a jest prawdziwe, zwróć b, w przeciwnym razie zwróć c. W tym przypadku, jeśli f == r, zwróć 1, w przeciwnym razie zwróć 0.

Joe
źródło
2

Znak zapytania to operator warunkowy. Kod oznacza, że ​​jeśli f == r to zwracane jest 1, w przeciwnym razie zwraca 0. Kod można przepisać jako

int qempty()
{
  if(f==r)
    return 1;
  else
    return 0;
}

co prawdopodobnie nie jest najczystszym sposobem, ale miejmy nadzieję, że pomaga w zrozumieniu.

ssakl
źródło