Menu

break et continue en C : fonctionnement et cas d'usage

break quitte une boucle ou un switch ; continue passe au tour suivant. Comment chacun se comporte dans for, while et do-while, comment sortir de boucles imbriquées avec un drapeau ou goto, et les abus qui rendent les boucles illisibles.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Deux façons de modifier le flux d'une boucle

La condition d'une boucle décide quand elle se termine, mais parfois la vraie réponse surgit au milieu du corps. Vous cherchez dans un tableau et vous trouvez l'élément au troisième rang - pourquoi vérifier les 997 autres ? Ou vous traitez une liste et une entrée est vide - sautez-la et continuez.

Le C a un mot-clé pour chaque cas :

  • break - quitter la boucle maintenant. L'exécution reprend à la première instruction qui la suit.
  • continue - abandonner seulement ce passage. Passer au suivant.

La première boucle affiche 1 2 3 4 et s'arrête. La seconde affiche 1 2 3 4 6 7 8 9 10 - elle a sauté une valeur et a poursuivi.

break dans une boucle

L'usage canonique est une recherche qui s'arrête dès qu'elle réussit :

Parce que found est affecté avant le break, le code après la boucle peut distinguer « trouvé » de « plus d'éléments ». Cet appariement - une variable de résultat plus un break - est l'idiome standard de recherche en C. Le compteur de boucle lui-même n'est pas utilisable ensuite quand il est déclaré dans l'en-tête, puisqu'il sort de portée à l'accolade fermante.

break quitte toujours une boucle : le for, while, do-while ou switch englobant le plus proche.

continue dans une boucle

continue sert aux entrées qu'il faut sauter plutôt que d'arrêter le travail :

L'endroit où continue saute dépend de la boucle :

for        -> la partie mise a jour de l'en-tete (le compteur avance donc quand meme)
while      -> le test de condition (rien d'autre du corps ne s'execute)
do-while   -> le test de condition, en bas

Cette différence n'est pas académique. Dans une boucle for, continue ne peut jamais sauter l'incrémentation du compteur, parce que celle-ci est dans l'en-tête. Dans une boucle while, si :

/* BUG: continue saute i++, donc cela bloque au premier nombre pair */
int i = 0;
while (i < 10) {
    if (i % 2 == 0) {
        continue;
    }
    printf("%d ", i);
    i++;
}

Soit vous déplacez i++ au-dessus du continue, soit vous l'écrivez en boucle for, où l'en-tête rend l'erreur impossible.

Un break dans un switch n'est pas un break de la boucle

break termine la boucle ou le switch englobant le plus proche - le plus proche des deux. Placez un switch dans une boucle et chaque break qu'il contient appartient au switch :

La commande q affiche son message et la boucle continue de tourner sur cc. Si sortir était censé terminer la boucle, ce break ne l'a pas fait. Les solutions sont un drapeau, un goto, ou le déplacement de la boucle dans une fonction avec return - toutes montrées ci-dessous.

S'échapper de boucles imbriquées

Un simple break quitte un niveau. Dans deux boucles imbriquées, il ne termine que la boucle interne, et la boucle externe entame son passage suivant comme si de rien n'était.

Le C n'a ni break 2 ni break étiqueté. Trois options honnêtes :

Un drapeau. Portable, évident et un peu bruyant :

Le drapeau apparaît à deux endroits - la condition externe et l'affectation - ce qui en est le coût. Avec trois niveaux d'imbrication, cela devient franchement désagréable.

goto. Le saut tant décrié du C, et c'est le seul cas où les programmeurs C expérimentés l'utilisent sans s'excuser :

Un goto vers l'avant, vers une étiquette juste après les boucles, fait exactement ce qu'un break étiqueté ferait dans d'autres langages, en une ligne et sans drapeau à maintenir. La réputation de goto est méritée par les sauts en arrière et les sauts au milieu d'autres blocs, qui produisent réellement un flux de contrôle illisible. Un unique saut vers l'avant hors de boucles imbriquées, ce n'est pas cela. Le noyau Linux utilise le même motif pour ses chemins de nettoyage. Utilisez-le délibérément et avec parcimonie ; ne laissez pas le tabou vous pousser vers une alternative à trois drapeaux plus difficile à lire.

Une fonction et return. Généralement la meilleure réponse, car une recherche mérite un nom :

return déroule toutes les boucles de la fonction, ne demande ni drapeau ni étiquette, et le code de recherche a maintenant un nom et peut être testé isolément. Quand l'imbrication est assez profonde pour que s'en échapper pose problème, c'est souvent le signe que le bloc voulait être une fonction de toute façon.

Quand ils aident, et quand ils nuisent

break et continue justifient leur place quand ils permettent à une boucle de dire « ce cas est réglé » une fois, près du début, au lieu d'envelopper tout le corps dans un if. Comparez :

/* avec continue : le vrai travail n'est pas indente */
for (int i = 0; i < n; i++) {
    if (!isValid(a[i])) continue;
    if (isDuplicate(a[i])) continue;
    process(a[i]);
}

/* sans : chaque garde ajoute un niveau */
for (int i = 0; i < n; i++) {
    if (isValid(a[i])) {
        if (!isDuplicate(a[i])) {
            process(a[i]);
        }
    }
}

Ils nuisent quand ils sont nombreux. Une boucle avec cinq break éparpillés et trois continue a une condition de sortie qui n'est écrite nulle part - un lecteur doit simuler tout le corps pour savoir quand elle s'arrête. Deux règles qui tiennent bien : gardez les gardes continue groupées en haut du corps, et si une boucle a plus d'un ou deux break, demandez-vous si la condition de l'en-tête n'aurait pas dû faire ce travail.

Deux pièges plus petits. continue dans un do-while saute au test du bas, qui est de toute façon la prochaine étape - inoffensif, mais cela surprend. Et un break hors de toute boucle ou switch est une erreur de compilation, la seule erreur ici que le compilateur attrape pour vous.

Questions fréquentes

Quelle est la différence entre break et continue en C ?

break met fin à la boucle entièrement et l'exécution reprend après elle. continue abandonne seulement le passage en cours et enchaîne sur le suivant - vers la mise à jour dans une boucle for, ou directement vers le test de condition dans un while ou un do-while.

Comment sortir d'une boucle imbriquée en C ?

Un simple break ne quitte que la boucle la plus interne. Pour sortir des deux, posez un drapeau et testez-le dans la condition de la boucle externe, utilisez goto pour sauter vers une étiquette après les boucles, ou - généralement le plus propre - déplacez les boucles dans une fonction et faites return.

break quitte-t-il la boucle ou seulement le switch ?

Celui qui l'entoure le plus étroitement. Un break dans un switch lui-même dans une boucle termine seulement le switch ; la boucle continue. Pour quitter la boucle depuis un switch, il faut un drapeau, un goto ou un return.

Pourquoi continue provoque-t-il une boucle infinie dans mon while ?

Parce que continue saute vers la condition et ignore le reste du corps - y compris l'incrémentation du compteur si elle se trouve à la fin. Dans une boucle for, la mise à jour est dans l'en-tête et s'exécute donc toujours ; dans un while, déplacez la mise à jour avant le continue ou utilisez un for.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER