sirve significa que poner para operadores operador incremento ejemplos definicion decremento como c++ c increment ternary-operator decrement

significa - para que sirve++ en c++



¿Es seguro colocar operadores de incremento/decremento dentro de operadores ternarios/condicionales? (5)

Entiendo el resultado, pero ¿es este comportamiento indefinido o no?

El código está perfectamente definido. El estándar C11 dice:

6.5.15 Operador condicional

Se evalúa el primer operando; hay un punto de secuencia entre su evaluación y la evaluación del segundo o tercer operando (el que se evalúe). El segundo operando se evalúa solo si el primero se compara con 0 ; el tercer operando se evalúa solo si el primero se compara igual a 0 ; el resultado es el valor del segundo o tercer operando (el que se evalúe), convertido al tipo descrito a continuación.110)

6.5.14 Operador OR lógico

A diferencia del bitwise | operador, el || el operador garantiza la evaluación de izquierda a derecha ; Si se evalúa el segundo operando, hay un punto de secuencia entre las evaluaciones del primer y segundo operandos . Si el primer operando se compara de manera desigual con 0 , el segundo operando no se evalúa.

Más wiki explica con el ejemplo:

  • Entre la evaluación de los operandos izquierdo y derecho del && (AND lógico), || (OR lógico) (como parte de la evaluación de cortocircuito), y comma operators . Por ejemplo, en la expresión *p++ != 0 && *q++ != 0 , todos los efectos secundarios de la subexpresión *p++ != 0 se completan antes de cualquier intento de acceso a q .

  • Entre la evaluación del primer operando del operador ternario de "interrogación" y el segundo o tercer operando. Por ejemplo, en la expresión a = (*p++) ? (*p++) : 0 a = (*p++) ? (*p++) : 0 hay un punto de secuencia después de la primera *p++ , lo que significa que ya se ha incrementado en el momento en que se ejecuta la segunda instancia.

La regla para || y ?: es igual para C ++ (sección 5.15 y 5.16) que en C.

¿El orden de evaluación está garantizado en cualquier caso?

Sí. El orden de evaluación de los operandos de los operadores || , && y ?: se garantiza que será de izquierda a derecha.

Aquí un ejemplo

#include <iostream> using namespace std; int main() { int x = 0; cout << (x == 0 ? x++ : x) << endl; //operator in branch cout << "x=" << x << endl; cout << (x == 1 || --x == 0 ? 1 : 2) << endl; //operator in condition cout << "x=" << x << endl; return 0; }

salida:

0 x=1 1 x=1

Entiendo el resultado, pero ¿ es este comportamiento indefinido o no? ¿El orden de evaluación está garantizado en cualquier caso?

Incluso si tengo garantía, estoy bastante consciente de que el uso de incrementos / decrementos puede convertirse rápidamente en un problema para la legibilidad. Solo pregunto porque vi un código similar e inmediatamente no estaba seguro, dado que hay muchos ejemplos de uso ambiguo / indefinido de operadores de incremento / decremento, como ...

  • C ++ no define el orden en que se evalúan los parámetros de la función.

    int nValue = Add(x, ++x);

  • El lenguaje C ++ dice que no puede modificar una variable más de una vez entre los puntos de secuencia.

    x = ++y + y++

  • Debido a que los operadores de incremento y decremento tienen efectos secundarios, el uso de expresiones con operadores de incremento o decremento en una macro de preprocesador puede tener resultados no deseados.

    #define max(a,b) ((a)<(b))?(b):(a) k = max( ++i, j );


Hay un orden de ejecución garantizado en operadores ternarios y booleanos && y || Operaciones, por lo que no hay conflicto en los puntos de secuencia de evaluación.

Uno a la vez

cout << (x == 0 ? x++ : x) << endl; //operator in branch

Siempre generará x pero lo incrementará solo si era 0.

cout << (x == 1 || --x == 0 ? 1 : 2) << endl; //operator in condition

