Je voudrais incrémenter deux variables dans une condition for
-loop au lieu d’une.
Donc quelque chose comme:
for (int i = 0; i != 5; ++i and ++j) do_something(i, j);
Quelle est la syntaxe pour cela?
Un idiome commun consiste à utiliser l’ opérateur de virgule qui évalue les deux opérandes et renvoie le second opérande. Ainsi:
for(int i = 0; i != 5; ++i,++j) do_something(i,j);
Maintenant, après avoir écrit cela, un commentateur a suggéré qu’il s’agissait en fait d’un sucre syntaxique spécial dans le for et non d’un opérateur de virgule. J’ai vérifié cela dans GCC comme suit:
int i=0; int a=5; int x=0; for(i; i<5; x=i++,a++){ printf("i=%da=%dx=%d\n",i,a,x); }
Je m'attendais à ce que x prenne la valeur originale de a, il aurait donc dû afficher 5,6,7 .. pour x. Ce que j'ai eu c'était ça
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
Cependant, si je mettais l'expression entre crochets pour forcer l'parsingur à voir un opérateur de virgule, je
int main(){ int i=0; int a=5; int x=0; for(i=0; i<5; x=(i++,a++)){ printf("i=%da=%dx=%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
Au départ, je pensais que cela montrait qu’il ne se comportait pas du tout comme une virgule, mais il s’agit simplement d’un problème de priorité - l’opérateur de virgule a la priorité la plus basse possible , donc l’expression x = i ++, a ++ est efficace analysé comme (x = i ++), a ++
Merci pour tous les commentaires, c'était une expérience d'apprentissage intéressante, et j'utilise C depuis de nombreuses années!
Essaye ça
for(int i = 0; i != 5; ++i, ++j) do_something(i,j);
Essayez de ne pas le faire!
De http://www.research.att.com/~bs/JSF-AV-rules.pdf :
Règle AV 199
L’expression d’incrémentation dans une boucle for n’effectuera aucune autre action que de changer un paramètre de boucle unique à la valeur suivante pour la boucle.Justification: lisibilité.
for (int i = 0; i != 5; ++i, ++j) do_something(i, j);
Je suis venu ici pour me rappeler comment coder un deuxième index dans la clause d’incrémentation d’une boucle FOR, ce que je savais peut être fait principalement en l’observant dans un échantillon que j’ai incorporé dans un autre projet, écrit en C ++.
Aujourd’hui, je travaille en C #, mais je suis sûr qu’il obéirait aux mêmes règles à cet égard, car la déclaration FOR est l’une des plus anciennes structures de contrôle de toute la programmation. Heureusement, j’ai récemment passé plusieurs jours à documenter avec précision le comportement d’une boucle FOR dans l’un de mes anciens programmes C, et j’ai rapidement compris que ces études contenaient des leçons applicables au problème C # actuel, en particulier au comportement de la deuxième variable d’index. .
Pour les imprudents, voici un résumé de mes observations. Tout ce que j’ai vu se produire aujourd’hui, en observant attentivement les variables dans la fenêtre Locals, a confirmé que je m’attendais à ce qu’une instruction C # FOR se comporte exactement comme une instruction FOR C ou C ++.
Si l’une de vos variables d’index rest dans la scope à la fin de la boucle, leur valeur sera supérieure au seuil qui arrête la boucle, dans le cas de la variable d’index vraie. De même, si, par exemple, la deuxième variable est initialisée à zéro avant l’entrée de la boucle, sa valeur à la fin sera le nombre d’itérations, en supposant qu’il s’agit d’un incrément (++), et non d’un décrément, et que rien dans le corps de la boucle change de valeur.
Je suis d’accord avec squelart. L’incrémentation de deux variables est sujette à des bogues, surtout si vous ne testez qu’un seul d’entre eux.
C’est la manière lisible de faire ceci:
for(int i = 0; i < 5; ++i) { ++j; do_something(i, j); }
For
boucles For
sont destinées aux cas où votre boucle s'exécute sur une variable croissante / décroissante. Pour toute autre variable, changez-la dans la boucle.
Si vous avez besoin de j
pour être lié à i
, pourquoi ne pas laisser la variable originale telle quelle et append i
?
for(int i = 0; i < 5; ++i) { do_something(i,a+i); }
Si votre logique est plus complexe (par exemple, vous devez contrôler plus d'une variable), j'utiliserais une boucle while.
int main(){ int i=0; int a=0; for(i;i<5;i++,a++){ printf("%d %d\n",a,i); } }
Utilisez les mathématiques. Si les deux opérations dépendent mathématiquement de l’itération de la boucle, pourquoi ne pas faire le calcul?
int i, j;//That have some meaningful values in them? for( int counter = 0; counter < count_max; ++counter ) do_something (counter+i, counter+j);
Ou, plus spécifiquement en référence à l'exemple de l'OP:
for(int i = 0; i != 5; ++i) do_something(i, j+i);
Surtout si vous passez à une fonction par valeur, alors vous devriez obtenir quelque chose qui fait exactement ce que vous voulez.