2009-08-25 18 views
16
if((A) && (B)) 
{ 
    //do something 
} 
else 
    //do something else 

Pytanie brzmi, czy stwierdzenie natychmiast przerwałoby się na inne, gdyby A było FALSE. Czy B zostanie oceniony?W jaki sposób ocenia się wyrażenie "if (A && B)"?

Pytam o to w przypadku, gdy B sprawdza poprawność indeksu tablicy, powiedz tablica [0], gdy tablica jest rzeczywiście pusta i ma zero elementów. Dlatego rzucanie segfaultem, ponieważ próbujemy uzyskać dostęp do czegoś, co jest poza granicami tablicy. Konkretnie

if((array.GetElements() > 0) && (array[0])) 
    array[0]->doSomething(); 
else 
    //do nothing and return 

Może to być niebezpieczne, jeśli tablica [0] faktycznie zostanie oceniona, ponieważ zwraca błąd bez pierwszego wyboru po lewej stronie programu „& &”. Pierwszeństwo mówi mi, że lewa strona na pewno będzie miała pierwszeństwo, ale nie mówi mi, że nie oceni ona prawej strony, jeśli lewe jest FALSE.

+0

Inną formą kanoniczną jest 'if (p && p-> bar) {}'. Jest to również bezpieczne. – MSalters

+0

Jeśli po prostu chcesz "nic nie robić i wrócić", powinieneś całkowicie pominąć "inny". W przeciwnym razie kompilator będzie albo narzekał, że nie ma instrukcji, aby przejść do innej (jeśli jest ostatnią rzeczą w zamykającym bloku), albo, co gorsza, bierze następną instrukcję i używa jej jako instrukcji do wstawienia bloku else . –

+0

Próbowałem użyć komentarzy jako symbolu zastępczego, co oznacza: niektóre kody zostaną tu przeniesione, ale nie jest to wystarczająco ważne, aby uwzględnić je w moim przykładzie. Rzeczywistość polega na tym, że istnieje kod, który zwraca się w zakresie innego, ale także kod po zasięgu innego. Mam nadzieję, że to wyczyści – BuckFilledPlatypus

Odpowiedz

44

W języku C i C++, "zwarcie" operatorów "&& i ||". Oznacza to, że oceniają tylko parametr, jeśli jest to wymagane. Jeśli pierwszy parametr do && ma wartość false lub pierwsza do || jest prawdziwa, reszta nie zostanie oceniona.

Kod, który wysłałeś, jest bezpieczny, ale zastanawiam się, dlaczego dodać pusty blok else.

+0

Tak, mój komentarz był niepoprawny, zmieniono na // nic nie robię i zwracam, co jest w tym przypadku dokładniejsze. – BuckFilledPlatypus

+10

Chciałbym dodać, że w przypadku przeciążenia operatora && lub || we własnej klasie, NIE ulegają już zwarciu. Coś, o czym należy pamiętać. –

+2

@Kristo, nie wiedziałem o tym! Nie sądzę jednak, aby istniały jakieś rozsądne przypadki przeciążenia tego operatora. Przeciążenie operatora obsady boolem byłoby bardziej przydatne, jak sądzę. – strager

-4

tak, jeśli ((A) & & (B)) nie powiedzie się w pierwszym zdaniu, jeśli (A) oceni fałsz.

dotyczy to dowolnego języka btw, a nie tylko pochodnych C. W przypadku przetwarzania gwintowanego i równoległego jest to inna historia;)

+6

Nie każdy język. Niektóre języki, takie jak Visual Basic, mają operatory logiczne, które * nie * zwarcia. –

+1

Chciałbym zaznaczyć, że nie było tak w przypadku VB przez długi czas, zanim wprowadzono "OrElse" i "AndAlso". Nawet teraz, "Or" i "I" nie zwarcia. Powodem tego jest to, że poprzednio logiczne i bitowe operatory "Or" i "And" były takie same. – DevByDefault

+1

Niektóre języki, takie jak Ada, mają obie dostępne opcje ("AND"/"AND THEN" i "OR"/"OR ELSE"). –

10

Pytasz o operatora &&, a nie o oświadczenie if.

&&short-circuits, co oznacza, że ​​jeśli podczas pracy spełnia warunek, który powoduje tylko jedną odpowiedź, przestaje działać i korzysta z tej odpowiedzi.

Wykonanie wykona 0, a następnie zakończy działanie, ponieważ nie ma możliwości, aby wyrażenie miało wartość różną od zera, niezależnie od tego, jaki jest drugi parametr dla &&.

3

Tak, nazywa się Short-circuit Evaluation.

Jeśli ważność oświadczenia boolowskiego można zapewnić po części instrukcji, reszta nie jest oceniana.

Jest to bardzo ważne, gdy niektóre z komunikatów mają skutki uboczne.

Powiązane problemy