Qu'est-ce que le «court-circuit» dans des langages de type C?

14

J'ai entendu parler du terme «court-circuit» utilisé en C, C ++, C #, Java et bien d'autres. Qu'est-ce que cela signifie et dans quel scénario serait-il utilisé?

fasil
la source
6
Il y a un article Wikipedia sur le concept: en.wikipedia.org/wiki/Short-circuit_evaluation C'est une optimisation dans l'évaluation de l' &&opérateur.
wirrbel
1
@wirrbel Je crois que cela s'applique ||également ... du moins, il devrait l'être.
Radu Murzea
1
@RaduMurzea En effet. Contraste ||et &&pour &et |voir la différence subtile. Avoir un programme simple évaluer 1 || printf("yay");vs 0 || printf("yay");et 1 | printf("yay");vs 0 | printf("yay");pour voir les différences
wirrbel

Réponses:

35

Le court-circuitage en C est lorsqu'un opérateur logique n'évalue pas tous ses arguments.

Prenez par exemple et &&, il est assez évident que cela 0 && WhoCaresva être faux, quoi qu'il en WhoCaressoit. Pour cette raison, C saute simplement l'évaluation WhoCares. Il en va de même 1 || WhoCares, ce sera toujours vrai. Pour cette raison, nous pouvons écrire du code comme

CanFireMissiles && FireMissiles()

De cette façon, nous évitons de faire une opération potentiellement impossible. Si nous ne pouvons pas tirer les missiles, nous ne voulons certainement pas essayer. Ceci est couramment utilisé avec les pointeurs, en particulier les pointeurs de fichiers.

 bool isN(int* ptr, int n){
     return ptr && *ptr == n;
 }

Cela se joue de nombreuses autres façons utiles pour éviter les calculs inutiles

 isFileReady() || getFileReady()

Cela évite de faire un travail supplémentaire si nous n'en avons pas besoin.

Daniel Gratzer
la source
1
À tout moment, si j'ai répondu à votre question, vous pouvez cocher la case à côté pour marquer votre question comme répondue
Daniel Gratzer
7
Je n'aime pas CanFireMissiles && FireMissiles(), car cela me fait penser que vous abusez des courts-circuits pour déclencher des effets secondaires. J'ai l'impression que vous cachez des actions au conditionnel. Un tel code est mieux écrit comme if(CanFireMissiles){FireMissiles();}ou if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}.
Brian
2
Je dirais que la seule utilisation est de masquer les effets secondaires. Habituellement, ce n'est pas le type "Faire sauter une ville", mais des choses comme le déréférencement d'un pointeur ou l'utilisation des ressources système sont également effectuées de cette manière en C assez souvent. Voir la page wikipedia, toute la section sous utilisation est "Cacher les effets secondaires"
Daniel Gratzer
2
@jozefg vous pouvez également l'utiliser pour éviter de faire des opérations coûteuses comme IsInCache(value) || IsInDatabase(value), où IsInDatabase peut prendre du temps (surtout si l'utilisation d'un appareil mobile et la latence du réseau est un problème).
mgw854 du
4

«Court-circuitage» se réfère généralement à « Évaluation de court-circuit » qui est un concept général, pas seulement spécifique à C.

Évaluation des opérateurs booléens de gauche à droite, donc tous les termes qui rendront les autres termes inutiles sont utiles. Vous pouvez donc vérifier une condition qui exclut d'autres conditions plus tard, permettant ainsi une évaluation partielle des opérations logiques plutôt que d'évaluer le tout.

Exemple:

while((x && y) == 1) {
    //This bit will not execute if x is 0 or y is 0 but y won't even be 
    //evaluated due to short circuit evaluation if x is 0.
}

Un exemple plus complexe:

if((a || b || c || d || e || f || g || h || i || j || k) == 1) {
    /* If any of these are equal to 1 the whole expression is equal to 1,
     * thus doesn't it make sense to short circuit evaluate this?
     * Saves a bunch of time.
     */
}
Ingénieur du monde
la source
8
Le court-circuit consiste moins à gagner du temps mais davantage à ne pas être évalué. Une fonction non évaluée n'aura pas non plus l'effet secondaire si elle était évaluée.
Pieter B
Vous savez, ce == 0n'est pas seulement inutile, cela pourrait en fait dérouter certaines personnes.
Déduplicateur