¿Qué es "cortocircuito" en C como lenguajes?

14

He oído hablar del término "cortocircuito" que se usa en C, C ++, C #, Java y muchos otros. ¿Qué significa esto y en qué escenario se usaría?

fasil
fuente
66
Hay un artículo de Wikipedia sobre el concepto: en.wikipedia.org/wiki/Short-circuit_evaluation Es una optimización en la evaluación del &&operador.
wirrbel
1
@wirrbel Creo que también se aplica ||... al menos debería.
Radu Murzea
1
@RaduMurzea De hecho. Contraste ||y &&para &y |ver la sutil diferencia. Haga que un programa simple evalúe 1 || printf("yay");vs 0 || printf("yay");y 1 | printf("yay");vs 0 | printf("yay");para ver las diferencias
wirrbel

Respuestas:

35

El cortocircuito en C es cuando un operador lógico no evalúa todos sus argumentos.

Tomemos por ejemplo y &&, es bastante obvio que 0 && WhoCaresva a ser falso sin importar lo que WhoCaressea. Debido a esto, C simplemente omite la evaluación WhoCares. Lo mismo ocurre 1 || WhoCares, siempre será cierto. Debido a esto, podemos escribir código como

CanFireMissiles && FireMissiles()

De esta forma, evitamos realizar operaciones potencialmente imposibles. Si no podemos disparar los misiles, ciertamente no queremos intentarlo. Esto se usa comúnmente con punteros, especialmente punteros de archivo.

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

Esto se desarrolla de muchas otras formas útiles para evitar la computación innecesaria

 isFileReady() || getFileReady()

Esto evita hacer un trabajo extra si no es necesario.

Daniel Gratzer
fuente
1
En cualquier momento, si he respondido a su pregunta, puede marcar la casilla de verificación al lado para marcar su pregunta como respondida
Daniel Gratzer
77
No me encanta CanFireMissiles && FireMissiles(), ya que me hace sospechar que estás abusando del cortocircuito para provocar efectos secundarios. Siento que estás ocultando acciones de manera condicional. Tal código está mejor escrito como if(CanFireMissiles){FireMissiles();}o if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}.
Brian
2
Yo diría que el único uso es ocultar los efectos secundarios. Por lo general, no se trata del tipo "Explotar una ciudad", pero las cosas como desreferenciar un puntero o usar recursos del sistema también se hacen de esta manera en C con bastante frecuencia. Vea la página de Wikipedia, toda la sección en uso es "Ocultar efectos secundarios"
Daniel Gratzer
2
@jozefg también puede usarlo para evitar realizar operaciones costosas como IsInCache(value) || IsInDatabase(value), por ejemplo , donde IsInDatabase puede tomar tiempo (especialmente si usar un dispositivo móvil y la latencia de la red es un problema).
mgw854
4

"Cortocircuito" generalmente se refiere a " Evaluación de cortocircuito ", que es un concepto general, no solo específico de C.

Evaluación de operadores booleanos de izquierda a derecha, por lo que cualquier término que haga innecesarios los otros términos es útil. Por lo tanto, puede verificar una condición que excluya otras condiciones más adelante, lo que permite una evaluación parcial de las operaciones lógicas en lugar de evaluar todo.

Ejemplo:

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 ejemplo más complejo:

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.
     */
}
Ingeniero mundial
fuente
8
El cortocircuito tiene menos que ver con ahorrar tiempo, pero más con no ser evaluado. Una función que no se evalúa tampoco tendrá el efecto secundario si se evalúa.
Pieter B
Ya sabes, == 0no solo es innecesario, sino que puede confundir a algunas personas.
Deduplicador