Nachdem ich Hidden Features und Dark Corners von C++/STL auf comp.lang.c++.moderated
gelesen hatte, war ich völlig überrascht, dass das folgende Snippet sowohl in Visual Studio 2008 als auch in G ++ 4.4 kompiliert und funktioniert hat.
Hier ist der Code:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Ich würde annehmen, dass dies C ist, da es auch in GCC funktioniert. Wo ist dies in der Norm definiert und woher kommt es?
-->
ist kein Operator. Tatsächlich handelt es sich um zwei separate Operatoren, --
und >
.
Der Code der Bedingung dekrementiert x
, während der ursprüngliche (nicht dekrementierte) Wert von x
zurückgegeben wird, und vergleicht dann den ursprünglichen Wert mit 0
unter Verwendung des Operators >
.
Zum besseren Verständnis könnte die Anweisung folgendermaßen geschrieben werden:
while( (x--) > 0 )
Oder für etwas ganz anderes ... x gleitet auf 0
while (x --\
\
\
\
> 0)
printf("%d ", x);
Nicht so mathematisch, aber ... jedes Bild sagt mehr als tausend Worte ...
Das ist ein sehr komplizierter Operator, daher hat auch ISO/IEC JTC1 (Joint Technical Committee 1) seine Beschreibung in zwei verschiedene Teile des C++ - Standards gestellt.
Abgesehen von Scherzen sind dies zwei verschiedene Operatoren: --
und >
, die in §5.2.6/2 bzw. §5.9 des C++ 03-Standards beschrieben sind.
Es ist gleichbedeutend mit
while (x-- > 0)
x--
(nach Dekrementierung) entspricht x = x-1
, daher wird der Code in Folgendes umgewandelt:
while(x > 0) {
x = x-1;
// logic
}
x
kann in entgegengesetzter Richtung noch schneller auf Null gehen:
int x = 10;
while( 0 <---- x )
{
printf("%d ", x);
}
8 6 4 2
Sie können die Geschwindigkeit mit einem Pfeil steuern!
int x = 100;
while( 0 <-------------------- x )
{
printf("%d ", x);
}
90 80 70 60 50 40 30 20 10
;)
Es ist
#include <stdio.h>
int main(void){
int x = 10;
while( x-- > 0 ){ // x goes to 0
printf("%d ", x);
}
return 0;
}
Nur der Raum lässt die Dinge lustig aussehen, --
dekrementiert und >
vergleicht.
Die Verwendung von -->
hat historische Relevanz. Das Dekrementieren war (und ist in einigen Fällen immer noch) schneller als das Inkrementieren auf der x86-Architektur. Die Verwendung von -->
legt nahe, dass x
zu 0
wechselt, und spricht diejenigen mit mathematischem Hintergrund an.
while( x-- > 0 )
ist, wie das analysiert wird.
Äußerst geek, aber ich werde dies verwenden:
#define as ;while
int main(int argc, char* argv[])
{
int n = atoi(argv[1]);
do printf("n is %d\n", n) as ( n --> 0);
return 0;
}
Ein Buch, das ich gelesen habe (an das ich mich nicht richtig erinnere), besagte: Compiler versuchen, Ausdrücke mit der left right-Regel zum größten Token zu analysieren.
In diesem Fall lautet der Ausdruck:
x-->0
Parses zu den größten Token:
token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0
Für diesen Ausdruck gilt die gleiche Regel :
a-----b
Nach dem Parsen:
token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b
Ich hoffe das hilft, den komplizierten Ausdruck zu verstehen ^^
Dies ist genau das gleiche wie
while (x--)
{
printf("%d ", x);
}
für nicht negative Zahlen
Wie auch immer, wir haben jetzt einen "Gehe zu" -Operator. "-->"
ist leicht als eine Richtung zu merken, und "solange x auf Null geht" bedeutet "gerade".
Außerdem ist es auf einigen Plattformen etwas effizienter als "for (x = 10; x > 0; x --)"
.
Dieser Code vergleicht zuerst x und 0 und dekrementiert dann x. (Auch in der ersten Antwort gesagt: Sie dekrementieren x nach und vergleichen dann x und 0 mit dem >
-Operator.) Siehe die Ausgabe dieses Codes:
9 8 7 6 5 4 3 2 1 0
Wir vergleichen jetzt zuerst und dekrementieren dann, indem wir 0 in der Ausgabe sehen.
Wenn wir zuerst dekrementieren und dann vergleichen möchten, verwenden Sie diesen Code:
#include <stdio.h>
int main(void)
{
int x = 10;
while( --x> 0 ) // x goes to 0
{
printf("%d ", x);
}
return 0;
}
Diese Ausgabe ist:
9 8 7 6 5 4 3 2 1
Mein Compiler druckt 9876543210 aus, wenn ich diesen Code ausführe.
#include <iostream>
int main()
{
int x = 10;
while( x --> 0 ) // x goes to 0
{
std::cout << x;
}
}
Wie erwartet. Das while( x-- > 0 )
bedeutet tatsächlich while( x > 0)
. Der x--
Beitrag dekrementiert x
.
while( x > 0 )
{
x--;
std::cout << x;
}
ist eine andere Art, dasselbe zu schreiben.
Es ist schön, dass das Original so aussieht wie "while x goes to 0".
Zwischen --
und >
fehlt ein Leerzeichen. x
wird nach dem Dekrementieren, dh nach dem Überprüfen der Bedingung x>0 ?
dekrementiert.
--
ist der Dekrement Operator und >
ist der Größer-als Operator.
Die beiden Operatoren werden wie -->
als ein einziger angewendet.
Es ist eine Kombination von zwei Operatoren. Zuerst dient --
zum Dekrementieren des Werts und >
zum Überprüfen, ob der Wert größer als der rechte Operand ist.
#include<stdio.h>
int main()
{
int x = 10;
while (x-- > 0)
printf("%d ",x);
return 0;
}
Die Ausgabe wird sein:
9 8 7 6 5 4 3 2 1 0
Tatsächlich dekrementiert x
nach und wird mit dieser Bedingung überprüft. Es ist nicht -->
, es ist (x--) > 0
Hinweis: Der Wert von x
wird geändert, nachdem die Bedingung überprüft wurde, da sie nach dem Dekrementieren auftritt. Einige ähnliche Fälle können auch auftreten, zum Beispiel:
--> x-->0
++> x++>0
-->= x-->=0
++>= x++>=0
C und C++ befolgen die "Maximum Munch" -Regel. Auf die gleiche Weise, wie a --- b in (a--) - b
übersetzt wird, wird x-->0
in (x--)>0
übersetzt.
Die Regel besagt im Wesentlichen, dass Ausdrücke von links nach rechts gebildet werden, indem das Maximum der Zeichen verwendet wird, die einen gültigen Ausdruck bilden.
Warum all die Komplikationen?
Die einfache Antwort auf die ursprüngliche Frage lautet einfach:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x = x-1;
}
}
Tut das Gleiche. Nicht, dass du es so machen solltest, aber es macht dasselbe und hätte die Frage in einem Beitrag beantwortet.
Der x--
ist nur eine Abkürzung für das oben Gesagte, und >
ist nur ein normaler Wert größer als operator
. Kein großes Rätsel!
Es gibt heutzutage zu viele Leute, die einfache Dinge komplizieren;)
Auf herkömmliche Weise definieren wir eine Bedingung in der while
-Rundenklammer ()
und eine Abschlussbedingung in geschweiften Klammern {}
, aber -->
definiert beide gleichzeitig.
Zum Beispiel:
int abc(void)
{
int a = 5
while((a--) > 0) // Decrement and comparison both at once
{
// Code
}
}
Dies dekrementiert a
und führt die Schleife aus, während a
größer als 0
ist.
Konventionell wäre es wie folgt:
int abc(void)
{
int a = 5;
while(a > 0)
{
a--;
// Code
}
a--;
}
In beiden Fällen tun wir dasselbe und erreichen dieselben Ziele.