2011-07-01 15 views
5

Załóżmy, że mamy 3 zmienne i musimy ZAZNACZAĆ, że mogą one wszystkie być równe -1 lub żadna nie może być równa -1. Napisałem poniższy kod:Ocena potrójnej równości

x := 1; 
y := 1; 
z := 1; 

ASSERT((x = -1) = (y = -1) = (z = -1)); 

Często piszę ten rodzaj czeku, ale dla dwóch zmiennych. Co zaskakujące, zestawiono również potrójne porównanie, ale nie działa zgodnie z oczekiwaniami. Dla wartości (1, 1, 1) oczekuję, że będzie to prawda. Po zastąpieniu wartości zmiennych i uproszczeniu uzyskujemy:

ASSERT(False = False = False); 

i pomyślałem, że powinno to być prawdziwe, ale tak nie jest. Jak ocenia się to potrójne porównanie?

+0

Ani? Jak to możliwe z 3 warunkami? –

+0

+1 za niesamowitą ekspresję! Gdybyś miał coś więcej niż wartości boolowskie, otrzymasz błąd kompilatora 'Incompatible types'; I przypuszczam, że jest to sytuacja kluczowa, ponieważ wartości BOOLEAN są rzadko porównywane z operatorem '='. –

+2

Nic nie jest dziwne, False = False jest równe True, a True <> False –

Odpowiedz

8

Przede wszystkim operator = jest operatorem binarnym: zawsze działa na parze wartości. Więc nie ma czegoś takiego jak "potrójna równość". Kompilator oceni jedną parę i użyje wyniku do oceny drugiej.

Gdy kompilator widzi wielu połączonych operatorów, musi grupować je w pary za pomocą tak zwanego "pierwszeństwa operatorów". Jest oczywiste, jeśli myślisz o podstawowych operacjach arytmetycznych, których nauczyliśmy się w szkole podstawowej. Nie ma wątpliwości co: 3+2*4 oznacza: jest to odpowiednik 3+(2*4). W razie wątpliwości zawsze dodawaj grupowanie. Jeśli to zrobisz, zobaczysz swój wyraz odpowiada:

((False = False) = False), i to oczywiste, że ocenia się:

(True = False).

Co prawdopodobnie chcesz użyć operatora AND i grupę początkowy Assert tak:

ASSERT(((x = -1) = (y = -1)) and ((y = -1) = (z = -1)))

Potem pewnie albo napisać, że wyrażenie na wielu liniach, aby AND operator oczywiste (SQL nałóg, wiem), albo przerobić go całkowicie:

Assert (
    ((x = -1) = (y = -1)) 
    and 
    ((x = -1) = (z = -1)) 
); 

czy ten wariant:

Assert (
    ((x = -1) and (y = -1) and (z = -1)) 
    or 
    ((x <> -1) and (y <> -1) and (z <> -1)) 
); 

Moja zasada brzmi: jeśli zajmie więcej niż 1 sekundę, aby ustalić pierwszeństwo operatorów, dodaj nawiasy.

+3

+1 dla "Mojej reguły". –

2

Porównanie jest łączne: Fałsz = False = False odpowiada (fałsz = False) = False. Pierwszy Fałsz = False ocenia się Prawdziwego, prowadząc do porównania Prawda = False który z kolei jest Fałsz.