¿Qué es el operador “–>” en C++?

5 minutos de lectura

Despues de leer Funciones ocultas y rincones oscuros de C++/STL en comp.lang.c++.moderatedme sorprendió por completo que el siguiente fragmento se compilara y funcionara tanto en Visual Studio 2008 como en G++ 4.4.

Aquí está el código:

#include <stdio.h>
int main()
{
    int x = 10;
    while (x --> 0) // x goes to 0
    {
        printf("%d ", x);
    }
}

Producción:

9 8 7 6 5 4 3 2 1 0

Supongo que esto es C, ya que también funciona en GCC. ¿Dónde se define esto en la norma y de dónde proviene?

--> no es un operador. De hecho, son dos operadores separados, -- y >.

El código del condicional decrementa xal volver xel valor original (no decrementado) de , y luego compara el valor original con 0 utilizando el > operador.

Para entender mejor, la declaración podría escribirse de la siguiente manera:

while( (x--) > 0 )

  • Lo he visto referido en broma como el operador “downto” (codegolf.stackexchange.com/questions/16226/…)

    – Moshé Bildner

    19 de mayo de 2021 a las 13:26

  • Creo que realmente no lo harías. necesitar los paréntesis alrededor x-- aunque hace cumplir aún más la separación. Probablemente sería suficiente asociar tokens más claramente con algo como while (x-- > 0).

    – pax diablo

    3 de julio de 2021 a las 1:18


  • Creo que Stack Overflow necesita una categoría separada como “chistes de sintaxis C ++” o algo así.

    – CuriousPanCake

    10 de junio a las 14:13

  • Creo que Stack Overflow necesita pasar una prueba de programación básica antes de poder hacer preguntas.

    – Michał Jaron

    1 de julio a las 13:27

O por algo completamente diferente… x diapositivas a 0.

while (x --\
            \
             \
              \
               > 0)
     printf("%d ", x);

No tan matemático, pero… cada imagen vale más que mil palabras…

Es un operador muy complicado, así que incluso ISO/IEC JTC1 (Comité Técnico Conjunto 1) colocó su descripción en dos partes diferentes del estándar C++.

Bromas aparte, son dos operadores diferentes: -- y > descritos respectivamente en §5.2.6/2 y §5.9 del estándar C++03.

x puede ir a cero aún más rápido en la dirección opuesta en C++:

int x = 10;

while( 0 <---- x )
{
   printf("%d ", x);
}

8 6 4 2

¡Puedes controlar la velocidad con una flecha!

int x = 100;

while( 0 <-------------------- x )
{
   printf("%d ", x);
}

90 80 70 60 50 40 30 20 10

😉

es equivalente a

while (x-- > 0)

x-- (post decremento) es equivalente a x = x-1 entonces, el código se transforma en:

while(x > 0) {
    x = x-1;
    // logic
}
x--;   // The post decrement done when x <= 0

  • x-- no es en modo alguno equivalente a x = x-1.

    – Roland Illig

    24 de enero a las 17:22

  • Son semánticamente equivalentes en este caso.

    –Weston McNamara

    2 abr a las 13:52


  • --x es equivalente a x = x-1 y x -=1. -1 de mi parte.

    – Adola

    4 de mayo a las 5:38

Es

#include <stdio.h>

int main(void) {
  int x = 10;
  while (x-- > 0) { // x goes to 0
    printf("%d ", x);
  }
  return 0;
}

Solo el espacio hace que las cosas se vean divertidas, -- decrementos y > compara

  • x-- no es en modo alguno equivalente a x = x-1.

    – Roland Illig

    24 de enero a las 17:22

  • Son semánticamente equivalentes en este caso.

    –Weston McNamara

    2 abr a las 13:52


  • --x es equivalente a x = x-1 y x -=1. -1 de mi parte.

    – Adola

    4 de mayo a las 5:38

el uso de --> tiene relevancia histórica. La disminución fue (y aún lo es en algunos casos) más rápida que incrementar en la arquitectura x86. Usando --> sugiere que x va a 0y atrae a aquellos con antecedentes matemáticos.

  • No es exactamente cierto. Decrementar e Incrementar toman la misma cantidad de tiempo, el beneficio de esto es que la comparación con cero es muy rápida en comparación con la comparación con una variable. Esto es cierto para muchas arquitecturas, no solo x86. Cualquier cosa con una instrucción JZ (saltar si es cero). Hurgando puedes encontrar muchos bucles “for” que están escritos al revés para ahorrar ciclos en la comparación. Esto es particularmente rápido en x86, ya que el acto de disminuir la variable establece el indicador cero de manera adecuada, por lo que luego podría bifurcarse sin tener que comparar explícitamente la variable.

    – burito

    30 de diciembre de 2009 a las 5:16

  • Bueno, disminuir hacia cero significa que solo tienes que comparar con 0 por iteración de ciclo, mientras que iterar hacia n significa comparar con n en cada iteración. El primero tiende a ser más fácil (y en algunas arquitecturas, se prueba automáticamente después de cada operación de registro de datos).

    –Joey Adams

    12 de abril de 2010 a las 15:07

  • Esto sería mejor como una nota al pie en otra respuesta o comentario; claramente no explica qué --> significa, que es lo que se le preguntó.

    – Bernhard Barker

    22 mayo 2015 a las 12:55

  • En x86 ASM, el LOOP <address> disminuye el ECX registrarse, luego salta a <address> a menos que la disminución de ECX dio como resultado cero. Disminuir el contador de bucles hacia cero permite que el compilador genere un solo LOOP instrucción, mientras que incrementar o contar a otros valores requiere instrucciones separadas INC/DEC/ADD/SUB, comparación y salto condicional. Los compiladores modernos a menudo pueden convertir otros bucles en un counter --> 0 bucle si el valor de counter no se usa en el bucle.

    – Mark K. Cowan

    8 de julio de 2015 a las 11:26


  • Continuando con mi comentario anterior: MOV ECX, value, @start:, <code>, LOOP @start es un equivalente ASM x86 para counter = value - 1; while (counter --> 0) { <code>; }. Tenga en cuenta que vomitará si value es inicialmente cero, por lo que se necesita una verificación adicional antes del bucle.

    – Mark K. Cowan

    8 de julio de 2015 a las 11:32

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad