La virgule n'est pas exclusive des boucles for ; c'est l'opérateur virgule.
x = (a, b);
fera d'abord a, puis b, puis fixera x à la valeur de b.
La syntaxe de for est :
for (init; condition; increment)
...
Ce qui est un peu (en ignorant continue
et break
pour l'instant) équivalent :
init;
while (condition) {
...
increment;
}
Donc votre exemple de boucle for est (encore une fois en ignorant continue
et break
) équivalent à
p=0;
while (p+=(a&1)*b,a!=1) {
...
a>>=1,b<<=1;
}
Qui agit comme s'il était (encore une fois ignorant continue
et break
) :
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
Deux détails supplémentaires de la boucle for qui n'étaient pas dans la conversion simplifiée en boucle while ci-dessus :
- Si la condition est omise, elle est toujours
true
(ce qui entraîne une boucle infinie, à moins qu'un break
, goto
ou quelque chose d'autre interrompt la boucle).
- A
continue
agit comme s'il s'agissait d'un goto vers un label juste avant l'incrément, contrairement à un continue
dans la boucle while, ce qui permettrait de sauter l'incrément.
De plus, un détail important concernant l'opérateur virgule : c'est un point de séquence, comme &&
et ||
(c'est pourquoi je peux le diviser en déclarations séparées et garder son sens intact).
Changements dans C99
La norme C99 introduit quelques nuances non mentionnées plus haut dans cette explication (ce qui est très bien pour C89/C90).
Tout d'abord, toutes les boucles sont des blocs à part entière. Effectivement,
for (...) { ... }
est lui-même enveloppé dans une paire d'accolades
{
for (...) { ... }
}
La norme dit :
ISO/IEC 9899:1999 §6.8.5 Déclarations d'itération
¶5 Une déclaration d'itération est un bloc dont la portée est un sous-ensemble strict de la portée de son bloc qui l'entoure. Le corps de la boucle est également un bloc dont la portée est un sous-ensemble strict de la portée de l'instruction d'itération. de l'instruction d'itération.
Ceci est également décrit dans la justification en termes d'accolades supplémentaires.
Deuxièmement, le init
en C99 peut être une déclaration (unique), comme dans
for (int i = 0; i < sizeof(something); i++) { ... }
Maintenant, le "bloc entourant la boucle" prend tout son sens ; il explique pourquoi la variable i
ne sont pas accessibles en dehors de la boucle. Vous pouvez déclarer plus d'une variable, mais elles doivent toutes être du même type :
for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }
La norme dit :
ISO/IEC 9899:1999 §6.8.5.3 L'instruction for
La déclaration
for ( clause-1 ; expression-2 ; expression-3 ) statement
se comporte comme suit : L'expression expression-2 est l'expression de contrôle qui est évaluée avant chaque exécution du corps de la boucle. L'expression expression-3 est évaluée comme une expression vide après chaque exécution du corps de la boucle. Si la clause-1 est une déclaration déclaration, la portée de toute variable qu'elle déclare est le reste de la déclaration et la totalité de la boucle, y compris les deux autres. la boucle entière, y compris les deux autres expressions ; elle est atteinte dans l'ordre d'exécution avant la première évaluation de l'expression de contrôle. Si la clause-1 est une expression, elle est évaluée comme une expression vide avant la première évaluation de l'expression de contrôle. 133)
La clause-1 et l'expression-3 peuvent être omises. Une expression-2 omise est remplacée par une constante non nulle.
133) Ainsi, la clause-1 spécifie l'initialisation de la boucle, en déclarant éventuellement une ou plusieurs variables à utiliser dans la boucle ; l'expression de contrôle, expression-2, spécifie une évaluation effectuée avant chaque itération, de sorte que l'exécution de la boucle se poursuit jusqu'à ce que l'expression soit égale à 0 ; et l'expression-3 spécifie une opération (telle que l'incrémentation) qui est effectuée après chaque itération.
0 votes
@Jesus -- Tu as corrigé "kinda" en "kind of", "coma" en "virgule", mis une majuscule à "I" et "Does" mais laissé "ppl" pour "people" ?
0 votes
J'ai corrigé quelques erreurs. Le message est beaucoup mieux présenté maintenant. Question intéressante.