Mon instructeur m'a dit une fois que je ne devrais pas définir une variable à l'intérieur d'une boucle , mais honnêtement, je ne comprends toujours pas pourquoi.
Quels en sont les inconvénients?
Quelqu'un pourrait-il m'expliquer cela?
Mon instructeur m'a dit une fois que je ne devrais pas définir une variable à l'intérieur d'une boucle , mais honnêtement, je ne comprends toujours pas pourquoi.
Quels en sont les inconvénients?
Quelqu'un pourrait-il m'expliquer cela?
const
raisons de style personnel, je préfère déclarer mes variables sauf s'il y a une raison de ne pas le faire (une habitude de la programmation fonctionnelle). Soit je ne les modifierai pas, et l'optimiseur devrait détecter quand ils ne sont pas nécessaires, soit je le ferai et j'ai évité un bug sérieux. Lorsque ces valeurs intermédiaires constantes sont spécifiques à une itération de la boucle, cela signifie les déclarer à l'intérieur de la boucle. Une autre fois, cependant, lorsque vous devez déclarer des variables en dehors de la boucle, c'est lorsque vous vous y référerez en dehors de la boucle; par exemple, les résultats que vous stockez.Réponses:
Ce n'est pas un problème de définir une variable dans une boucle. En fait, c'est une bonne pratique, car les identifiants doivent être limités à la plus petite portée possible.
Ce qui est mauvais, c'est d' affecter une variable dans une boucle si vous pouvez tout aussi bien l'affecter une fois avant que la boucle ne s'exécute. Selon la complexité du côté droit de l'affectation, cela pourrait devenir assez coûteux et même dominer le temps d'exécution de la boucle. Si vous écrivez une boucle qui utilise la même valeur calculée dans toutes les itérations, vous devez certainement la calculer au - dessus de la boucle, ce qui est plus important que de minimiser sa portée.
Pour clarifier: tant que
compute()
renvoie toujours la même valeur, cetteest plus intelligent que cela:
la source
1/1/1900
, la variable doit être déclarée et la valeur doit être affectée avant la boucle.Les types complexes ont des constructeurs et des destructeurs non triviaux.
Ceux-ci seront appelés au début et à la fin du corps de la boucle (car il est initialisé et hors de portée). Si l'initialisation est coûteuse car elle doit allouer de la mémoire, cela doit être évité.
Cependant pour les types triviaux ce n'est pas un problème. L'allocation et la désallocation elles-mêmes ajoutent et soustraient simplement une valeur du pointeur de pile. (qui sera optimisé)
la source
Eh bien, ses conseils sont un peu trop simples (c'est un euphémisme).
Le suivre va de la bonne idée à qui s'en soucie et de la mauvaise idée à l' impossible .
Vous devez le suivre chaque fois que la réutilisation est moins chère que la destruction de l'ancien et la création d'un nouveau.
Vous devez l'éviter par style lorsque cela n'a pas d'importance pour les performances.
Vous devriez vraiment l' éviter lorsqu'il a de moins bonnes performances ou une mauvaise sémantique.
Vous ne pouvez pas le suivre lorsque le type utilisé ne permet ni l'échange, ni l'assignation de déplacement ni l'assignation de copie.
la source
for (std::string s; std::cin >> s;) ...
et être toujours "extérieur"