alors que la boucle nécessite une condition explicite, pour la boucle ne le fait pas, pourquoi?
En C++, vous êtes autorisé à avoir une condition vide dans la boucle for, par exemple dans for (;;)
ou for (int x = 0;; ++x)
. Mais vous ne pouvez pas faire while ()
.
Lorsque la condition est omise dans la boucle for, la condition est supposée être true
(donc la boucle boucle pour toujours). Pourquoi n'est-ce pas le cas avec les boucles while
, c'est-à-dire, quel est l'argument derrière le fait de ne pas laisser while ()
être un alias de while (true)
?
6 réponses
Vraisemblablement, c'est un effet secondaire du fait que chaque clause donnée dans l'instruction for est facultative. Il y a des raisons pour lesquelles certaines boucles for n'auraient pas besoin d'une affectation; il y a des raisons pour lesquelles d'autres n'auraient pas besoin d'une condition; il y a des raisons pour lesquelles d'autres n'auraient pas besoin d'incrément. Exiger qu'il y en ait un nombre minimum serait inutilement compliqué.
Ce qui suit est tiré du livre Deep C Secrets :
Au début C n'avait pas d'opérateurs distincts pour & et & & ou | et//. (Compris?) Au lieu de cela, il a utilisé la notion (héritée de B et BCPL) de "contexte de valeur de vérité": où une valeur booléenne était attendue, après" if " et "while" et ainsi de suite, les opérateurs & et | ont été interprétés comme && et || sont maintenant; dans les expressions ordinaires, les interprétations binaires ont été utilisées. Cela a plutôt bien fonctionné, mais c'était difficile à expliquer. (Il y avait de la notion d '"opérateurs de haut niveau" dans un contexte de valeur-vérité.)
Donc là vous l'avez, while()
définirait le contexte pour une valeur de vérité et ne peut pas être vide ou implicite pour la même raison si () ne peut pas être vide, la mécanique du langage précoce s'attendait à ce qu'ils ne le soient pas.
En C++, vous êtes autorisé à avoir une condition vide dans la boucle for ... Quel est l'argument derrière ne pas laisser
while()
être un alias dewhile(true)
?
Tout d'abord, C++ (et C# et beaucoup d'autres langages) sont la façon dont ils sont pour la rétrocompatibilité avec C, alors parlons de C.
Faisons quelques déclarations et tirons une conclusion.
- Il y a une bonne raison pour laquelle la boucle
for
vous permet d'omettre la condition. - le même bien la raison s'applique à la boucle
while
. - la boucle
while
ne permet pas d'omettre la condition; elle est incohérente. - la cohérence des choix de conception entre les énoncés est un facteur important dans la conception de C.
- par conséquent, il doit y avoir une bonne raison non évidente pour l'incohérence; il doit y avoir une bonne raison pour laquelle la boucle
while
est incompatible avec la bouclefor
.
Et maintenant la question Est "Quelle est cette bonne raison non évidente?"
Mais le question n'a de sens que si la chaîne de logique décrite ci-dessus est correcte, ce qui n'est pas le cas. De ces déclarations, seulement # 3 est en fait vrai! La boucle for
en C est une mauvaise conception; elle est redondante, déroutante pour les novices et ses conventions lexicales sont incompatibles avec le reste de la langue. Il fournit presque zéro puissance de représentation supplémentaire à la langue sur une boucle simple while
.
Il N'y a pas de réponse à votre question; la bonne réponse est plutôt de rejeter la prémisse de la question entièrement. La Boucle for
ne semble raisonnable que parce que c'est une erreur de 40 ans et plus avec laquelle la plupart d'entre nous ont grandi, donc ses bizarreries sont une seconde nature maintenant; c'est la familiarité, pas un bon design. Si nous avions grandi sans la boucle for
, nous ne l'ajouterions pas.
Je pense que la principale différence est entre expressions et déclarations.
Bien sûr, en C, les deux ne sont pas rigoureusement distingués, mais je dirais que la boucle for Est:
for (statement; expression; statement) {
...
}
L'expression est une expression booléenne, alors que les instructions le sont...des déclarations qui ont des effets secondaires. Bien sûr, C n'est pas semi-fonctionnel; vous pouvez mettre des effets secondaires dans l'expression du milieu, mais ce n'est pas idiomatique.
Parfois, vous ne voulez pas d'expression, mais les instructions au début et à chaque itération de boucle sont utiles, donc l'expression du milieu est facultative:
// Infinite counter
int i;
for (i = 0;;i++) {
...
}
Cela signifie par définition que l'expression est considérée comme toujours vraie
D'autre part, while
et if
peut seulement prendre des expressions. Il n'y a plus rien de très utile (contrairement aux deux instructions utiles à gauche) si vous omettez cette expression: personne n'écrirait
// Idiot coding
if (true) {
...
}
Parce que le point d'une instruction if
est de vérifier si certains inconnus est vrai ou pas!
Même chose avec while
. Le but de while
est de faire quelque chose encore et encore tant qu'une condition sous la forme d'une expression est vraie. C'est un peu comme un "iterated if
". C'est pourquoi
while() {
...
}
N'est pas considéré comme logique et donc pas autorisé.
6.8.5.3 La déclaration d'
La déclaration
for ( clause-1 ; expression-2 ; expression-3 )
instruction 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. 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, la portée de identifiants qu'il déclare est le reste de la déclaration et le boucle entière, y compris les deux autres expressions; il est atteint dans l'ordre d'exécution avant la première évaluation du contrôle expression. Si la clause-1 est une expression, elle est évaluée comme vide expression avant la première évaluation du contrôle expression.158)
- la clause-1 et l'expression-3 peuvent être omises. un omis l'expression-2 est remplacée par une constante non nulle.
Ainsi, dans le cas de for
boucle, la condition sera remplacée par une constante non nulle et aucune implémentation de ce type pour la boucle while
.
La différence entre les instructions logiques utilisées dans les boucles while() Et for(;;) Est la suivante:
Dans le cas de la déclaration définit condition de sortie de la boucle
Dans le cas de tout() la déclaration définit condition de l'exécution de la boucle
En supposant que, vous voyez que pour entrer dans une boucle, vous avez besoin d'au moins une condition d'exécution, pas une condition de sortie.