2011-10-07 10 views
19

Kiedy na przykład napiszę 7>1 w C (powiedzmy C99, jeśli nie jest to zawsze funkcja), czy mogę oczekiwać, że wynik będzie dokładnie 1 lub tylko pewna niezerowa wartość? Czy to dotyczy wszystkich operatorów bool?Czy "prawdziwy" wynik z>, <,!, &&, || lub == zdefiniowane?

+3

Najbardziej prawdopodobne jest to duplikat, ale nie było może go znaleźć :-( – mbq

+3

@TRD: Nieprawidłowe Wyrażenie C '7> 1' daje wynik typu' int' z wartością '1'. –

Odpowiedz

35

w C99 §6.5.8 operatorów relacji pozycja 6 (<, >, <= i >=)

Każdy z podmiotów < (poniżej),> (większy) < = (mniejsze niż lub równe), a> = (większy lub równy) wyda , jeśli określony związek jest prawdziwa i jeśli jest fałszywy) wynik ma typ Int.

Jak dla operatorów równości, to trochę dalej na §6.5.9 (== i !=):

== (równy) a = (nie równa się) Operatorzy są analogiczne do operatorów relacyjnych , z wyjątkiem ich niższego pierwszeństwa) Każdy z operatorów daje , jeśli określona relacja jest prawdziwa i jeśli jest fałszywa. Wynik ma typ int. Dla dowolnej pary argumentów , dokładnie jedna z relacji jest prawdziwa.

logicznego AND i logiczne ALBO jeszcze nieco dalej w §6.5.13 (&&)

& & operator wyda gdy oba jej argumentów porównanie różnych od 0; w przeciwnym razie, daje . Wynik ma typ int.

... i §6.5.14 (||)

|| operator wyda , jeśli którykolwiek z jego argumentów porówna wynik nierówny do 0; w przeciwnym razie, daje . Wynik ma typ int.

I semantyka jednoargumentowego arytmetycznego operatora ! są na co §6.5.3.3/4:

Wynik logicznym operatorem negacji! jest jeżeli wartość jej argumentu porównuje nierówny 0, jeżeli wartość jej argumentu porównuje równa 0. Wynik musi wpisać int. Wyrażenie! E jest równoważne (0 == E).

typ Wynik jest int w całej rozciągłości, z 0 i 1 jako możliwych wartości. (O ile nie pominąłem niektórych.)

+6

I wygodnie stdbool.h definiuje true i false jako 1 i 0 (C99 7.16). – Lundin

+0

Dobrze, zwłaszcza, że ​​&& i || zachowują się inaczej w innych językach (zwracając ostatnio ocenianą wartość) .Jeśli standardowe operatory nie są zaangażowane, zaciskanie może być wykonane za pomocą '!!' lub [casting to ' '' bool'] (http://www.jacquesf.com/2011/04/in-defense-of-the-c99-boolean-type/). – Tobu

14

C podąża za Postel's Law dla swoich operatorów boolowskich: bądź konserwatywny w tym, co robisz, bądź liberalny w tym, co akceptujesz od innych. Będzie traktował każdą niezerową wartość jako prawdziwą w wyrażeniach logicznych, ale zawsze będzie generować albo 0, albo 1. 2 != 3 jest zawsze 1.

+0

+1 za wzmiankę o prawie Postela – glglgl

6

ze standardu ISO C99, sekcja 6.5.8:

6 każdy z podmiotów < (poniżej),> (większy) < = (mniej niż lub równe), a > = (większy lub równy) daje 1, jeśli określona relacja jest prawdziwa, a 0, jeśli jest fałszem. Wynik ma postać typu int.

Z sekcji 6.5.9:

3 == (równy) a = (nie równe) operatorzy są analogiczne do relacyjnych operatorów z wyjątkiem ich niższym priorytecie. Każdy operator daje 1, jeśli podana relacja jest prawdziwa, a 0, jeśli jest nieprawdziwe. Wynik ma typ int. Dla dowolnej pary operandów, dokładnie jedna z relacji jest prawdziwa.

To samo dzieje się z logicznej koniunkcji (&&) i alternatywy (||) operatorów.

PS: Nawiasem mówiąc, dlatego operatory bitowe (& i |) mogą być zwykle używane jako nie powodujące zwarcia wersje operatorów logicznych.

4

Wszystkie C operatorzy które dają logicznie prawda/fałsz wartości zawsze uzyskując wynik typu int o wartości 0 za fałszywe, 1 za prawdziwe.

To nie jest tak w przypadku wszystkich wyrażeń C , które dają logicznie prawdziwe/fałszywe wartości. Na przykład funkcje klasyfikacji znaków is*() zadeklarowane w <ctype.h> (isdigit(), isupper() itd.) Zwracają 0, jeśli warunek jest fałszywy, ale może zwrócić dowolną niezerową wartość, jeśli warunek jest prawdziwy.

Dopóki używasz wynik bezpośrednio jako warunek:

if (isdigit(c)) ... 
if (!isdigit(c)) ... 
if (isdigit(c) || islower(c)) ... 

i nie próbę porównania go do czegoś:

if (isdigit(c) == 1) ... /* WRONG */ 
if (isdigit(c) == true) ... /* ALSO WRONG */ 

to nie powinno spowodować żadnych problemów .

(Ty może bezpiecznie porównać wynik do 0 lub false, ale nie ma dobry powód, aby to zrobić, to właśnie operator ! jest).

Powiązane problemy