Disponible la versión 6 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


4.9.6  Operador Condicional

§1  Sinopsis

El operador condicional es el único operador ternario de la gramática C++ y sirve para tomar decisiones. Proporciona un resultado entre dos posibilidades en función de una condición.

Nota: Puede afirmarse que este operador ha hecho fortuna, ya que existe con la misma sintaxis e idéntico comportamiento, en multitud de otros lenguajes de programación.

§2  Sintaxis

expresion-relacional ? expr1 : expr2

§3  Comentario

El operador condicional ? : produce un resultado. En la expresión E1 ? E2 : E3, E1 es una expresión relacional ( 4.9.12) que se evalúa primero. Si el resultado es cierto, entonces se evalúa E2 y este es el resultado. En caso contrario (si E1 resulta falso), entonces se evalúa E3 y este es el resultado. Observe que si la premisa E1 es cierta, entonces no llega a evaluarse la expresión E3.


§3.1  El operador ? : puede usarse para sustituir ciertas sentencias del tipo if-then-else, aunque puede conducir a expresiones más compactas que las correspondientes if...else. En el ejemplo que sigue, a y se le asigna el valor 100:

x = 10;
y = x > 9 ? 100 : 200;

§3.2  No es necesario poner paréntesis en la primera expresión (E1), ya que la precedencia ( 4.9.0a) de ? : es muy baja (justamente sobre la asignación = ). De todos modos, es aconsejable ponerlos por legibilidad.

y = (x > 9)? 100 : 200;


§3.3  En caso de que E1 no sea una expresión relacional, debe ser un escalar reducible a un booleano (Conversión de tipos 3.2.1b). Por ejemplo es válido:

int y = 6 ? 7: 8;

aunque en este caso el resultado sería siempre y == 7 (el int 6 se se traduce en el booleano true).


§3.4  En ocasiones se aprovechan los efectos laterales ( 4.9) del operador para producir un resultado. Ejemplo:

++x ? ++y : --z;


El compilador GNU cpp permite la ausencia del segundo operando en este tipo de expresiones. Por ejemplo, es válido:

x ? : z;        // E1

El resultado de esta expresión es el valor de x si este es distinto de cero, y z en caso contrario. Por consiguiente, es equivalente a:

x ? x : z;      // E2

El manual informa que este tipo de expresiones solo son de utilidad en caso de que la evaluación de x tenga efectos laterales (por ejemplo, que sea utilizada como argumento en una función), en cuyo caso la expresión E2 tendría efecto lateral doble si x es distinto de cero. La omisión del segundo operador en E1 evitaría esta computación indeseada y dejaría el valor previamente computado sin que se produzca un doble efecto.


§4  E2 y E3 deben seguir las reglas siguientes:

  1. Si E2 y E3 son de tipos distintos, se realiza una conversión de tipo estándar, de forma que el resultado será siempre del mismo tipo, con independencia de E1.
  2. Si E2 y E3 son de tipos unión o estructuras compatibles. El resultado es una unión o estructura del tipo de E2 y E3.
  3. Si E2 y E3 son de tipo void, el resultado es void.
  4. Ambos operandos son punteros a versiones cualificadas o no cualificadas de tipos compatibles. El resultado es un puntero a cualquiera de los tipos de ambos operandos.
  5. Un operando es un puntero y el otro es un puntero nulo. El resultado es un puntero que puede señalar a un tipo del primero o del segundo operando.
  6. Un operando es un puntero a un objeto o tipo incompleto, y el otro es un puntero a una versión cualificada o no cualificada de void. El tipo resultante es el del puntero distinto de void.
§5  Ejemplos

§5.1  Suponiendo que z e y sean Lvalues, las siguientes expresiones son equivalentes:

(x ? y : z) = 10;
(x ? y = 10 : (z = 10));


§5.2
  El bucle que sigue imprime n elementos de una matriz, 10 por línea, con cada columna separada por un espacio y con cada línea terminada por un NL (nueva línea), incluida la última.

for (i = 0; i < n; i++)
printf ("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');


§5.3  Ejemplo:

printf ( "Tienes %d item%s.\n", n, n==1 ? "" : "s");


§5.4
  Ejemplo:

#include <iostream.h>
#include <time.h>

int main(void) {        // ============
  time_t t;
  time(&t);
  struct tm* petm = localtime(&t);
  long dgt = _timezone/60;
  cout << "Diferencia hora local con Greenwich = "
       << abs(dgt) << " minutos " <<
       (dgt == 0 ? "\n" : (dgt < 0 ? "adelanto\n" : "atraso\n"));
  cout << "Horario: " << (petm->tm_isdst ? "Verano" : "Invierno") << endl;
}

Salida:

Diferencia hora local con Greenwich = 60 minutos adelanto
Horario: Verano