Disponible la nueva versión "donationware" 7.3 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