Was bedeutet Kurzschließen in C-ähnlichen Sprachen?

14

Ich habe von dem Begriff "Kurzschließen" gehört, der in C, C ++, C #, Java und vielen anderen verwendet wird. Was bedeutet das und in welchem ​​Szenario würde es verwendet?

fasil
quelle
6
Über das Konzept gibt es einen Wikipedia-Artikel: en.wikipedia.org/wiki/Short-circuit_evaluation Es handelt sich um eine Optimierung bei der Bewertung des &&Betreibers.
Wirrbel
1
@wirrbel Ich glaube das gilt ||auch ... zumindest sollte es so sein.
Radu Murzea
1
@ RaduMurzea In der Tat. Kontrast ||und &&zu &und |um den subtilen Unterschied zu sehen. Lassen Sie ein einfaches Programm 1 || printf("yay");vs 0 || printf("yay");und 1 | printf("yay");vs auswerten 0 | printf("yay");, um die Unterschiede zu sehen
wirrbel

Antworten:

35

Ein Kurzschluss in C liegt vor, wenn ein logischer Operator nicht alle seine Argumente bewertet.

Nehmen wir zum Beispiel und &&, es ist ziemlich offensichtlich, dass 0 && WhoCareses falsch sein wird, egal was WhoCaresist. Aus diesem Grund überspringt C nur die Auswertung WhoCares. Gleiches gilt 1 || WhoCares, es wird immer wahr sein. Aus diesem Grund können wir Code wie schreiben

CanFireMissiles && FireMissiles()

Auf diese Weise vermeiden wir potenziell unmögliche Operationen. Wenn wir die Raketen nicht abfeuern können, wollen wir es auf keinen Fall versuchen. Dies wird häufig bei Zeigern verwendet, insbesondere bei Dateizeigern.

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

Dies kann auf viele andere nützliche Arten geschehen, um unnötiges Rechnen zu vermeiden

 isFileReady() || getFileReady()

Dies vermeidet zusätzliche Arbeit, wenn dies nicht erforderlich ist.

Daniel Gratzer
quelle
1
Wenn ich Ihre Frage beantwortet habe, können Sie jederzeit das Kontrollkästchen neben der Frage aktivieren, um sie als beantwortet zu markieren
Daniel Gratzer
7
Ich liebe nicht CanFireMissiles && FireMissiles(), da ich den Verdacht habe, dass Sie einen Kurzschluss missbrauchen, um Nebenwirkungen auszulösen. Ich habe das Gefühl, Sie verstecken Aktionen unter bestimmten Bedingungen. Solcher Code ist besser als if(CanFireMissiles){FireMissiles();}oder geschrieben if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}.
Brian
2
Ich würde argumentieren, dass die einzige Verwendung darin besteht, Nebenwirkungen zu verbergen. Normalerweise wird in C nicht die Sortierung "Eine Stadt in die Luft sprengen" verwendet, aber Dinge wie die Dereferenzierung eines Zeigers oder die Verwendung von Systemressourcen werden in dieser Weise häufig ausgeführt. Siehe die Wikipedia-Seite, der gesamte Abschnitt unter Verwendung ist "Verstecken von Nebenwirkungen"
Daniel Gratzer
2
@jozefg Sie können es auch verwenden, um teure Vorgänge zu vermeiden IsInCache(value) || IsInDatabase(value), bei denen IsInDatabase möglicherweise einige Zeit in Anspruch nimmt (insbesondere, wenn die Verwendung eines Mobilgeräts und die Netzwerklatenz ein Problem darstellen).
mgw854
4

"Kurzschluss" bezieht sich typischerweise auf " Kurzschlussbewertung ", die ein allgemeines Konzept ist, nicht nur C-spezifisch.

Die Auswertung der Booleschen Operatoren erfolgt von links nach rechts. Daher sind alle Begriffe nützlich, die die anderen Begriffe überflüssig machen. Sie können also später nach einer Bedingung suchen, die andere Bedingungen ausschließt, und so eine teilweise Bewertung der logischen Operationen zulassen, anstatt das Ganze zu bewerten.

Beispiel:

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.
}

Ein komplexeres Beispiel:

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.
     */
}
Weltingenieur
quelle
8
Bei Kurzschlüssen geht es weniger um Zeitersparnis als vielmehr darum, nicht bewertet zu werden. Eine Funktion, die nicht bewertet wird, hat auch nicht die Nebenwirkung, wenn sie bewertet würde.
Pieter B
Sie wissen, das == 0ist nicht nur unnötig, es könnte tatsächlich einige Leute verwirren.
Deduplizierer
3

Die Kurzschlussbewertung kann dazu führen, dass einige Teile eines Zustands nicht bewertet werden.

Beispielsweise:

if (true || f()) { ... }

wird nicht ausgeführt f.

Frank
quelle