Unterschied zwischen Pre-Inkrement und Post-Inkrement in einer Schleife?


303

Gibt es einen Unterschied in ++iund i++in einer forSchleife? Ist es einfach eine Syntaxsache?



18
Ich bin erstaunt, wie viele Antworten den Punkt der Frage völlig verfehlt haben.
Graeme Perrow

3
Vielleicht sollten wir uns wundern, dass niemand die Frage bearbeitet hat, um klarer zu sein :)
Jon B

2
Diese Frage könnte für C, Java, C ++, PHP, C #, Javascript, JScript, Ziel C gelten: en.wikipedia.org/wiki/Category:C_programming_language_family
Chris S

1
Gute Antwort hier gepostet: stackoverflow.com/a/4706225/214296
Jim Fell

Antworten:


233

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 #:

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:

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

4
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.

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.


102
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

i ++ liest den Wert von i und erhöht ihn dann.

++ i erhöht den Wert von i und liest ihn dann.


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.


2
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.


3
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):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PreOrPostIncrement
{
    class Program
    {
        static int SomethingToIncrement;

        static void Main(string[] args)
        {
            PreIncrement(1000);
            PostIncrement(1000);
            Console.WriteLine("SomethingToIncrement={0}", SomethingToIncrement);
        }

        static void PreIncrement(int count)
        {
            /*
            .method private hidebysig static void  PreIncrement(int32 count) cil managed
            {
              // Code size       25 (0x19)
              .maxstack  2
              .locals init ([0] int32 i)
              IL_0000:  ldc.i4.0
              IL_0001:  stloc.0
              IL_0002:  br.s       IL_0014
              IL_0004:  ldsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
              IL_0009:  ldc.i4.1
              IL_000a:  add
              IL_000b:  stsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
              IL_0010:  ldloc.0
              IL_0011:  ldc.i4.1
              IL_0012:  add
              IL_0013:  stloc.0
              IL_0014:  ldloc.0
              IL_0015:  ldarg.0
              IL_0016:  blt.s      IL_0004
              IL_0018:  ret
            } // end of method Program::PreIncrement             
             */
            for (int i = 0; i < count; ++i)
            {
                ++SomethingToIncrement;
            }
        }

        static void PostIncrement(int count)
        {
            /*
                .method private hidebysig static void  PostIncrement(int32 count) cil managed
                {
                  // Code size       25 (0x19)
                  .maxstack  2
                  .locals init ([0] int32 i)
                  IL_0000:  ldc.i4.0
                  IL_0001:  stloc.0
                  IL_0002:  br.s       IL_0014
                  IL_0004:  ldsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
                  IL_0009:  ldc.i4.1
                  IL_000a:  add
                  IL_000b:  stsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
                  IL_0010:  ldloc.0
                  IL_0011:  ldc.i4.1
                  IL_0012:  add
                  IL_0013:  stloc.0
                  IL_0014:  ldloc.0
                  IL_0015:  ldarg.0
                  IL_0016:  blt.s      IL_0004
                  IL_0018:  ret
                } // end of method Program::PostIncrement
             */
            for (int i = 0; i < count; i++)
            {
                SomethingToIncrement++;
            }
        }
    }
}

14

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.


7

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.


7

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):

public class PreOrPostIncrement extends java.lang.Object{
static int somethingToIncrement;

static {};
Code:
0:  iconst_0
1:  putstatic   #10; //Field somethingToIncrement:I
4:  return

public PreOrPostIncrement();
Code:
0:  aload_0
1:  invokespecial   #15; //Method java/lang/Object."<init>":()V
4:  return

public static void main(java.lang.String[]);
Code:
0:  sipush  1000
3:  istore_1
4:  sipush  1000
7:  invokestatic    #21; //Method postIncrement:(I)V
10: sipush  1000
13: invokestatic    #25; //Method preIncrement:(I)V
16: return

private static void postIncrement(int);
Code:
0:  iconst_0
1:  istore_1
2:  goto    16
5:  getstatic   #10; //Field somethingToIncrement:I
8:  iconst_1
9:  iadd
10: putstatic   #10; //Field somethingToIncrement:I
13: iinc    1, 1
16: iload_1
17: iload_0
18: if_icmplt   5
21: return

private static void preIncrement(int);
Code:
0:  iconst_0
1:  istore_1
2:  goto    16
5:  getstatic   #10; //Field somethingToIncrement:I
8:  iconst_1
9:  iadd
10: putstatic   #10; //Field somethingToIncrement:I
13: iinc    1, 1
16: iload_1
17: iload_0
18: if_icmplt   5
21: return

}

5

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. 

4

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

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;
}

3

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

for (i=0; i<x; i++)  

oder

for (i=0; i<x; ++i)   

Es gibt keinen Unterschied in den resultierenden Ausführungen.


Ist es eine Antwort oder eine Frage?
Palec

2
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

zwei Gegenstimmen? Was ist los mit dem, was ich geschrieben habe? Und es hängt mit der Frage zusammen (so vage wie es ist).
Crashmstr

2

In Javascript kann aus folgenden Gründen i ++ besser verwendet werden:

var i=1;
alert(i++); // before, 1. current, 1. after, 2.
alert(i); // before, 2. current, 2. after, 2.
alert(++i); // before, 2. current, 3 after, 3.

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 .


2

Um zu verstehen, was eine FOR- Schleife tut

Geben Sie hier die Bildbeschreibung ein

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 for
while (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 :

  1. Das erste Argument von FOR (int i) wird außerhalb vor der Schleife ausgeführt.

  2. 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.


1

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).


1

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 = 

Überprüfen Sie diesen Link .


0

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

for(i=0, j=i; i<10; j=++i){
    console.log(j, i)
}

for(i=0, j=i; i<10; j=i++){
    console.log(j, i)
}

Was fügt dies den vorhandenen Antworten hinzu?
GManNickG

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);

} und die Ausgabe ist:

  • 4
  • 5
  • 6

-3

i ++; ++ i; beide sind ähnlich, da sie nicht in einem Ausdruck verwendet werden.

class A {

     public static void main (String []args) {

     int j = 0 ;
     int k = 0 ;
     ++j;
     k++;
    System.out.println(k+" "+j);

}}

prints out :  1 1
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.