1185 Stimmen

Was ist der Unterschied zwischen ++i und i++?

Was ist in C der Unterschied zwischen der Verwendung von ++i y i++ und die im Inkrementierungsblock einer for Schleife?

48voto

Francesco Boi Punkte 6901

Der einzige Unterschied besteht in der Reihenfolge der Operationen zwischen dem Inkrement der Variablen und dem Wert, den der Operator zurückgibt.

Dieser Code und seine Ausgabe erklären den Unterschied:

#include<stdio.h>

int main(int argc, char* argv[])
{
  unsigned int i=0, a;
  printf("i initial value: %d; ", i);
  a = i++;
  printf("value returned by i++: %d, i after: %d\n", a, i);
  i=0;
  printf("i initial value: %d; ", i);
  a = ++i;
  printf(" value returned by ++i: %d, i after: %d\n",a, i);
}

Die Ausgabe ist:

i initial value: 0; value returned by i++: 0, i after: 1
i initial value: 0;  value returned by ++i: 1, i after: 1

Also grundsätzlich ++i gibt den Wert zurück, nachdem er inkrementiert wurde, während i++ den Wert zurückgeben, bevor er inkrementiert wird. Am Ende wird in beiden Fällen der i wird sein Wert inkrementiert.

Ein weiteres Beispiel:

#include<stdio.h>

int main ()
  int i=0;
  int a = i++*2;
  printf("i=0, i++*2=%d\n", a);
  i=0;
  a = ++i * 2;
  printf("i=0, ++i*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  return 0;
}

Ausgabe:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2

Oftmals gibt es keinen Unterschied

Die Unterschiede werden deutlich, wenn der zurückgegebene Wert einer anderen Variablen zugewiesen wird oder wenn die Inkrementierung in Verkettung mit anderen Operationen durchgeführt wird, bei denen der Vorrang von Operationen angewendet wird ( i++*2 unterscheidet sich von ++i*2 aber (i++)*2 y (++i)*2 gibt den gleichen Wert zurück) sind sie in vielen Fällen austauschbar. Ein klassisches Beispiel ist die Syntax der for-Schleife:

for(int i=0; i<10; i++)

hat die gleiche Wirkung wie

for(int i=0; i<10; ++i)

Zu beachtende Regel

Um eine Verwechslung zwischen den beiden Betreibern zu vermeiden, habe ich diese Regel aufgestellt:

Zuordnen der Position des Bedieners ++ in Bezug auf die Variable i in der Reihenfolge der ++ Operation in Bezug auf den Auftrag

Mit anderen Worten:

  • ++ antes de i bedeutet, dass die Inkrementierung durchgeführt werden muss antes de Zuweisung;
  • ++ nach i bedeutet, dass die Inkrementierung durchgeführt werden muss nach Zuweisung:

31voto

OysterD Punkte 6480

Der Grund ++i puede etwas schneller sein als i++ ist das i++ kann eine lokale Kopie des Wertes von i erfordern, bevor dieser erhöht wird, während ++i nie tut. In einigen Fällen optimieren einige Compiler dies weg, wenn möglich... aber es ist nicht immer möglich, und nicht alle Compiler tun dies.

Ich versuche, mich nicht zu sehr auf die Optimierungen von Compilern zu verlassen, daher würde ich Ryan Fox' Rat folgen: Wenn ich beides verwenden kann, verwende ich ++i .

21voto

dusktreader Punkte 3544

Das effektive Ergebnis der Verwendung beider Methoden in einer Schleife ist identisch. Mit anderen Worten, die Schleife tut in beiden Fällen genau das Gleiche.

Im Hinblick auf die Effizienz könnte die Wahl von i++ gegenüber ++i mit einem Nachteil verbunden sein. In Bezug auf die Sprachspezifikation sollte die Verwendung des Post-Inkrement-Operators eine zusätzliche Kopie des Wertes erzeugen, auf den der Operator wirkt. Dies könnte eine Quelle für zusätzliche Operationen sein.

Sie sollten jedoch zwei Hauptprobleme mit der vorangegangenen Logik berücksichtigen.

  1. Moderne Compiler sind großartig. Alle guten Compiler sind intelligent genug, um zu erkennen, dass es sich um eine Inkrementierung einer ganzen Zahl in einer for-Schleife handelt, und optimieren beide Methoden auf denselben effizienten Code. Wenn die Verwendung von Post-Increment gegenüber Pre-Increment tatsächlich dazu führt, dass Ihr Programm langsamer läuft, dann verwenden Sie eine schrecklich Kompilator.

  2. Hinsichtlich des Zeitaufwands sind die beiden Methoden (selbst wenn tatsächlich eine Kopie durchgeführt wird) gleichwertig. Die Anzahl der Anweisungen, die innerhalb der Schleife ausgeführt werden, sollte die Anzahl der Operationen in der Inkrement-Operation deutlich überwiegen. Daher wird in jeder Schleife von signifikanter Größe der Nachteil der Inkrementierungsmethode durch die Ausführung des Schleifenkörpers massiv in den Schatten gestellt. Mit anderen Worten: Es ist viel besser, sich um die Optimierung des Codes in der Schleife zu kümmern als um die Inkrementierung.

Meiner Meinung nach läuft die ganze Angelegenheit einfach auf eine Stilvorliebe hinaus. Wenn Sie meinen, dass die Vorinkrementierung besser lesbar ist, dann verwenden Sie sie. Ich persönlich bevorzuge die Post-Inkrementierung, aber das liegt wahrscheinlich daran, dass mir das so beigebracht wurde, bevor ich etwas über Optimierung wusste.

Dies ist ein typisches Beispiel für eine verfrühte Optimierung, und Fragen wie diese können uns von ernsthaften Problemen beim Design ablenken. Es ist dennoch eine gute Frage, die man sich stellen sollte, denn es gibt keine einheitliche Verwendung oder einen Konsens über die "beste Praxis".

20voto

Usman Punkte 2272

Sie erhöhen beide die Zahl. ++i ist gleichbedeutend mit i = i + 1 .

i++ y ++i sind sehr ähnlich, aber nicht genau gleich. Beide erhöhen die Zahl, aber ++i inkrementiert die Zahl, bevor der aktuelle Ausdruck ausgewertet wird, während i++ erhöht die Zahl, nachdem der Ausdruck ausgewertet wurde.

Beispiel:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3

13voto

Scitech Punkte 487

++i Die eine ist vor der Inkrementierung, die andere nach der Inkrementierung.

i++ : holt das Element und erhöht es dann.
++i i: Inkrementiert i und gibt dann das Element zurück.

Beispiel:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

Ausgabe:

i: 0
i++: 0
++i: 2

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X