Frage

C, was der Unterschied zwischen der Verwendung von ++i und i++, und der in dem Inkrementierung Block eines for Schleife verwendet werden sollte?

War es hilfreich?

Lösung

  • ++i den Wert von i erhöhen und dann den erhöhten Wert zurück.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++ den Wert von i erhöhen, aber den ursprünglichen Wert zurück, bevor sie erhöht gehalten i.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    

Für eine for Schleife, entweder funktioniert. ++i scheint häufiger, vielleicht, weil das ist, was in K & R verwendet wird.

In jedem Fall folgt der Leitlinie „bevorzugt ++i über i++“ und Sie werden nicht schief gehen.

Es gibt ein paar Kommentare, die Effizienz der ++i und i++ in Bezug auf. In jeder Nicht-Schüler-Projekt Compiler, wird es kein Unterschied in der Leistung sein. Sie können dies überprüfen, indem Sie auf den generierten Code suchen, die identisch sein wird.

Die Effizienz Frage ist interessant ... hier ist mein Versuch einer Antwort: Gibt es einen Unterschied in der Leistung zwischen i ++ und ++ i in C?

Wie Einen Freund Noten, es ist etwas anderes für ein C ++ Objekt, da operator++() eine Funktion ist, und der Compiler kann nicht wissen, die Schaffung eines temporären Objekt zu optimieren entfernt, um den Zwischenwert zu halten.

Andere Tipps

i ++ ist bekannt als Post Increment , während ++ i wird als Pre-Schritte.

i++

i++ ist Post Schritt, weil es i Wert um 1 erhöht, nachdem die Operation beendet ist.

Hier können Sie das folgende Beispiel sehen:

int i = 1, j;
j = i++;

Hier Wert von j = 1 aber i = 2. Hier Wert von i zugewiesen wird zunächst auf j dann i erhöht wird.

++i

++i ist vor Schritt, weil es i Wert um 1 vor der Operation erhöht. Es bedeutet j = i; nach i++ ausgeführt wird.

Hier können Sie das folgende Beispiel sehen:

int i = 1, j;
j = ++i;

Hier Wert von j = 2 aber i = 2. Hier Wert von i wird zugewiesen nach dem j incremention von i i. Ähnlich ++i vor j=i; ausgeführt wird.

Für Ihre Frage die im Inkrementierung Block einer for-Schleife verwendet werden sollte? die Antwort ist, können Sie ein beliebiges verwenden .. spielt keine Rolle. Es wird Ihre for-Schleife gleiche nicht ausführen. Mal.

for(i=0; i<5; i++)
   printf("%d ",i);

Und

for(i=0; i<5; ++i)
   printf("%d ",i);

Beide werden die Schleifen gleiche Leistung erzeugen. dh 0 1 2 3 4.

Es ist nur wichtig ist, wo Sie es verwenden.

for(i = 0; i<5;)
    printf("%d ",++i);

In diesem Fall Ausgabe 1 2 3 4 5 wird.

Bitte sorgen Sie sich nicht um die „Effizienz“ (Geschwindigkeit, wirklich), von denen man schneller ist. Wir haben Compiler diesen Tagen, dass diese Dinge kümmern. Verwenden Sie je nachdem, was ein Gefühl, auf deren Grundlage klarer zeigt Ihre Absicht zu bedienen ist.

++i erhöht den Wert, gibt es dann.

i++ gibt den Wert, und dann erhöht er.

Es ist ein feiner Unterschied.

Für eine for-Schleife verwenden ++i, da es etwas schneller ist. i++ wird eine zusätzliche Kopie erstellen, die nur weggeworfen werden.

i++: In diesem Szenario zunächst der Wert zugewiesen wird und dann Schritt passiert.

++i: In diesem Szenario zunächst der Zuwachs erfolgt und dann wird der Wert zugewiesen

Im Folgenden finden Sie die Bildvisualisierung und auch hier ist ein schönes praktisches Video , die zeigt, das gleiche.

eingeben Bild Beschreibung hier

Der Grund ++i können geringfügig schneller als i++ ist, dass i++ eine lokale Kopie des Wertes von i erfordern kann, bevor er erhöht wird, während ++i nie. In einigen Fällen werden optimieren einige Compiler es weg, wenn möglich ... aber es ist nicht immer möglich, und nicht alle Compiler tun.

Ich versuche, nicht zu viele Optimierungen auf Compiler angewiesen, also würde ich Ryan Fox Rat folgen: wenn ich beide verwenden kann, verwende ich ++i.

Das effektive Ergebnis der Verwendung von entweder identisch ist. Mit anderen Worten, tut die Schleife genau die gleiche Sache in beiden Fällen.

Im Hinblick auf die Effizienz, könnte es eine Strafe mit der Wahl beteiligt sein i über ++ i ++. In Bezug auf die Sprache spec sollte die Post-Inkrement-Operator erstellen, auf dem eine zusätzliche Kopie des Wertes der Betreiber fungiert. Dies könnte eine Quelle für zusätzliche Operationen sein.

