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
foreachund whileSchleifen hängen davon ab, welchen Inkrementtyp Sie verwenden. Bei for-Schleifen wie unten macht es keinen Unterschied, da Sie nicht den Rückgabewert von i 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, wird die Art des Inkrements signifikant:
Dies ist nicht einmal das, wonach der Benutzer gefragt hat.
Dimitri
223
Pre-Inkrement ++ i erhöht den Wert von i und wertet den neuen inkrementierten Wert aus.
int i = 3;
int preIncrementResult = ++i;
Assert( preIncrementResult == 4 );
Assert( i == 4 );
Nach dem Inkrementieren von i ++ wird der Wert von i erhöht und auf den ursprünglichen nicht inkrementierten Wert ausgewertet.
int i = 3;
int postIncrementResult = i++;
Assert( postIncrementtResult == 3 );
Assert( i == 4 );
In C ++ wird normalerweise das Vorinkrement bevorzugt, wenn Sie eines von beiden verwenden können.
Dies liegt daran, dass der Compiler bei Verwendung von Post-Inkrement möglicherweise Code generieren muss, der eine zusätzliche temporäre Variable erstellt. Dies liegt daran, dass sowohl der vorherige als auch der neue Wert der inkrementierten Variablen irgendwo gespeichert werden müssen, da sie möglicherweise an anderer Stelle im ausgewerteten Ausdruck benötigt werden.
Zumindest in C ++ kann es also einen Leistungsunterschied geben, der Sie bei der Auswahl der zu verwendenden Elemente unterstützt.
Dies ist hauptsächlich dann nur dann ein Problem, wenn die inkrementierte Variable ein benutzerdefinierter Typ mit einem überschriebenen ++ - Operator ist. Für primitive Typen (int usw.) gibt es keinen Leistungsunterschied. Es lohnt sich jedoch, sich an den Operator vor dem Inkrementieren als Richtlinie zu halten, es sei denn, der Operator nach dem Inkrementieren ist definitiv das, was erforderlich ist.
Wenn Sie in C ++ STL verwenden, verwenden Sie möglicherweise for-Schleifen mit Iteratoren. Diese haben hauptsächlich überschriebene ++ - Operatoren, daher ist es eine gute Idee, sich an das Vorinkrementieren zu halten. Compiler werden jedoch immer intelligenter, und neuere können möglicherweise Optimierungen durchführen, die bedeuten, dass es keinen Leistungsunterschied gibt - insbesondere, wenn der zu inkrementierende Typ in der Header-Datei inline definiert wird (wie dies bei STL-Implementierungen häufig der Fall ist), damit der Compiler sehen kann, wie Die Methode ist implementiert und kann dann wissen, welche Optimierungen sicher durchgeführt werden können. Trotzdem lohnt es sich wahrscheinlich immer noch, sich an das Vorinkrementieren zu halten, da Schleifen häufig ausgeführt werden und dies bedeutet, dass ein kleiner Leistungsverlust bald verstärkt werden könnte.
In anderen Sprachen wie C #, in denen der ++ - Operator nicht überladen werden kann, gibt es keinen Leistungsunterschied. In einer Schleife zum Vorrücken der Schleifenvariablen werden die Operatoren vor und nach dem Inkrementieren äquivalent.
Korrektur: Überladen von ++ in C # ist zulässig. Es scheint jedoch, dass Sie in C # im Vergleich zu C ++ die Vor- und Nachversionen nicht unabhängig voneinander überladen können. Wenn das Ergebnis des Aufrufs von ++ in C # keiner Variablen zugewiesen oder als Teil eines komplexen Ausdrucks verwendet wird, würde der Compiler die Vor- und Nachversionen von ++ auf Code reduzieren, der eine gleichwertige Leistung erbringt.
Wäre es nicht großartig gewesen, wenn C ++ ++ C genannt worden wäre, was darauf hinweist, dass Sie damit einen gut optimierten Code schreiben können.
Naveen
9
Sollten moderne Compiler dies nicht optimieren können, wenn der resultierende Wert offensichtlich sowieso weggeworfen wird?
Che
6
@che - Sie tun dies, wenn es sich um einen einfachen Typ handelt. Klassen, die Operator ++ überladen (z. B. Iteratoren), sind jedoch eine andere Geschichte.
Ferruccio
7
@che: Das ist eine gute Frage. Der Grund, warum C ++ - Compiler "CustomType ++" nicht ersetzen; mit "++ CustomType;" Dies liegt daran, dass nicht garantiert werden kann, dass beide benutzerdefinierten Funktionen den gleichen Effekt haben. Sie sollten ... aber es gibt keine Garantie.
Drew Dormann
2
@ michael.bartnett: Guter Punkt, Überladung ++ in C # scheint verfügbar zu sein. Es scheint jedoch, dass Sie in c # im Vergleich zu c ++ die Vor- und Nachversionen nicht unabhängig voneinander überladen können. Wenn das Ergebnis des Aufrufs von ++ in C # keiner Variablen zugewiesen oder als Teil eines komplexen Ausdrucks verwendet wird, würde der Compiler die Vor- und Nachversionen von ++ auf Code reduzieren, der eine gleichwertige Leistung erbringt.
Scott Langham
83
In C # gibt es keinen Unterschied, wenn es in einer for-Schleife verwendet wird .
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); }
Wie andere bereits betont haben, habe ich bei der allgemeinen Verwendung von i ++ und ++ einen subtilen, aber signifikanten Unterschied:
int i = 0;
Console.WriteLine(i++); // Prints 0
int j = 0;
Console.WriteLine(++j); // Prints 1
Fazit: Die gleiche Post / Pre-Inkrement-Semantik wie in C ++.
xtofl
@xtofl - nicht sicher, was dein Punkt ist? Ich habe gerade c # für mein Beispiel ausgewählt.
Jon B
3
Ich denke nicht, dass der erste Punkt relevant ist. In einer for-Schleife (c # oder nicht) wird der Inkrementteil immer nach dem Hauptteil der Schleife ausgeführt. Nach der Ausführung wird die Variable geändert, unabhängig davon, ob ein Post- oder Pre-Inkrement verwendet wurde.
MatthieuP
9
@MatthieuP - Ich habe die Frage als "spielt es eine Rolle, ob Sie i ++ oder ++ i in einer for-Schleife verwenden" gelesen. Die Antwort lautet "nein, tut es nicht".
Jon B
1
@ JonB Die Reihenfolge der Operationen in der Antwort ist nicht genau korrekt. Beide ++iund i++führen dieselben Vorgänge in derselben Reihenfolge aus: temporäre Kopie von erstellen i; Erhöhen Sie den temporären Wert, um einen neuen Wert zu erzeugen (um den temporären Wert nicht zu überschreiben). Speichern Sie den neuen Wert in i; Wenn ++idas Ergebnis zurückgegeben wird, ist dies der neue Wert. Wenn i++das Ergebnis zurückgegeben wird, handelt es sich um die temporäre Kopie. Detailliertere Antwort hier: stackoverflow.com/a/3346729/3330348
PiotrWolkowski
51
Die Frage ist:
Gibt es einen Unterschied zwischen ++ i und i ++ in einer for-Schleife?
Die Antwort lautet: Nein .
Warum muss jede zweite Antwort detaillierte Erklärungen zum Inkrementieren vor und nach dem Inkrementieren enthalten, wenn dies nicht einmal gefragt wird?
Diese for-Schleife:
for (int i = 0; // Initialization
i < 5; // Condition
i++) // Increment
{
Output(i);
}
Würde ohne Verwendung von Schleifen in diesen Code übersetzen:
int i = 0; // Initialization
loopStart:
if (i < 5) // Condition
{
Output(i);
i++ or ++i; // Increment
goto loopStart;
}
Ist es jetzt wichtig, ob Sie hier i++oder ++ials Inkrement setzen? Nein, der Rückgabewert der Inkrementierungsoperation ist unbedeutend. iwird NACH der Ausführung des Codes erhöht, der sich innerhalb des for-Schleifenkörpers befindet.
Dies ist buchstäblich die erste Antwort, die direkt auf den Punkt kommt. Vielen Dank.
Yassir
1
Dies ist nicht die beste Antwort, da die Implementierung von ++ x möglicherweise schneller als x ++ ist, wenn die for-Schleife ein komplexes Objekt inkrementiert (etwas anderes als int!) (Siehe herbsutter.com/2013/05/13/gotw -2-Lösung-temporäre-Objekte )
JCx
30
Da Sie nach dem Unterschied in einer Schleife fragen, meinen Sie das wohl
for(int i=0; i<10; i++)
...;
In diesem Fall haben Sie in den meisten Sprachen keinen Unterschied: Die Schleife verhält sich unabhängig davon, ob Sie schreiben i++und ++i. In C ++ können Sie Ihre eigenen Versionen der ++ - Operatoren schreiben und separate Bedeutungen für diese definieren, wenn ies sich um einen benutzerdefinierten Typ handelt (z. B. Ihre eigene Klasse).
Der Grund, warum es oben nicht wichtig ist, ist, dass Sie den Wert von nicht verwenden i++. Eine andere Sache ist, wenn Sie es tun
for(int i=0, a = 0; i<10; a = i++)
...;
Nun gibt es einen Unterschied, denn wie andere betonen, i++bedeutet dies Inkrementieren, aber auf den vorherigen Wert auswerten , aber Inkrementieren++i bedeuten , aber auswerteni (daher würde es auf den neuen Wert auswerten). Im obigen Fall awird der vorherige Wert von i zugewiesen, während i inkrementiert wird.
In C ++ ist es dem Compiler nicht immer möglich, das temporäre Erstellen zu vermeiden. Daher wird das Vorinkrementierungsformular bevorzugt.
David Thornley
Wenn Sie ein i vom benutzerdefinierten Typ haben, können diese beim Schreiben unterschiedliche Semantiken haben. Wenn Sie jedoch ein i vom primitiven Typ verwenden, macht dies für die erste Schleife keinen Unterschied. Da dies eine sprachunabhängige Frage ist, habe ich mir vorgenommen, nicht zu viel über C ++ - spezifische Dinge zu schreiben.
Johannes Schaub - litb
15
Wie dieser Code zeigt (siehe die entschlüsselte MSIL in den Kommentaren), unterscheidet der C # 3-Compiler in einer for-Schleife nicht zwischen i ++ und ++ i. Wenn der Wert von i ++ oder ++ i verwendet würde, würde es definitiv einen Unterschied geben (dies wurde in Visutal Studio 2008 / Release Build kompiliert):
Eins (++ i) ist Vorinkrement, eins (i ++) ist Nachinkrement. Der Unterschied besteht darin, welcher Wert sofort vom Ausdruck zurückgegeben wird.
// Psuedocode
int i = 0;
print i++; // Prints 0
print i; // Prints 1
int j = 0;
print ++j; // Prints 1
print j; // Prints 1
Edit: Woops, ignorierte die Loop-Seite der Dinge völlig. Es gibt keinen tatsächlichen Unterschied zwischen for-Schleifen, wenn es sich um den 'Step'-Teil handelt (for (...; ...;)), aber in anderen Fällen kann er ins Spiel kommen.
Es gibt keinen Unterschied, ob Sie den Wert nach dem Inkrementieren in der Schleife nicht verwenden.
for (int i = 0; i < 4; ++i){
cout<<i;
}
for (int i = 0; i < 4; i++){
cout<<i;
}
Beide Schleifen geben 0123 aus.
Der Unterschied ergibt sich jedoch, wenn Sie den Wert nach dem Inkrementieren / Dekrementieren in Ihrer Schleife wie folgt verwenden:
Pre-Increment-Schleife:
for (int i = 0,k=0; i < 4; k=++i){
cout<<i<<" ";
cout<<k<<" ";
}
Ausgabe: 0 0 1 1 2 2 3 3
Post-Increment-Schleife:
for (int i = 0, k=0; i < 4; k=i++){
cout<<i<<" ";
cout<<k<<" ";
}
Ausgabe: 0 0 1 0 2 1 3 2
Ich hoffe, der Unterschied wird durch den Vergleich der Ausgabe deutlich. Hierbei ist zu beachten, dass das Inkrementieren / Dekrementieren immer am Ende der for-Schleife durchgeführt wird und daher die Ergebnisse erklärt werden können.
Hier ist ein Java-Beispiel und der Byte-Code, Post- und Pre-Increment zeigen keinen Unterschied im Bytecode:
public class PreOrPostIncrement {
static int somethingToIncrement = 0;
public static void main(String[] args) {
final int rounds = 1000;
postIncrement(rounds);
preIncrement(rounds);
}
private static void postIncrement(final int rounds) {
for (int i = 0; i < rounds; i++) {
somethingToIncrement++;
}
}
private static void preIncrement(final int rounds) {
for (int i = 0; i < rounds; ++i) {
++somethingToIncrement;
}
}
}
Und nun zum Bytecode (javap -private -c PreOrPostIncrement):
Ja da ist. Die Differenz liegt im Rückgabewert. Der Rückgabewert von "++ i" ist der Wert nach dem Inkrementieren von i. Die Rückgabe von "i ++" ist der Wert vor dem Inkrementieren. Dies bedeutet, dass der Code wie folgt aussieht:
int a = 0;
int b = ++a; // a is incremented and the result after incrementing is saved to b.
int c = a++; // a is incremented again and the result before incremening is saved to c.
Daher wäre a 2 und b und c wären jeweils 1.
Ich könnte den Code folgendermaßen umschreiben:
int a = 0;
// ++a;
a = a + 1; // incrementing first.
b = a; // setting second.
// a++;
c = a; // setting first.
a = a + 1; // incrementing second.
In beiden Fällen gibt es keinen tatsächlichen Unterschied. ' i' Wird um 1 erhöht.
Es gibt jedoch einen Unterschied, wenn Sie es in einem Ausdruck verwenden, zum Beispiel:
int i = 1;
int a = ++i;
// i is incremented by one and then assigned to a.
// Both i and a are now 2.
int b = i++;
// i is assigned to b and then incremented by one.
// b is now 2, and i is now 3
++ i und i ++ bieten mehr als Schleifen und Leistungsunterschiede. ++ i gibt einen l-Wert zurück und i ++ gibt einen r-Wert zurück. Basierend darauf gibt es viele Dinge, die Sie mit (++ i) tun können, aber nicht mit (i ++).
1- It is illegal to take the address of post increment result. Compiler won't even allow you.
2- Only constant references to post increment can exist, i.e., of the form const T&.
3- You cannot apply another post increment or decrement to the result of i++, i.e., there is no such thing as I++++. This would be parsed as ( i ++ ) ++ which is illegal.
4- When overloading pre-/post-increment and decrement operators, programmers are encouraged to define post- increment/decrement operators like:
T& operator ++ ( )
{
// logical increment
return *this;
}
const T operator ++ ( int )
{
T temp( *this );
++*this;
return temp;
}
Da es keine Rolle spielt, warum sollte es Sie verwirren, ob jemand i ++ geschrieben hat? Gibt es einen Grund, warum jemand lieber ++ i schreiben würde?
Dronz
2
Wie @Jon B sagt, gibt es keinen Unterschied in einer for-Schleife.
In einer whileoder- do...whileSchleife können Sie jedoch einige Unterschiede feststellen, wenn Sie einen Vergleich mit dem ++ioder durchführeni++
while(i++ < 10) { ... } //compare then increment
while(++i < 10) { ... } //increment then compare
Während Arrays (ich denke alle) und einige andere Funktionen und Aufrufe 0 als Ausgangspunkt verwenden, müssten Sie i auf -1 setzen, damit die Schleife mit dem Array funktioniert, wenn Sie ++ i verwenden .
Bei Verwendung von i ++ verwendet der folgende Wert den erhöhten Wert. Man könnte sagen, i ++ ist die Art und Weise, wie Menschen zählen, weil man mit einer 0 beginnen kann .
Das obige Bild zeigt, dass FOR in WHILE konvertiert werden kann , da sie letztendlich denselben Assembler-Code haben (zumindest in gcc). So können wir FOR in ein paar Teile zerlegen, um zu verstehen, was es tut.
for(i =0; i <5;++i){DoSomethingA();DoSomethingB();}
ist gleich der WHILE- Version
i =0;//first argument (a statement) of forwhile(i <5/*second argument (a condition) of for*/){DoSomethingA();DoSomethingB();++i;//third argument (another statement) of for}
Dies bedeutet, dass Sie FOR als einfache Version von WHILE verwenden können :
Das erste Argument von FOR (int i) wird außerhalb vor der Schleife ausgeführt.
Das dritte Argument von FOR (i ++ oder ++ i) wird in der letzten Zeile der Schleife ausgeführt.
TL: DR: Egal ob i++oder ++i, wir wissen, dass sie, wenn sie eigenständig sind, keinen Unterschied machen, sondern +1 für sich.
In der Schule unterrichten sie normalerweise den i ++ Weg, aber es gibt auch viele Leute, die den ++ i Weg aus mehreren Gründen bevorzugen .
HINWEIS: In der Vergangenheit hat i ++ nur sehr geringe Auswirkungen auf die Leistung, da es nicht nur eins für sich plus, sondern auch den ursprünglichen Wert im Register behält. Im Moment macht es jedoch keinen Unterschied, da der Compiler das Plus-Teil gleich macht.
Bei Schleifen kann es einen Unterschied geben. Dies ist die praktische Anwendung von Post / Pre-Inkrement.
int i = 0;
while(i++ <= 10) {
Console.Write(i);
}
Console.Write(System.Environment.NewLine);
i = 0;
while(++i <= 10) {
Console.Write(i);
}
Console.ReadLine();
Während der erste bis 11 zählt und 11-mal schleift, tut der zweite nicht.
Meistens wird dies eher in einer einfachen Weile verwendet (x--> 0); - - Schleife, um zum Beispiel alle Elemente eines Arrays zu iterieren (ausgenommen hier foreach-Konstrukte).
Beide erhöhen die Zahl. ++iist äquivalent zu i = i + 1.
i++und ++isind sehr ähnlich, aber nicht genau gleich. Beide erhöhen die Zahl, ++ierhöhen jedoch die Zahl, bevor der aktuelle Ausdruck ausgewertet wirdi++ die Zahl erhöht wird, nachdem der Ausdruck ausgewertet wurde.
int i = 3;
int a = i++; // a = 3, i = 4
int b = ++a; // b = 4, a =
Ja, es gibt einen Unterschied zwischen ++iund i++in einer forSchleife, wenn auch in ungewöhnlichen Anwendungsfällen. wenn eine Schleifenvariable mit Inkrement / Dekrement-Operator im for-Block oder innerhalb des Schleifentestausdrucks oder mit einer der Schleifenvariablen verwendet wird . Nein, es ist nicht einfach eine Syntaxsache.
Wie iin einem Code bedeutet das Auswerten des Ausdrucks iund der Operator bedeutet nicht eine Auswertung, sondern nur eine Operation;
++ibedeutet Inkrementwert ivon 1 und später auswerteni ,
i++bedeutet auswerten iund später den Wert ium 1 erhöhen .
Was also aus jeweils zwei Ausdrücken erhalten wird, unterscheidet sich, weil das, was ausgewertet wird, in jedem unterschiedlich ist. Alles gleich für--i undi--
Beispielsweise;
let i = 0
i++ // evaluates to value of i, means evaluates to 0, later increments i by 1, i is now 1
0
i
1
++i // increments i by 1, i is now 2, later evaluates to value of i, means evaluates to 2
2
i
2
In ungewöhnlichen Anwendungsfällen ist das nächste Beispiel zwar nützlich oder nicht wichtig, es zeigt jedoch einen Unterschied
Es beantwortet direkter, was gefragt wird, als die Antworten, die ich gelesen habe.
Selçuk
-2
Für ibenutzerdefinierte Typen könnten ( sollten aber nicht ) diese Operatoren im Kontext eines Schleifenindex signifikant unterschiedliche Sematiken haben, und dies könnte (sollte aber nicht) das Verhalten der beschriebenen Schleife beeinflussen.
Außerdem ist c++es im Allgemeinen am sichersten, das Pre-Inkrement-Formular ( ++i) zu verwenden, da es einfacher zu optimieren ist. (Scott Langham hat mich zu diesem Leckerbissen geschlagen . Verfluche dich, Scott)
Die Semantik von Postfix soll größer als das Präfix sein. -1
xtofl
-2
Ich weiß es nicht für die anderen Sprachen, aber in Java ++ ist i ein Präfixinkrement, was bedeutet: Erhöhe i um 1 und verwende dann den neuen Wert von i in dem Ausdruck, in dem ich mich befinde , und i ++ ist ein Postfixinkrement , das Folgendes bedeutet : Verwenden Sie den aktuellen Wert von i im Ausdruck und erhöhen Sie ihn dann um 1. Beispiel:
public static void main(String [] args){
int a = 3;
int b = 5;
System.out.println(++a);
System.out.println(b++);
System.out.println(b);
Antworten:
a ++ wird als Postfix bezeichnet.
addiere 1 zu a, gibt den alten Wert zurück.
++ a ist als Präfix bekannt.
addiere 1 zu a, gibt den neuen Wert zurück.
C #:
Ausgabe:
foreach
undwhile
Schleifen hängen davon ab, welchen Inkrementtyp Sie verwenden. Bei for-Schleifen wie unten macht es keinen Unterschied, da Sie nicht den Rückgabewert von i verwenden:Wenn der ausgewertete Wert verwendet wird, wird die Art des Inkrements signifikant:
quelle
Pre-Inkrement ++ i erhöht den Wert von i und wertet den neuen inkrementierten Wert aus.
Nach dem Inkrementieren von i ++ wird der Wert von i erhöht und auf den ursprünglichen nicht inkrementierten Wert ausgewertet.
In C ++ wird normalerweise das Vorinkrement bevorzugt, wenn Sie eines von beiden verwenden können.
Dies liegt daran, dass der Compiler bei Verwendung von Post-Inkrement möglicherweise Code generieren muss, der eine zusätzliche temporäre Variable erstellt. Dies liegt daran, dass sowohl der vorherige als auch der neue Wert der inkrementierten Variablen irgendwo gespeichert werden müssen, da sie möglicherweise an anderer Stelle im ausgewerteten Ausdruck benötigt werden.
Zumindest in C ++ kann es also einen Leistungsunterschied geben, der Sie bei der Auswahl der zu verwendenden Elemente unterstützt.
Dies ist hauptsächlich dann nur dann ein Problem, wenn die inkrementierte Variable ein benutzerdefinierter Typ mit einem überschriebenen ++ - Operator ist. Für primitive Typen (int usw.) gibt es keinen Leistungsunterschied. Es lohnt sich jedoch, sich an den Operator vor dem Inkrementieren als Richtlinie zu halten, es sei denn, der Operator nach dem Inkrementieren ist definitiv das, was erforderlich ist.
Weitere Diskussionen finden Sie hier:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htm
Wenn Sie in C ++ STL verwenden, verwenden Sie möglicherweise for-Schleifen mit Iteratoren. Diese haben hauptsächlich überschriebene ++ - Operatoren, daher ist es eine gute Idee, sich an das Vorinkrementieren zu halten. Compiler werden jedoch immer intelligenter, und neuere können möglicherweise Optimierungen durchführen, die bedeuten, dass es keinen Leistungsunterschied gibt - insbesondere, wenn der zu inkrementierende Typ in der Header-Datei inline definiert wird (wie dies bei STL-Implementierungen häufig der Fall ist), damit der Compiler sehen kann, wie Die Methode ist implementiert und kann dann wissen, welche Optimierungen sicher durchgeführt werden können. Trotzdem lohnt es sich wahrscheinlich immer noch, sich an das Vorinkrementieren zu halten, da Schleifen häufig ausgeführt werden und dies bedeutet, dass ein kleiner Leistungsverlust bald verstärkt werden könnte.
In anderen Sprachen wie C #, in denen der ++ - Operator nicht überladen werden kann, gibt es keinen Leistungsunterschied. In einer Schleife zum Vorrücken der Schleifenvariablen werden die Operatoren vor und nach dem Inkrementieren äquivalent.
Korrektur: Überladen von ++ in C # ist zulässig. Es scheint jedoch, dass Sie in C # im Vergleich zu C ++ die Vor- und Nachversionen nicht unabhängig voneinander überladen können. Wenn das Ergebnis des Aufrufs von ++ in C # keiner Variablen zugewiesen oder als Teil eines komplexen Ausdrucks verwendet wird, würde der Compiler die Vor- und Nachversionen von ++ auf Code reduzieren, der eine gleichwertige Leistung erbringt.
quelle
In C # gibt es keinen Unterschied, wenn es in einer for-Schleife verwendet wird .
gibt das gleiche aus wie
Wie andere bereits betont haben, habe ich bei der allgemeinen Verwendung von i ++ und ++ einen subtilen, aber signifikanten Unterschied:
i ++ liest den Wert von i und erhöht ihn dann.
++ i erhöht den Wert von i und liest ihn dann.
quelle
++i
undi++
führen dieselben Vorgänge in derselben Reihenfolge aus: temporäre Kopie von erstelleni
; Erhöhen Sie den temporären Wert, um einen neuen Wert zu erzeugen (um den temporären Wert nicht zu überschreiben). Speichern Sie den neuen Wert ini
; Wenn++i
das Ergebnis zurückgegeben wird, ist dies der neue Wert. Wenni++
das Ergebnis zurückgegeben wird, handelt es sich um die temporäre Kopie. Detailliertere Antwort hier: stackoverflow.com/a/3346729/3330348Die Frage ist:
Die Antwort lautet: Nein .
Warum muss jede zweite Antwort detaillierte Erklärungen zum Inkrementieren vor und nach dem Inkrementieren enthalten, wenn dies nicht einmal gefragt wird?
Diese for-Schleife:
Würde ohne Verwendung von Schleifen in diesen Code übersetzen:
Ist es jetzt wichtig, ob Sie hier
i++
oder++i
als Inkrement setzen? Nein, der Rückgabewert der Inkrementierungsoperation ist unbedeutend.i
wird NACH der Ausführung des Codes erhöht, der sich innerhalb des for-Schleifenkörpers befindet.quelle
Da Sie nach dem Unterschied in einer Schleife fragen, meinen Sie das wohl
In diesem Fall haben Sie in den meisten Sprachen keinen Unterschied: Die Schleife verhält sich unabhängig davon, ob Sie schreiben
i++
und++i
. In C ++ können Sie Ihre eigenen Versionen der ++ - Operatoren schreiben und separate Bedeutungen für diese definieren, wenni
es sich um einen benutzerdefinierten Typ handelt (z. B. Ihre eigene Klasse).Der Grund, warum es oben nicht wichtig ist, ist, dass Sie den Wert von nicht verwenden
i++
. Eine andere Sache ist, wenn Sie es tunNun gibt es einen Unterschied, denn wie andere betonen,
i++
bedeutet dies Inkrementieren, aber auf den vorherigen Wert auswerten , aber Inkrementieren++i
bedeuten , aber auswerteni
(daher würde es auf den neuen Wert auswerten). Im obigen Falla
wird der vorherige Wert von i zugewiesen, während i inkrementiert wird.quelle
Wie dieser Code zeigt (siehe die entschlüsselte MSIL in den Kommentaren), unterscheidet der C # 3-Compiler in einer for-Schleife nicht zwischen i ++ und ++ i. Wenn der Wert von i ++ oder ++ i verwendet würde, würde es definitiv einen Unterschied geben (dies wurde in Visutal Studio 2008 / Release Build kompiliert):
quelle
Eins (++ i) ist Vorinkrement, eins (i ++) ist Nachinkrement. Der Unterschied besteht darin, welcher Wert sofort vom Ausdruck zurückgegeben wird.
Edit: Woops, ignorierte die Loop-Seite der Dinge völlig. Es gibt keinen tatsächlichen Unterschied zwischen for-Schleifen, wenn es sich um den 'Step'-Teil handelt (for (...; ...;)), aber in anderen Fällen kann er ins Spiel kommen.
quelle
Es gibt keinen Unterschied, ob Sie den Wert nach dem Inkrementieren in der Schleife nicht verwenden.
Beide Schleifen geben 0123 aus.
Der Unterschied ergibt sich jedoch, wenn Sie den Wert nach dem Inkrementieren / Dekrementieren in Ihrer Schleife wie folgt verwenden:
Pre-Increment-Schleife:
Ausgabe: 0 0 1 1 2 2 3 3
Post-Increment-Schleife:
Ausgabe: 0 0 1 0 2 1 3 2
Ich hoffe, der Unterschied wird durch den Vergleich der Ausgabe deutlich. Hierbei ist zu beachten, dass das Inkrementieren / Dekrementieren immer am Ende der for-Schleife durchgeführt wird und daher die Ergebnisse erklärt werden können.
quelle
Hier ist ein Java-Beispiel und der Byte-Code, Post- und Pre-Increment zeigen keinen Unterschied im Bytecode:
Und nun zum Bytecode (javap -private -c PreOrPostIncrement):
quelle
Ja da ist. Die Differenz liegt im Rückgabewert. Der Rückgabewert von "++ i" ist der Wert nach dem Inkrementieren von i. Die Rückgabe von "i ++" ist der Wert vor dem Inkrementieren. Dies bedeutet, dass der Code wie folgt aussieht:
Daher wäre a 2 und b und c wären jeweils 1.
Ich könnte den Code folgendermaßen umschreiben:
quelle
In beiden Fällen gibt es keinen tatsächlichen Unterschied. '
i
' Wird um 1 erhöht.Es gibt jedoch einen Unterschied, wenn Sie es in einem Ausdruck verwenden, zum Beispiel:
quelle
++ i und i ++ bieten mehr als Schleifen und Leistungsunterschiede. ++ i gibt einen l-Wert zurück und i ++ gibt einen r-Wert zurück. Basierend darauf gibt es viele Dinge, die Sie mit (++ i) tun können, aber nicht mit (i ++).
quelle
Es verwirrt mich, warum so Leute den Inkrementausdruck in for-Schleife als i ++ schreiben können.
In einer for-Schleife, wenn die 3. Komponente eine einfache Inkrementanweisung ist, wie in
oder
Es gibt keinen Unterschied in den resultierenden Ausführungen.
quelle
Wie @Jon B sagt, gibt es keinen Unterschied in einer for-Schleife.
In einer
while
oder-do...while
Schleife können Sie jedoch einige Unterschiede feststellen, wenn Sie einen Vergleich mit dem++i
oder durchführeni++
quelle
In Javascript kann aus folgenden Gründen i ++ besser verwendet werden:
Während Arrays (ich denke alle) und einige andere Funktionen und Aufrufe 0 als Ausgangspunkt verwenden, müssten Sie i auf -1 setzen, damit die Schleife mit dem Array funktioniert, wenn Sie ++ i verwenden .
Bei Verwendung von i ++ verwendet der folgende Wert den erhöhten Wert. Man könnte sagen, i ++ ist die Art und Weise, wie Menschen zählen, weil man mit einer 0 beginnen kann .
quelle
ist gleich der WHILE- Version
quelle
Bei Schleifen kann es einen Unterschied geben. Dies ist die praktische Anwendung von Post / Pre-Inkrement.
Während der erste bis 11 zählt und 11-mal schleift, tut der zweite nicht.
Meistens wird dies eher in einer einfachen Weile verwendet (x--> 0); - - Schleife, um zum Beispiel alle Elemente eines Arrays zu iterieren (ausgenommen hier foreach-Konstrukte).
quelle
Beide erhöhen die Zahl.
++i
ist äquivalent zui = i + 1
.i++
und++i
sind sehr ähnlich, aber nicht genau gleich. Beide erhöhen die Zahl,++i
erhöhen jedoch die Zahl, bevor der aktuelle Ausdruck ausgewertet wirdi++
die Zahl erhöht wird, nachdem der Ausdruck ausgewertet wurde.Überprüfen Sie diesen Link .
quelle
Ja, es gibt einen Unterschied zwischen
++i
undi++
in einerfor
Schleife, wenn auch in ungewöhnlichen Anwendungsfällen. wenn eine Schleifenvariable mit Inkrement / Dekrement-Operator im for-Block oder innerhalb des Schleifentestausdrucks oder mit einer der Schleifenvariablen verwendet wird . Nein, es ist nicht einfach eine Syntaxsache.Wie
i
in einem Code bedeutet das Auswerten des Ausdrucksi
und der Operator bedeutet nicht eine Auswertung, sondern nur eine Operation;++i
bedeutet Inkrementwerti
von 1 und später auswerteni
,i++
bedeutet auswerteni
und später den Werti
um 1 erhöhen .Was also aus jeweils zwei Ausdrücken erhalten wird, unterscheidet sich, weil das, was ausgewertet wird, in jedem unterschiedlich ist. Alles gleich für
--i
undi--
Beispielsweise;
In ungewöhnlichen Anwendungsfällen ist das nächste Beispiel zwar nützlich oder nicht wichtig, es zeigt jedoch einen Unterschied
quelle
Für
i
benutzerdefinierte Typen könnten ( sollten aber nicht ) diese Operatoren im Kontext eines Schleifenindex signifikant unterschiedliche Sematiken haben, und dies könnte (sollte aber nicht) das Verhalten der beschriebenen Schleife beeinflussen.Außerdem ist
c++
es im Allgemeinen am sichersten, das Pre-Inkrement-Formular (++i
) zu verwenden, da es einfacher zu optimieren ist. (Scott Langham hat mich zu diesem Leckerbissen geschlagen . Verfluche dich, Scott)quelle
Ich weiß es nicht für die anderen Sprachen, aber in Java ++ ist i ein Präfixinkrement, was bedeutet: Erhöhe i um 1 und verwende dann den neuen Wert von i in dem Ausdruck, in dem ich mich befinde , und i ++ ist ein Postfixinkrement , das Folgendes bedeutet : Verwenden Sie den aktuellen Wert von i im Ausdruck und erhöhen Sie ihn dann um 1. Beispiel:
} und die Ausgabe ist:
quelle
i ++; ++ i; beide sind ähnlich, da sie nicht in einem Ausdruck verwendet werden.
quelle