Pregunta

En el código PHP

if(a() && b())

cuando el primer operando se evalúa como false , b () no se evaluará.

Del mismo modo, en

if (a() || b())

cuando el primer operando se evalúa como verdadero , b () no se evaluará ..

¿Es esto cierto para todos los lenguajes, como Java, C #, etc.?

Este es el código de prueba que usamos.

<?php
function a(){
echo 'a';
return false;
}

function b(){
echo 'b';
return true;
}


if(a() && b()){
echo 'c';
}
?>
¿Fue útil?

Solución

Esto se llama evaluación de cortocircuito .

Generalmente es cierto para lenguajes derivados de C (C, C ++, Java, C #) pero no es cierto para todos los lenguajes.

Por ejemplo, VB6 no hace esto, ni se hizo en versiones anteriores de VB.NET. VB8 (en Visual Studio 2005) introdujo el AndAlso y OrElse operadores para este propósito.

Además, según los comentarios, parece que csh realiza una evaluación de cortocircuito de derecha a izquierda, para hacer las cosas aún más confusas.

También debe señalarse que la evaluación de cortocircuito (o falta de ella) tiene sus peligros a tener en cuenta. Por ejemplo, si el segundo operando es una función que tiene efectos secundarios, entonces el código puede no funcionar exactamente como el programador pretendía.

Otros consejos

No es cierto para VB6.

En VB.net debe usar " AndAlso " en lugar de " Y " si desea omitir la evaluación de la segunda expresión.

  

¿Es esto cierto para TODOS los idiomas, como JAVA, C #, etc.?

En C # esto solo es cierto para los operadores de cortocircuito ' || ' y ' & amp; & amp; '; si solo usa ' | ' o ' & amp; ', evaluará ambos lados cada vez.

Se llama evaluación de cortocircuito y la mayoría de los idiomas hacen esto. En algunos idiomas existen operadores que no hacen esto.

La versión original de Pascal no lo hizo, lo que causó mucho dolor. Pascales modernos, como Delphi, funcionan de la misma manera que C et al.

Ada tiene formas especiales de cortocircuitos condicionales:

and then
or else

usado así:

if p.next /= null and then p.next.name = 'foo'
if x = 0 or else 1/x = y

De alguna manera es agradable porque puedes deducir que el programador sabía que la expresión necesitaba un cortocircuito y que el condicional no funciona por accidente.

Es cierto para los idiomas que son "niños" de C: PHP, Java, C ++, C #, ... o en la misma `` inspiración '', como Perl.

Pero no es cierto para VB (al menos antes de .NET, que introdujo nuevas palabras clave para eso).
(Y eso es realmente inquietante la primera vez que trabajas con VB ^^)

Microsoft VBScript (a menudo utilizado en junto con ASP 'Clásico') no tenía evaluación de cortocircuito para operadores booleanos, sino que utiliza evaluación bit a bit. ¡Cuál es una de las muchas razones por las que posiblemente sea el peor idioma de todos!

  

" Lo que sucede es que VBScript es   no es lógico. VBScript es bit a bit. Todos   funcionan los llamados operadores lógicos   en números, no en valores booleanos!   No, And, Or, XOr, Eqv y Imp all   convertir sus argumentos a cuatro bytes   enteros, hacen la operación lógica en   cada par de bits en los enteros, y   devolver el resultado Si True es -1 y   Falso es 0, entonces todo funciona,   porque -1 tiene todos sus bits activados   y 0 tiene todos sus bits desactivados. Pero   si entran otros números, todos   las apuestas están canceladas " ;.

Tomado de este blog. de Eric Lippert.

En Delphi es una opción de compilador.

Esto también es cierto para Java, pero los operadores |, & amp; etc. evaluará ambos lados.

En Erlang, los operadores y y o no realizan evaluaciones de cortocircuito; debe usar los operadores orelse y andalso si desea un comportamiento de cortocircuito.

En FORTRAN o Fortran estándar, los operandos de una expresión booleana se pueden evaluar en cualquier orden. Se permite la evaluación incompleta, pero la implementación está definida.

Esto permite la optimización de expresiones booleanas que no se permitirían si se aplicara un orden estricto de izquierda a derecha. Las expresiones que requieren un orden estricto deben descomponerse en condicionales separados, o se pueden hacer suposiciones dependientes de la implementación.

Dado que la descomposición se usa para imponer el orden, se deduce que las declaraciones IF separadas no siempre se pueden optimizar en una sola expresión. Sin embargo, la evaluación de cortocircuito es explícita con descomposición, y esto nunca es peor que los lenguajes que imponen un estricto orden de izquierda a derecha para permitir una evaluación diferida.

Los idiomas que se derivan de FORTRAN (Fortran, BASIC, VBn), y los idiomas que fueron diseñados para lograr una eficiencia similar a FORTRAN (Pascal, Ada) inicialmente siguieron el ejemplo FORTRAN de permitir la evaluación fuera de orden.

La mayoría de los idiomas (todo lo que he visto) usan la evaluación de cortocircuito en operadores CONDICIONALES como & amp; & amp; y ||. Dejarán de evaluar tan pronto como una de las condiciones haya satisfecho el requisito. (El primer falso en & amp; & amp ;. El primer verdadero en ||)

Todos los operadores BINARIOS como & amp; y |, se procesan. (Original)

Todos los operadores BITWISE como & amp; y |, se procesan. (Editar: 10/05/17)

Esto se llama evaluación de cortocircuito y es común para todos los lenguajes en los que he trabajado (C, C ++, C #, Java, Smalltalk, Javascript, Lisp) a excepción de VB, VB.NET y Fortran.

En realidad es una característica bastante útil. Sin un cortocircuito no podría hacer esto:

if (a != null && a.isBlank())

Sin cortocircuito, tendría que haber anidado si las instrucciones porque la segunda parte arrojaría un error si un era nulo.

Coldfusion nativamente hará una evaluación de cortocircuito Estoy seguro de que todos los desarrolladores de CF han escrito:

<cfif isdefined("somevariable") and somevariable eq something>
//do logic
</cfif>

MATLAB es un idioma que distingue entre " estándar " operadores lógicos y operadores de cortocircuito :

  • & amp; (Operador AND) y | (El operador OR) puede operar en matrices de forma inteligente.
  • & amp; & amp; y || son versiones de cortocircuito para las cuales el segundo operando se evalúa solo cuando el resultado no está completamente determinado por el primer operando. Estos solo pueden funcionar en escalares , no en matrices.

Otras respuestas han dado buenos ejemplos de idiomas con y sin evaluación de cortocircuito, por lo que no los repetiré.

Solo un punto interesante para agregar: Lisps como Clojure tienen evaluación booleana de cortocircuito, pero además puede definir de manera bastante trivial cualquier operador que desee con la evaluación de cortocircuito mediante el uso de macros.

Ejemplo de un cortocircuito '' nand '' operación en Clojure:

(defmacro nand 
  ([x] 
    `(not ~x))
  ([x & xs] 
    `(let [nand# (not ~x)]
       (if nand# 
         true               ; short circuit if we can prove the nand is true
         (nand ~@xs)))))    ; continue with the other expressions otherwise

(nand true true)
=> false

(nand false (println "Expression with a side effect!"))
=> true
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top