Sie sollten jedoch zwei Hauptprobleme bei der vorhergehenden Logik betrachten.

  1. Moderne Compiler sind groß. Alle guten Compiler sind intelligent genug, um zu erkennen, dass es eine ganze Zahl Schritt in einer for-Schleife ist zu sehen, und es werden beide Methoden zum gleichen effizienten Code optimieren. Bei der Verwendung von Post-Inkrement über Prä-Inkrement tatsächlich Ihr Programm führt zu einer langsameren Laufzeit hat, dann verwenden Sie eine schrecklich Compiler.

  2. In Bezug auf die Laufzeit-Komplexität, die beiden Methoden (auch wenn eine Kopie tatsächlich ausgeführt wird) sind gleichwertig. Die Anzahl von Anweisungen, wobei innerhalb der Schleife durchgeführt, sollte signifikant die Anzahl der Operationen in der Inkrementoperation dominieren. Daher wird in jeder Schleife von signifikanter Größe, die Strafe der Inkrement Methode wird massiv durch die Ausführung des Schleifenkörpers überlagert werden. Mit anderen Worten: Sie sind viel besser dran sich Gedanken über den Code in der Schleife statt der Erhöhung zu optimieren.

Meiner Meinung nach ist das ganze Thema kocht einfach auf einen Stil bevorzugt nach unten. Wenn Sie Prä-Inkrement denken besser lesbar ist, verwenden Sie es dann. Ich persönlich ziehe die Post-incrment, aber das ist wahrscheinlich, weil es das war, was ich gelehrt wurde, bevor ich etwas über die Optimierung kannte.

Dies ist ein wesentliches Beispiel vorzeitiger Optimierung und Fragen wie diese haben das Potenzial, uns von ernsten Problemen im Design abzulenken. Es ist immer noch eine gute Frage, aber zu fragen, weil es keine Einheitlichkeit in der Nutzung oder Konsens in ist „best practice“.

Sie sowohl die Zahl erhöhen. ++i entspricht i = i + 1.

i++ und ++i sind sehr ähnlich, aber nicht genau das gleiche. Sowohl die Zahl erhöht, aber ++i erhöht die Anzahl vor dem aktuellen Ausdruck wird ausgewertet, während i++ die Zahl erhöht, nachdem der Ausdruck ausgewertet wird.

Beispiel:

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

++i (Präfix Betrieb): Stufung und dann weist den Wert
(Eg): int i = 5, int b = ++i        In diesem Fall wird zunächst 6 bis b zugeordnet und inkrementiert dann bis 7 und so weiter.

i++ (Postfix-Betrieb): Ordnet und erhöht dann den Wert
(Eg): int i = 5, int b = i++        In diesem Fall wird zunächst 5 bis b zugeordnet und inkrementiert dann bis 6 und so weiter.

Incase der for-Schleife: i++ meist verwendet wird, weil wir normalerweise den Startwert von i verwenden, bevor for-Schleife in erhöht wird. Aber je nach Programmlogik kann es variieren.

++i: vorge Zuwachs der andere Nachinkrement

.

i++: Ruft das Element und dann erhöht er
. ++i. Schritten i und gibt dann das Element

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

Ich nehme an, Sie den Unterschied in der Semantik jetzt verstehen (obwohl ehrlich frage ich mich, warum Leute fragen Fragen auf Stack-Überlauf ‚Was bedeutet Operator X bedeutet‘ eher als das Lesen, Sie wissen, ein Buch oder eine Web-Tutorial oder so etwas.

Aber wie auch immer, so weit wie die man zu verwenden, ignorieren Fragen der Leistung, welche unwahrscheinlich wichtig, auch in C ++. Dies ist das Prinzip Sie verwenden sollten bei der Entscheidung, was zu verwenden:

Sagen Sie, was Sie in Code bedeuten.

Wenn Sie den Wert-vor-Zuwachs in Ihrer Erklärung nicht benötigen, nicht, dass die Form des Betreibers verwenden. Es ist ein kleines Problem, aber wenn Sie mit einem Styleguide arbeiten, die eine verbietet Version für den anderen zusammen (auch bekannt als ein Knochen-köpfigen Style Guide), sollten Sie verwenden die Form, die meisten genau zum Ausdruck bringt, was Sie versuchen zu tun.

QED, verwenden Sie die Prä-Inkrement-Version:

for (int i = 0; i != X; ++i) ...

Der Unterschied kann durch diese einfachen C ++ Code unten zu verstehen:

int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
  

Der Hauptunterschied ist

     
      
  • i ++ Post ( Nach Increment ) und
  •   
  • ++ i Pre ( Vor Increment )

         
        
    • post, wenn die Schleife Schritten wie i =1 1,2,3,4,n
    •   
    • pre wenn die Schleife Schritten wie i =1 2,3,4,5,n
    •   
  •   

i ++ und ++ i

Dieser kleine Code kann dazu beitragen, den Unterschied von einem anderen Winkel als die bereits gebucht Antworten sichtbar zu machen:

int i = 10, j = 10;

printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);

printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);

Das Ergebnis ist:

//Remember that the values are i = 10, and j = 10

i is 10 
i++ is 10     //Assigns (print out), then increments
i is 11 

j is 10 
++j is 11    //Increments, then assigns (print out)
j is 11 

Achten Sie auf die vor und nach Situationen.

für Schleife

Wie bei dem einer von ihnen sollte in einem Inkrementierung Block eines for-Schleife verwendet werden, denke ich, dass das Beste, was wir tun können, eine Entscheidung zu treffen, ist ein gutes Beispiel verwenden:

int i, j;

for (i = 0; i <= 3; i++)
    printf (" > iteration #%i", i);

printf ("\n");

for (j = 0; j <= 3; ++j)
    printf (" > iteration #%i", j);

Das Ergebnis ist:

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 

Ich weiß nicht, über Sie, aber ich sehe keinen Unterschied in der Anwendung, zumindest in einem for-Schleife.

Das folgende C Codefragment veranschaulicht den Unterschied zwischen den Pre- und Post-Inkrement- und Dekrement-Operatoren:

int  i;
int  j;

Increment Operatoren:

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2

Pre-crement bedeutet Schritt auf der gleichen Linie. Post-Zuwachs bedeutet Schritt nach der Linie führt.

int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.

int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes

Wenn es darum geht mit OR, AND-Operatoren, wird es noch interessanter.

int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}

int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}

In Array

System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12

jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13

mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13

for (int val: a) {
     System.out.print(" " +val); //55, 13, 15, 20, 25
}

In C ++ post / pre-Zuwachs von Zeigervariable

#include <iostream>
using namespace std;

int main() {

    int x=10;
    int* p = &x;

    std::cout<<"address = "<<p<<"\n"; //prints address of x
    std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
    std::cout<<"address = "<<&x<<"\n"; //prints address of x

    std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}

Kurz:

++i und i++ Werke gleich, wenn Sie schreiben, sie nicht in einer Funktion. Wenn Sie so etwas wie function(i++) verwenden oder function(++i) können Sie den Unterschied sehen.

function(++i) sagt erstes Inkrement i um 1, danach diese i mit neuem Wert in die Funktion setzen.

function(i++) sagt die erste Stelle setzen i in die Funktion nach dieser Erhöhung i um 1.

int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now

Der einzige Unterschied ist die Reihenfolge der Operationen zwischen der Zunahme der Variablen und der Wert der Bediener zurückkehrt.

Dieser Code und seine Ausgabe erklärt den Unterschied:

#include<stdio.h>

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

Die Ausgabe ist:

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

Also im Grunde gibt ++i den Wert, nachdem er erhöht wird, während ++i den Wert zurück, bevor er erhöht wird. Am Ende, in beiden Fällen sind die i sein Wert erhöht hat.

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

Oft gibt es keinen Unterschied

Unterschiede sind deutlich, wenn der zurückgegebene Wert einer anderen Variablen zugeordnet ist oder wenn das Inkrement in Verkettung mit anderen Operationen durchgeführt wird, in dem Operationen Vorrang angewendet wird (i++*2 unterscheidet sich von ++i*2, aber (i++)*2 und (++i)*2 gibt denselben Wert) in vielen Fällen sie sind austauschbar. Ein klassisches Beispiel ist die for-Schleife Syntax:

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

hat die gleiche Wirkung von

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

Regel erinnern

Um nicht machen Verwechslungen zwischen den beiden Betreibern ich diese Regel angenommen:

Partner die Position des Bedieners ++ in Bezug auf den variable i die Reihenfolge der ++ Operation in Bezug auf die Zuordnung

Diese in anderen Worten:

  • ++ vor i bedeutet Inkrementierung durchgeführt werden müssen vor Zuordnung;
  • ++ nach i bedeutet Inkrementierung durchgeführt werden müssen nach Zuordnung:

Sie interner Konvertierung an das denken können als mehr Anweisungen ;

// case 1 :

i++;

/* you can think as,
 * i;
 * i= i+1;
 */

// case 2

++i;

/* you can think as,
 * i = i+i;
 * i;
 */

a = i ++ bedeutet, enthält ein Strom i Wert a = ++ i bedeutet ein enthält inkrementiert i-Wert

Hier ist das Beispiel, um den Unterschied zu verstehen

int i=10;
printf("%d %d",i++,++i);

Ausgabe: 10 12/11 11 (abhängig von der Reihenfolge der Auswertung der Argumente an die printf-Funktion, die über Compilern und Architekturen variiert)

Erläuterung: i++-> i gedruckt ist, und inkrementiert dann. (Druckt 10, aber i wird werden 11) ++i-> i Wert Schritten und gibt den Wert. (Druckt 12, und der Wert von i auch 12)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top