122 votes

Doit-on utiliser < ou <= dans une boucle for ?

Si vous deviez itérer dans une boucle 7 fois, utiliseriez-vous :

for (int i = 0; i < 7; i++)

ou :

for (int i = 0; i <= 6; i++)

Il y a deux considérations :

  • performance
  • lisibilité

Pour des raisons de performances, je suppose qu'il s'agit de Java ou de C#. Est-il important d'utiliser "inférieur à" ou "inférieur ou égal à" ? Si vous avez des idées pour un autre langage, veuillez indiquer lequel.

Pour des raisons de lisibilité, je suppose que les tableaux sont basés sur 0.

UPD : Ma mention des tableaux basés sur 0 a peut-être semé la confusion. Je ne parle pas d'itération à travers les éléments d'un tableau. Juste d'une boucle générale.

Il y a un bon point ci-dessous sur l'utilisation d'une constante à qui expliquerait ce qu'est ce nombre magique. Donc si j'avais " int NUMBER_OF_THINGS = 7 " alors " i <= NUMBER_OF_THINGS - 1 "aurait l'air bizarre, n'est-ce pas ?

287voto

Jon Skeet Points 692016

Le premier est plus idiomatique . En particulier, il indique (dans un sens basé sur 0) le nombre d'itérations. Lorsque l'on utilise quelque chose de basé sur 1 (par exemple JDBC, IIRC), je pourrais être tenté d'utiliser <=. Donc :

for (int i=0; i < count; i++) // For 0-based APIs

for (int i=1; i <= count; i++) // For 1-based APIs

Je m'attendrais à ce que la différence de performance soit insignifiante dans le code réel.

72voto

Steve Losh Points 11958

Ces deux boucles itèrent 7 fois. Je dirais que celle avec un 7 est plus lisible/claire, à moins que vous ayez une très bonne raison pour l'autre.

55voto

Martin Brown Points 8593

Je me souviens de l'époque où nous faisions de l'assemblage 8086 à l'université, c'était plus performant :

for (int i = 6; i > -1; i--)

comme il y avait un JNS opération qui signifie Sauter si pas de signe. En utilisant cette méthode, il n'y avait pas de recherche en mémoire après chaque cycle pour obtenir la valeur de comparaison et pas de comparaison non plus. De nos jours, la plupart des compilateurs optimisent l'utilisation des registres, de sorte que l'aspect mémoire n'est plus important, mais vous obtenez toujours une comparaison non requise.

Au fait, mettre 7 ou 6 dans votre boucle, c'est introduire un " nombre magique ". Pour une meilleure lisibilité, vous devez utiliser une constante avec un nom révélant l'intention. Comme ceci :

const int NUMBER_OF_CARS = 7;
for (int i = 0; i < NUMBER_OF_CARS; i++)

EDIT : Les gens ne comprennent pas le concept d'assemblage, donc un exemple plus complet est évidemment nécessaire :

Si nous faisons for (i = 0 ; i <= 10 ; i++) vous devez faire ceci :

    mov esi, 0
loopStartLabel:
                ; Do some stuff
    inc esi
                ; Note cmp command on next line
    cmp esi, 10
    jle exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

Si nous faisons for (int i = 10 ; i > -1 ; i--) alors vous pouvez vous en sortir :

    mov esi, 10
loopStartLabel:
                ; Do some stuff
    dec esi
                ; Note no cmp command on next line
    jns exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

Je viens de vérifier et le compilateur C++ de Microsoft ne fait pas cette optimisation, mais il le fait si vous le faites :

for (int i = 10; i >= 0; i--) 

La morale est donc que si vous utilisez Microsoft C++†, et que l'ascendant ou le descendant ne fait aucune différence, pour obtenir une boucle rapide, vous devriez utiliser :

for (int i = 10; i >= 0; i--)

plutôt que l'un ou l'autre :

for (int i = 10; i > -1; i--)
for (int i = 0; i <= 10; i++)

Mais franchement, obtenir la lisibilité de "for (int i = 0 ; i <= 10 ; i++)" est normalement bien plus important que de manquer une commande du processeur.

† D'autres compilateurs peuvent faire des choses différentes.

27voto

Omar Kooheji Points 14073

J'utilise toujours < array.length car c'est plus facile à lire que <= array.length-1.

ayant également < 7 et étant donné que vous savez qu'il commence avec un indice 0, il devrait être intuitif que le nombre est le nombre d'itérations.

18voto

erlando Points 5802

Du point de vue de l'optimisation, cela n'a pas d'importance.

Vu sous l'angle du style de code, je préfère < la raison :

for ( int i = 0; i < array.size(); i++ )

est tellement plus lisible que

for ( int i = 0; i <= array.size() -1; i++ )

également < vous donne directement le nombre d'itérations.

Un autre vote en faveur de < est que vous pourriez éviter beaucoup d'erreurs accidentelles de type off-by-one.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X