Je voudrais incrémenter deux variables dans une for
condition -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?
Je voudrais incrémenter deux variables dans une for
condition -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?
Réponses:
Un idiome courant consiste à utiliser l' opérateur virgule qui évalue les deux opérandes et renvoie le deuxième opérande. Donc:
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 virgule du tout. 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 prenne la valeur d'origine de a, donc il aurait dû afficher 5,6,7 .. pour x. Ce que j'ai eu c'est ç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 place l'expression entre crochets pour forcer l'analyseur à vraiment voir un opérateur virgule, j'obtiens 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 qu'il ne se comportait pas du tout comme un opérateur virgule, mais il s'avère qu'il s'agit simplement d'un problème de priorité - l'opérateur virgule a la priorité la plus basse possible , donc l'expression x = i ++, a ++ est effectivement analysé comme (x = i ++), a ++
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);
for( ; ; ((++i), (++j)) )
for(int i = 0; i != 5; (++i)) {
les parenthèses supplémentaires font croire au compilateur que ce n'est plus une opération "d'incrémentation".
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 action autre que de changer un paramètre de boucle unique à la valeur suivante pour la boucle.Justification: lisibilité.
Je suis venu ici pour me rappeler comment coder un deuxième index dans la clause d'incrémentation d'une boucle FOR, ce qui, je le savais, pouvait être fait principalement en l'observant dans un échantillon que j'ai incorporé dans un autre projet, celui écrit en C ++.
Aujourd'hui, je travaille en C #, mais je suis convaincu qu'il obéirait aux mêmes règles à cet égard, puisque 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 précisément le comportement d'une boucle FOR dans l'un de mes anciens programmes C, et j'ai rapidement réalisé que ces études contenaient des leçons qui s'appliquaient au problème C # d'aujourd'hui, 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é mon attente qu'une instruction C # FOR se comporte exactement comme une instruction C ou C ++ FOR.
Si l'une de vos variables d'index reste dans la portée à la fin de la boucle, sa valeur sera supérieure d'une unité 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 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 (++), 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 à des bogues, surtout si vous ne testez qu'une seule d'entre elles.
Voici la manière lisible de faire ceci:
int j = 0;
for(int i = 0; i < 5; ++i) {
do_something(i, j);
++j;
}
For
les boucles sont destinées aux cas où votre boucle s'exécute sur une variable croissante / décroissante. Pour toute autre variable, modifiez-la dans la boucle.
Si vous devez j
être lié à i
, pourquoi ne pas laisser la variable d'origine 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 en fait surveiller plus d'une variable), j'utiliserais une while
boucle.
int main(){
int i=0;
int a=0;
for(i;i<5;i++,a++){
printf("%d %d\n",a,i);
}
}
i
et a
local à la boucle?
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 précisément en se référant à l'exemple du PO:
for(int i = 0; i != 5; ++i)
do_something(i, j+i);
Surtout si vous passez à une fonction par valeur, vous devriez obtenir quelque chose qui fait exactement ce que vous voulez.