Je voudrais incrémenter deux variables dans une condition de boucle for
- 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 langage courant consiste à utiliser opérateur de virgule , qui évalue les deux opérandes et renvoie le deuxième opérande. Ainsi:
for(int i = 0; i != 5; ++i,++j)
do_something(i,j);
Après avoir écrit cela, un commentateur a suggéré qu'il s'agissait en fait d'un sucre syntaxique spécial dans l'instruction 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=%d a=%d x=%d\n",i,a,x);
}
Je m'attendais à ce que x récupère la valeur initiale de a, il aurait donc dû afficher 5,6,7 .. pour x. Ce que j'ai eu était ceci
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 met l'expression entre crochets pour forcer l'analyseur à vraiment voir un opérateur de virgule, je reçois ceci
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
Au départ, je pensais que cela montrait que cela ne se comportait pas du tout comme un opérateur de virgule, mais il s’avère que c’est tout simplement un problème de priorité - l’opérateur de virgule a le le plus bas précédent possible , ainsi l'expression x = i ++, un ++ est effectivement analysé comme (x = i ++), un ++
Merci pour tous les commentaires, ce fut 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’exécutera aucune action autre que celle de changer un paramètre de boucle unique à la valeur suivante de 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 pouvoir être fait principalement en l'observant dans un exemple que j'ai incorporé à un autre projet, celui écrit en C++.
Aujourd'hui, je travaille en C #, mais je suis convaincu qu'il obéira aux mêmes règles à cet égard, car l'instruction FOR est l'une des plus anciennes structures de contrôle de toute la programmation. Heureusement, j'avais 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 vite compris que ces études contenaient des leçons qui s'appliquent 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 aujourd'hui, en observant attentivement les variables de la fenêtre Locals, a confirmé mon attente selon laquelle une instruction C # FOR se comporte exactement comme une instruction C ou C++ FOR.
Si l'une de vos variables d'index reste dans l'étendue à la fin de la boucle, sa valeur sera supérieure au seuil qui arrête la boucle, dans le cas de la vraie variable d'index. De même, si, par exemple, la deuxième variable est initialisée à zéro avant la boucle, sa valeur à la fin sera le compte d’itérations, en supposant qu’il s’agit d’un incrément (++), pas 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 aux bogues, surtout si vous ne testez que l'une d'entre elles.
C'est le moyen lisible de faire ceci:
for(int i = 0; i < 5; ++i) {
++j;
do_something(i, j);
}
Les 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 que j
soit lié à i
, pourquoi ne pas laisser la variable originale telle quelle et ajouter i
?
for(int i = 0; i < 5; ++i) {
do_something(i,a+i);
}
Si votre logique est plus complexe (par exemple, vous devez surveiller plusieurs variables), utilisez 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 vous référant à l'exemple du PO:
for(int i = 0; i != 5; ++i)
do_something(i, j+i);
Surtout si vous passez dans une fonction par valeur, alors vous devriez obtenir quelque chose qui fait exactement ce que vous voulez.