352 Stimmen

Unterschied zwischen Vorinkrement und Nachinkrement in einer Schleife?

Gibt es einen Unterschied in ++i y i++ in einem for Schleife? Ist es einfach eine Sache der Syntax?

271voto

Chris S Punkte 63542

a++ wird als Postfix bezeichnet.

addiert 1 zu a und gibt den alten Wert zurück.

++a wird als Präfix bezeichnet.

addiert 1 zu a und gibt den neuen Wert zurück.

C#:

string[] items = {"a","b","c","d"};
int i = 0;
foreach (string item in items)
{
    Console.WriteLine(++i);
}
Console.WriteLine("");

i = 0;
foreach (string item in items)
{
    Console.WriteLine(i++);
}

Ausgabe:

1
2
3
4

0
1
2
3

foreach y while Schleifen hängen davon ab, welchen Inkrementtyp Sie verwenden. Bei for-Schleifen wie unten macht es keinen Unterschied, da Sie den Rückgabewert von i nicht verwenden:

for (int i = 0; i < 5; i++) { Console.Write(i);}
Console.WriteLine("");
for (int i = 0; i < 5; ++i) { Console.Write(i); }

0 1 2 3 4
0 1 2 3 4

Wenn der ausgewertete Wert verwendet wird, ist die Art des Inkrements von Bedeutung:

int n = 0;
for (int i = 0; n < 5; n = i++) { }

237voto

Scott Langham Punkte 55597

Vorinkrement ++i inkrementiert den Wert von i und wertet den neuen inkrementierten Wert aus.

int i = 3;
int preIncrementResult = ++i;
Assert( preIncrementResult == 4 );
Assert( i == 4 );

Post-Inkrement i++ inkrementiert den Wert von i und wertet den ursprünglichen, nicht inkrementierten Wert aus.

int i = 3;
int postIncrementResult = i++;
Assert( postIncrementtResult == 3 );
Assert( i == 4 );

In C++ wird in der Regel die Vorinkrementierung bevorzugt, wenn man beides verwenden kann.

Der Grund dafür ist, dass der Compiler bei der Verwendung von Post-Increment unter Umständen Code erzeugen muss, der eine zusätzliche temporäre Variable erzeugt. Der Grund dafür ist, dass sowohl der vorherige als auch der neue Wert der Variablen, die inkrementiert wird, irgendwo gespeichert werden müssen, da sie an anderer Stelle im ausgewerteten Ausdruck benötigt werden können.

Zumindest in C++ kann es also einen Leistungsunterschied geben, der Sie bei der Wahl der zu verwendenden Methode leitet.

Dies ist hauptsächlich nur dann ein Problem, wenn die zu erhöhende Variable ein benutzerdefinierter Typ mit einem überschriebenen ++-Operator ist. Bei primitiven Typen (int, etc.) gibt es keinen Leistungsunterschied. Es lohnt sich jedoch, den Prä-Inkrement-Operator als Richtlinie zu verwenden, es sei denn, der Post-Inkrement-Operator ist unbedingt erforderlich.

Es gibt eine weitere Diskussion aquí .

In C++, wenn Sie STL verwenden, können Sie for-Schleifen mit Iteratoren verwenden. Diese haben meist überschriebene ++-Operatoren, so dass es eine gute Idee ist, sich an die Vorinkrementierung zu halten. Compiler werden jedoch immer schlauer, und neuere können möglicherweise Optimierungen durchführen, die keinen Leistungsunterschied bedeuten - vor allem, wenn der Typ, der inkrementiert wird, inline in der Header-Datei definiert ist (wie es bei STL-Implementierungen oft der Fall ist), so dass der Compiler sehen kann, wie die Methode implementiert ist, und dann wissen kann, welche Optimierungen sicher durchgeführt werden können. Trotzdem lohnt es sich wahrscheinlich, bei der Vorinkrementierung zu bleiben, da Schleifen sehr oft ausgeführt werden und dies bedeutet, dass eine kleine Leistungseinbuße schnell verstärkt werden kann.


In anderen Sprachen wie C#, in denen der Operator ++ nicht überladen werden kann, gibt es keinen Leistungsunterschied. In einer Schleife verwendet, um die Schleifenvariable zu erhöhen, sind die Operatoren pre und post increment gleichwertig.

Korrektur: Überladen ++ in C # ist erlaubt. Es scheint jedoch, dass im Vergleich zu C++, in C# können Sie nicht überladen die pre und post-Versionen unabhängig. Ich würde also davon ausgehen, dass, wenn das Ergebnis des ++-Aufrufs in C# nicht einer Variablen zugewiesen oder als Teil eines komplexen Ausdrucks verwendet wird, der Compiler die Pre- und Post-Versionen von ++ auf einen Code reduzieren würde, der gleichwertig ist.

89voto

Jon B Punkte 49459

In C# gibt es keinen Unterschied bei Verwendung in einer for-Schleife .

for (int i = 0; i < 10; i++) { Console.WriteLine(i); }

gibt das Gleiche aus wie

for (int i = 0; i < 10; ++i) { Console.WriteLine(i); }

Als o

int i = 0;
Console.WriteLine(i++);   // Prints 0
int j = 0;
Console.WriteLine(++j);   // Prints 1

i

++

79voto

Vinz Punkte 2749

Die Frage ist:

Gibt es einen Unterschied zwischen ++i und i++ in einer for-Schleife?

Die Antwort lautet: Nein .

Warum muss in jeder zweiten Antwort detailliert auf die Vor- und Nachinkrementierung eingegangen werden, wenn diese Frage gar nicht gestellt wird?

Diese for-Schleife:

for (int i = 0; // Initialization
     i < 5;     // Condition
     i++)       // Increment
{
   Output(i);
}

Würde zu diesem Code übersetzen, ohne Schleifen zu verwenden:

int i = 0; // Initialization

loopStart:
if (i < 5) // Condition
{
   Output(i);

   i++ or ++i; // Increment

   goto loopStart;
}

Spielt es nun eine Rolle, ob Sie die i++ o ++i als Inkrement hier? Nein, tut es nicht da der Rückgabewert der Inkrementierungsoperation unbedeutend ist. i wird NACH der Ausführung des Codes innerhalb des for-Schleifenkörpers inkrementiert.

31voto

Da Sie nach dem Unterschied in einer Schleife fragen, vermute ich, Sie meinen

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

In diesem Fall gibt es in den meisten Sprachen keinen Unterschied: Die Schleife verhält sich gleich, unabhängig davon, ob Sie schreiben i++ y ++i . In C++ können Sie Ihre eigenen Versionen der ++-Operatoren schreiben, und Sie können separate Bedeutungen für sie definieren, wenn die i von einem benutzerdefinierten Typ ist (z.B. Ihre eigene Klasse).

Der Grund, warum das oben keine Rolle spielt, ist, dass Sie den Wert von i++ . Eine andere Sache ist, wenn Sie

for(int i=0, a = 0; i<10; a = i++) 
    ...;

Nun, es gibt es einen Unterschied, denn wie andere betonen, i++ bedeutet inkrementieren, aber zum vorherigen Wert auswerten mais ++i bedeutet inkrementieren, sondern auf i (und würde somit den neuen Wert auswerten). Im obigen Fall, a wird der vorherige Wert von i zugewiesen, während i inkrementiert wird.

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