Esto también está bien definido, si x era 1 no evaluará el RHS, si no lo --x disminuiría pero --x nunca será 0, por lo que será verdadero si x == 1, en cuyo caso x Ahora también será 0.

En el último caso, si x es INT_MIN no es un comportamiento bien definido para disminuirlo (y se ejecutaría).

Eso no puede suceder en el primer caso donde x no será 0 si es INT_MAX por lo que está seguro.


Para el operador condicional (§5.16 [expr.cond] / p1):

Cada cálculo de valor y efecto secundario asociado con la primera expresión se secuencia antes de cada cálculo de valor y efecto secundario asociado con la segunda o tercera expresión.

Para el operador lógico OR (§5.15 [expr.log.or] / p1-2):

el segundo operando no se evalúa si el primer operando se evalúa como true . [...] Si se evalúa la segunda expresión, cada cálculo de valor y efecto secundario asociado con la primera expresión se secuencia antes de cada cálculo de valor y efecto secundario asociado con la segunda expresión.

El comportamiento de su código está bien definido.


Sí, es seguro usar los operadores de incremento / decremento que tiene. Esto es lo que está sucediendo en su código:

Fragmento # 1

cout << (x == 0 ? x++ : x) << endl; //operator in branch

En este fragmento, estás probando si x == 0 , lo cual es true . Como es true , tu expresión ternaria evalúa el x++ . Como está utilizando un incremento posterior aquí, el valor original de x se imprime en la secuencia de salida estándar, y luego se incrementa x .

Fragmento # 2

cout << (x == 1 || --x == 0 ? 1 : 2) << endl; //operator in condition

Este fragmento de código es un poco más confuso, pero aún produce un resultado predecible. En este punto, x = 1 del primer fragmento. En la expresión ternaria, la parte condicional se evalúa primero; sin embargo, debido al Short-Circuiting , la segunda condición, --x == 0 , nunca se evalúa.

Para C ++ los operadores || y && son los operadores booleanos de cortocircuito para OR lógico y lógico AND respectivamente. Cuando utiliza estos operadores, sus condiciones se verifican (de izquierda a derecha) hasta que se pueda determinar el resultado final. Una vez determinado el resultado, no se verifican más condiciones.

En cuanto al fragmento 2, su primera condición verifica si x == 1 . Dado que su primera condición se evalúa como true y está utilizando el OR lógico, no es necesario seguir evaluando otras condiciones. Eso significa que --x == 0 nunca se ejecuta .

Una nota rápida sobre el cortocircuito:

El cortocircuito es útil para aumentar el rendimiento de su programa. Supongamos que tiene una condición como esta que llama a varias funciones caras:

if (task1() && task2()) { //...Do something... }

En este ejemplo, nunca se debe llamar a task1 menos que task1 complete con éxito ( task2 depende de algunos datos que se alteran por task1 ).

Debido a que estamos utilizando un operador AND de cortocircuito , si la task1 falla al devolver false , la instrucción if tiene la información suficiente para salir temprano y dejar de verificar otras condiciones. Esto significa que task2 nunca se llama.


En C, el valor almacenado de un objeto solo puede modificarse una vez entre dos puntos de secuencia.

Se produce un punto de secuencia:

  1. Al final de la expresión plena.
  2. En el && , || y ?: operadores
  3. En una llamada de función.

Entonces, por ejemplo, esta expresión x = i++ * i++ no está definida , mientras que x = i++ && i++ es perfectamente legal .

Tu código muestra un comportamiento definido .

int x = 0;

cout << (x == 0? x ++: x) << endl;

En la expresión anterior, x es 0 , por lo que x++ se ejecutará, aquí x ++ es un incremento posterior, por lo que generará 0 .

cout << "x =" << x << endl;

En la expresión anterior, como x ahora tiene valor 1 la salida será 1 .

cout << (x == 1 || --x == 0? 1: 2) << endl;

Aquí x es 1 por lo que la siguiente condición no se evalúa ( --x == 0 ) y la salida será 1 .

cout << "x =" << x << endl;

Como la expresión --x == 0 no se evalúa, la salida será nuevamente 1 .