Frage

Ich mag zwei Variablen in einem for-Loop-Zustand erhöhen, statt einem.

So etwas wie:

for (int i = 0; i != 5; ++i and ++j) 
    do_something(i, j);

Was ist die Syntax für das?

War es hilfreich?

Lösung

Eine gemeinsame Idiom ist die Kommaoperator zu verwenden, das beide Operanden ausgewertet wird, und gibt das zweite Operand. Also:

for(int i = 0; i != 5; ++i,++j) 
    do_something(i,j);

Aber ist es wirklich ein Komma-Operator?

Nun schrieb haben, dass ein Kommentator schlug es war tatsächlich einige besondere syntaktische Zucker in der for-Anweisung, und schon gar nicht ein Komma-Operator. Ich überprüfte, dass in GCC wie folgt:

int i=0;
int a=5;
int x=0;

for(i; i<5; x=i++,a++){
    printf("i=%d a=%d x=%d\n",i,a,x);
}

Ich erwarte x den ursprünglichen Wert von a zu holen, so sollte es 5,6,7 .. für x angezeigt hat. Was ich erhielt, war dieses

i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3

Allerdings, wenn ich den Ausdruck in eckigen Klammern, um den Parser zu zwingen, wirklich ein Komma-Operator zu sehen, bekomme ich diese

int main(){
    int i=0;
    int a=5;
    int x=0;

    for(i=0; i<5; x=(i++,a++)){
        printf("i=%d a=%d x=%d\n",i,a,x);
    }
}

i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8

Am Anfang dachte ich, dass dies zeigte, dass es wurde nicht als Komma-Operator verhalten überhaupt, aber es stellt sich heraus, das ist einfach ein Vorrang Problem - der Komma-Operator die niedrigsten mögliche Priorität , so der Ausdruck x = i ++ ist ein ++ wirksam als (x = i ++) analysiert, ein ++

Vielen Dank für alle Kommentare, es war eine interessante Lernerfahrung, und ich habe seit vielen Jahren C wurde mit!

Andere Tipps

Versuchen Sie, diese

for(int i = 0; i != 5; ++i, ++j)
    do_something(i,j);

Versuchen Sie nicht, es zu tun!

Von http://www.research.att.com/~bs/JSF-AV-rules.pdf :

  

AV-Regel 199
  Das Inkrement Expression in einer for-Schleife wird keine Aktion durchführen als andere einen einzelnen zu ändern   Loop-Parameter auf den nächsten Wert für die Schleife.

     

Begründung: Ablesbarkeit.

for (int i = 0; i != 5; ++i, ++j) 
    do_something(i, j);

Ich ist hergekommen, um mich daran erinnern, wie ein zweiten Index in die Erhöhung Klausel eines FOR-Schleife codieren, die ich vor allem in einer Probe durchgeführt werden kannte, konnte aus der Beobachtung, dass ich in ein anderes Projekt eingebunden, das in C ++ geschrieben.

Heute arbeite ich in C #, aber ich war mir sicher, dass es die gleichen Regeln in dieser Hinsicht gehorchen würde, da die FOR-Anweisung ist eine der ältesten Kontrollstrukturen in allen Programmierung ist. Zum Glück hatte ich vor kurzem einige Tage genau dokumentieren das Verhalten einer FOR-Schleife in einer meiner älteren C-Programme ausgegeben, und ich erkannte schnell, dass diese Studien Unterricht statt, die den heutigen C # Problem angewendet, insbesondere auf das Verhalten des zweiten Indexvariable .

Für die Unvorsichtigen, folgt eine Zusammenfassung meiner Beobachtungen. Alles, was ich sah heute geschieht, durch vorsichtiges Variablen im Lokalfenster beobachten, bestätigt meine Erwartung, dass eine C # FOR-Anweisung genau verhält sich wie ein C oder C ++ FOR-Anweisung.

  1. Das erste Mal eine FOR-Schleife ausführt, die Erhöhung der Klausel (die dritte der drei) übersprungen. In Visual C und C ++, wird das Inkrement als drei Maschinenbefehle in der Mitte des Blockes erzeugt, die die Schleife implementiert, so dass der Anstich nur einmal den Initialisierungscode ausgeführt wird, springt dann über den Inkrement-Block den Beendigungstest auszuführen. Dies implementiert die Funktion, die ein FOR-Schleife führt Null oder mehrmals, je nach dem Zustand seines Index und Grenz Variablen.
  2. Wenn der Körper der Schleife ausführt, seine letzte Aussage ist ein Sprung auf den ersten der drei Schritt Anweisungen, die von der ersten Iteration übersprungen wurden. Nachdem diese ausführen, Steuerung fällt natürlich in den Limit-Test-Code, der die mittlere Klausel implementiert. Das Ergebnis dieser Prüfung bestimmt, ob der Körper der FOR-Schleife ausgeführt wird, oder ob die Steuerung zu der nächsten Anweisung auf den Sprung an der Unterseite ihres Anwendungsbereichs.
  3. Da die Steuerung von dem Boden des Blockes FOR-Schleife, um das Inkrement Block wird die Indexvariable inkrementiert, bevor der Test ausgeführt wird. Nicht nur, dass dieses Verhalten zu erklären, warum Sie Ihr Limit Klauseln den Weg codieren müssen Sie gelernt, aber es wirkt sich auf alle sekundären Zuwachs, die Sie über den Komma-Operator hinzufügen, weil es Teil der dritten Klausel wird. Daher ist es nicht auf der ersten Iteration geändert, aber es ist auf der letzten Iteration, die nie den Körper führt.

Wenn entweder Ihre Indexvariablen in Umfang bleibt, wenn die Schleife beendet ist, wird ihr Wert um eins höher ist als der Schwellenwert sein, den die Schleife stoppt im Fall des wahren Indexvariable. Ebenso, wenn zum Beispiel die zweite Variable auf Null initialisiert wird, bevor die Schleife eingegeben wird, dessen Wert am Ende wird der Iterationszähler sein, vorausgesetzt, dass es sich um ein Inkrement (++), nicht ein Dekrement, und dass nichts in der Körper der Schleife ändert seinen Wert.

Ich bin mit squelart. Inkrementieren zwei Variablen Fehler anfällig, vor allem wenn Sie nur für einen von ihnen testen.

Dies ist die lesbare Weise, dies zu tun:

for(int i = 0; i < 5; ++i) {
    ++j;
    do_something(i, j);
}

For Schleifen für die Fälle, in denen mit der Schleife auf der einen läuft steigend / fallend variabel. Für jede andere Variable, es in der Schleife ändern.

Wenn Sie j gebunden werden, um i warum nicht die ursprüngliche Variable lassen wie es ist und i hinzufügen?

for(int i = 0; i < 5; ++i) {
    do_something(i,a+i);
}

Wenn Sie Ihre Logik komplexer ist (zum Beispiel, müssen Sie tatsächlich mehr als eine Variable überwachen), habe ich eine while Schleife verwenden würde.

int main(){
    int i=0;
    int a=0;
    for(i;i<5;i++,a++){
        printf("%d %d\n",a,i);
    } 
}

Mit Mathe. Wenn die beiden mathematisch-Operationen auf der Schleife Iteration ab, warum die Mathematik nicht tun?

int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
    do_something (counter+i, counter+j);

Oder, genauer gesagt auf das Beispiel des OP verweisen:

for(int i = 0; i != 5; ++i)
    do_something(i, j+i);

Vor allem, wenn Sie in eine Funktion von Wert vorbei sind, dann sollten Sie etwas, das genau das tut, was Sie wollen.

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