2010-07-23 22 views
30

Estaba escribiendo una aplicación de consola que trataría de "adivinar" un número por prueba y error, funcionó bien y todo eso me dejó preguntándome sobre cierta parte que yo escribió distraídamente,?: Comportamiento del operador condicional ternario al dejar una expresión vacía

el código es:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int x,i,a,cc; 
    for(;;){ 
    scanf("%d",&x); 
    a=50; 
    i=100/a; 
for(cc=0;;cc++) 
{ 
    if(x<a) 
    { 
     printf("%d was too big\n",a); 
     a=a-((100/(i<<=1))?:1); 

    } 
    else if (x>a) 
    { 
     printf("%d was too small\n",a); 
     a=a+((100/(i<<=1))?:1); 

    } 
    else 
    { 
     printf("%d was the right number\n-----------------%d---------------------\n",a,cc); 
     break; 
    } 
} 
} 
return 0; 
} 

Más concretamente la parte que me confunde es

a=a+((100/(i<<=1))?:1); 
//Code, code 
a=a-((100/(i<<=1))?:1); 

he usado para hacer su ((100/(i<<=1))?:1) re que si 100/(i<<=1) devolviera 0 (o falso) la expresión completa evaluaría a 1 ((100/(i<<=1))?:***1***), y dejé la parte del condicional que funcionaría si fuera verdadera ((100/(i<<=1))? _this space_ :1) vacía, parece funcionar correctamente pero ¿hay algún riesgo al dejar eso? parte del condicional vacío?

+0

Este tipo de condicional se denomina operación ternaria. Puede obtener una mejor respuesta si vuelve a etiquetar o volver a titular su publicación para incluir 'ternario'. –

+1

@Segphault: se llama * el * operador condicional (en C). Es un ejemplo de * a * operador ternario que es un término genérico que significa cualquier operador con tres operandos. – JeremyP

+0

Si tiene dudas, que conducen a esta pregunta, no hay duda de que debería haber hecho explícita la asignación de casos verdaderos. TooBored .... Considera no codificar los juegos de consola tontos, porque es un retroalimentador de aburrimiento positivo. – jpinto3912

Respuesta

52

Esta es una extensión GNU C (consulte ?: wikipedia entry), por lo que para la portabilidad debe indicar explícitamente el segundo operando.

En el caso 'verdadero', devuelve el resultado del condicional.

Las siguientes afirmaciones son casi equivalentes:

a = x ?: y; 
a = x ? x : y; 

La única diferencia está en la primera declaración, x siempre se evalúa una vez, mientras que en el segundo, x serán evaluados dos veces si es cierto. Entonces la única diferencia es cuando la evaluación de x tiene efectos secundarios.

De cualquier manera, consideraría que este es un uso sutil de la sintaxis ... y si tiene empatía con quienes mantienen su código, debe indicar explícitamente el operando. :)

Por otro lado, es un buen truco para un caso de uso común.

+5

Casi equivalente ... excepto que 'x' se evalúa solo una vez en' x?: y'. – kennytm

+0

@KennyTM: Es cierto, debería decirlo explícitamente. – Stephen

+1

Intenté esta sintaxis ternaria con el segundo operando faltante en xlc (IBM XL C/C++ para AIX, V11.1) y también funcionó. – Ted

16

Esto es GCC extension al lenguaje C. Cuando no aparece nada entre ?:, el valor de la comparación se usa en el caso verdadero.

El operando del medio en una expresión condicional se puede omitir. Entonces, si el primer operando es distinto de cero, su valor es el valor de la expresión condicional.

Por lo tanto, la expresión

    x ? : y

tiene el valor de x si es distinto de cero; de lo contrario, el valor de y.

este ejemplo es perfectamente equivalente a

    x ? x : y

En este caso sencillo, la capacidad de omitir el operando media no es especialmente útil. Cuando resulta útil es cuando el primer operando lo hace, o puede (si es un argumento macro) contener un efecto secundario. Luego repetir el operando en el medio realizaría el efecto secundario dos veces. Omitir el operando medio utiliza el valor ya calculado sin los efectos indeseables de volver a calcularlo.

Cuestiones relacionadas