2011-10-07 16 views
19

Cuando, por ejemplo, escribo 7>1 en C (digamos C99 si esta no es una característica que se haya utilizado siempre), ¿puedo esperar que el resultado sea exactamente 1 o solo un valor distinto de cero? ¿Esto es válido para todos los operadores bool?Es el resultado "verdadero" de>, <,!, &&, || o == definido?

+3

lo más probable es un duplicado, pero no estaba capaz de encontrarlo :-( – mbq

+3

@TRD: Incorrecto. La expresión C '7> 1' produce un resultado de tipo' int' con el valor '1'. –

Respuesta

35

En Operadores relacionales §6.5.8 C99, punto 6 (<, >, <= y >=):

Cada uno de los operadores < (menor que),> (mayor que), < = (menor o igual a), y> = (mayor que o igual a) deberá dar si la relación especificada que es verdadero y si es falsa) el resultado ha escriba int.

En cuanto a los operadores de igualdad, que es un poco más lejos en §6.5.9 (== y !=): operadores

El == (igual a) y = (distinto de) son análogos a los operadores relacionales excepto por su menor prioridad) Cada uno de los operadores produce si la relación especificada es verdadera y si es falsa. El resultado tiene el tipo int. Para cualquier par de operandos , exactamente una de las relaciones es verdadera.

La lógica AND y OR lógico todavía un poco más lejos están en §6.5.13 (&&)

El operador & & rendirá si ambos de sus operandos comparar desigual a 0; de lo contrario, produce . El resultado tiene el tipo int.

... y §6.5.14 (||)

La || el operador rendirá si cualquiera de sus operandos compara desigual a 0; de lo contrario, produce . El resultado tiene el tipo int.

Y la semántica del operador aritmético unario ! son más en §6.5.3.3/4:

El resultado del operador negación lógica! es si el valor de su operando compara desigual a 0, si el valor de su operando compara igual a 0. El resultado ha escriba int. La expresión! E es equivalente a (0 == E).

tipo de resultado es int en todos los ámbitos, con 0 y 1 valores posibles. (A menos que me haya perdido algo).

+6

Y convenientemente stdbool.h define verdadero y falso como 1 y 0 (C99 7.16). – Lundin

+0

Bueno, especialmente porque && y || se comportan de manera diferente en otros idiomas (devolviendo el último valor evaluado). Si los operadores estándar no están involucrados, la fijación se puede hacer usando '!!' o [fundición a ' '' bool'] (http://www.jacquesf.com/2011/04/in-defense-of-the-c99-boolean-type/). – Tobu

14

C sigue Postel's Law para sus operadores booleanos: sea conservador en lo que hace, sea liberal en lo que acepta de los demás. Tratará cualquier valor distinto de cero como verdadero en expresiones booleanas, pero siempre producirá un 0 o un 1 en sí mismo. 2 != 3 es siempre 1.

+0

+1 por mencionar la Ley de Postel – glglgl

6

de la norma ISO C99, sección 6.5.8:

6 Cada uno de los operadores < (menor que),> (mayor que), < = (menos de o igual a), y > = (mayor que o igual a) rendirá 1 si la relación especificada es verdadera y 0 si es falsa. El resultado tiene tipo int.

De la sección 6.5.9:

3 El == (igual a) y = (no igual a) los operadores son análogos a los operadores relacionales excepto por su menor precedencia. Cada de los operadores produce 1 si la relación especificada es verdadera y 0 si es falsa. El resultado tiene tipo int. Para cualquier par de operandos, exactamente una de las relaciones es verdadera.

Lo mismo sucede con la conjunción lógica (&&) y (||) operadores disyunción.

PD: A propósito, esta es la razón por la cual los operadores bit a bit (& y |) pueden usualmente usarse como versiones sin cortocircuito de los operadores lógicos.

4

Todos C operadores que producen valores lógicamente verdadero/falso siempre producen un resultado de tipo int con el valor 0 para falsa, 1 para la verdadera.

Ese no es el caso para todas las expresiones C que producen valores lógicamente verdaderos/falsos. Por ejemplo, las funciones de clasificación de caracteres is*() declaradas en <ctype.h> (isdigit(), isupper(), etc.) devuelven 0 si la condición es falsa, pero pueden devolver cualquier valor distinto de cero si la condición es verdadera.

Como siempre y cuando utilice el resultado directamente como una condición:

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

y no lo hacen intento de comparar a algo:

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

esto no debería causar ningún problema .

(Usted puede comparar con seguridad el resultado de 0 o false, pero no hay una buena razón para hacerlo, eso es lo que el operador ! es para.)

Cuestiones relacionadas