Pergunta

No código PHP

if(a() && b())

quando as primeiras avalia operando para false, b() não serão avaliadas.

Da mesma forma, no

if (a() || b())

quando as primeiras avalia operando para true, b() não serão avaliadas ..

Isso é verdade para todas as línguas, como Java, C #, etc?

Este é o código de teste que usamos.

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

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


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

Solução

Isso é chamado curto-circuito avaliação .

É geralmente verdade para linguagens derivadas de C (C, C ++, Java, C #), mas não é verdade para todos os idiomas.

Por exemplo, VB6 não faz isso, nem foi feito em versões anteriores do VB.NET. VB8 (no Visual Studio 2005) introduziu o AndAlso e OrElse operadores para esta finalidade.

Além disso, a partir dos comentários, parece que a avaliação realiza csh curto-circuito da direita para a esquerda, para tornar as coisas ainda mais confusas.

Também deve ser salientado que a avaliação curto-circuito (ou falta de) tem os seus perigos para estar ciente. Por exemplo, se o segundo operando é uma função que tem quaisquer efeitos secundários, em seguida, o código pode não funcionar exatamente como o programador pretendia.

Outras dicas

Não é verdade para VB6.

Em VB.net você tem que usar "AndAlso" em vez de "E" se você quer que ele pule avaliar a segunda expressão.

Isso é verdade para todas as línguas, como Java, C #, etc?

Em C este # só é verdade para os operadores '||' e '&&'-circuito curto; se você usar apenas '|' ou '&' que irá avaliar ambos os lados de cada vez.

É chamado curto-circuito avaliação e a maioria das linguagens fazer isso. Em algumas línguas, existe operadores que não fazer isso.

A versão original do Pascal não fez, o que causou muita dor. Pascais modernas, tais como o trabalho de Delphi da mesma maneira como C et al.

Ada tem formas de condicionais especiais circuito-curto:

and then
or else

usado como este:

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

Em alguns aspectos, é uma espécie de bom porque você pode deduzir que o programador conhecia a expressão precisava estar em curto-circuito e que a condicional não está funcionando por acidente.

É verdade para as línguas que são "filhos" do C:. PHP, Java, C ++, C #, ... ou no mesmo "inspiração", como Perl

Mas isso não é verdade para VB (pelo menos antes NET, que introduziu novas palavras-chave para isso).
(E isso é realmente preocupante o primeiro você trabalha com VB ^^)

Microsoft VBScript (muitas vezes utilizados em conjunto com ASP 'Classic') não teve avaliação de curto-circuito para operadores booleanos, em vez disso, usa avaliação bit a bit. Que é uma das muitas razões por que é possivelmente o pior linguagem de sempre!

"O que está acontecendo é que VBScript é não é lógico. VBScript é bit a bit. Tudo o chamado operadores lógicos trabalho em números, não em valores booleanos! Não, E, OR, XOR, Eqv e Imp todos converter os seus argumentos para quatro bytes inteiros, fazer a operação lógica em cada par de bits nos números inteiros, e retornar o resultado. Se é verdadeiro -1 e Falso é 0, em seguida, tudo funciona, porque-1 tem todos os seus bits ligado e 0 tem todos seus bits desligado. Mas se outros números de chegar lá, todos as apostas estão fora".

este blog. por Eric Lippert.

Em Delphi é uma opção de compilador.

Isto é verdade para Java tão bem, mas os operadores |., & Etc irá avaliar ambos os lados

Em Erlang, os operadores and e or não fazer avaliação de curto-circuito; você tem que usar operadores orelse e andalso se você quer um comportamento de curto-circuito.

em Fortran padrão ou Fortran, os operandos de uma expressão booleana pode ser avaliada por qualquer ordem. avaliação incompleta é permitido, mas a implementação definida.

Isso permite a otimização de expressões booleanas que não seriam permitidas caso rigorosa ordenação Esquerda para a Direita foi cumprida. Expressões que exigem ordenação estrita deve ser decomposto em condicionais separadas, ou suposições dependente de implementação pode ser feita.

Uma vez que a decomposição é usado para fazer cumprir a encomenda, segue-se que separado IF nem sempre pode ser otimizado em uma única expressão. No entanto, a avaliação de curto-circuito é explícita com decomposição, e isso nunca é pior do que línguas que impor estrito da esquerda para a direita ordenação para permitir a avaliação preguiçosa.

línguas wich são derivados de Fortran (Fortran, BASIC, VBN), e idiomas que foram concebidas para alcançar Fortran semelhante eficiência (Pascal, Ada) inicialmente seguido do exemplo Fortran de permitir fora de ordem de avaliação.

A maioria das línguas (todas as que eu já vi) usar a avaliação curto-circuito na operadores condicionais, como && e ||. Eles vão parar de avaliar, logo que uma das condições satisfez a exigência. (A primeira falsas sobre &&. O primeiro verdadeiro em ||)

operadores Todos os binários como & e |, são processados. (Original)

operadores All bit a bit como & e |, são processados. (Edit: 5/10/17)

Isso é chamado de avaliação de curto-circuito e é comum para todas as línguas que eu já trabalhei em (C, C ++, C #, Java, Smalltalk, Javascript, Lisp), exceto para VB, VB.NET e Fortran.

É realmente um recurso muito útil. Sem curto-circuito, você não seria capaz de fazer isso:

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

Sem um curto-circuito, você teria que ter aninhados if porque a segunda parte iria lançar um erro se uma era nulo.

Coldfusion vai nativamente fazer avaliação de curto circut. Estou certo de que todos os desenvolvedores CF ter escrito:

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

MATLAB é uma linguagem que distingue entre "padrão" lógica operadores operadores e curto-circuito :

  • & (operador AND) e | (OR operador) pode operar em matrizes de forma elemento-wise.
  • && e || são versões de curto-circuito para que o segundo operando é avaliado apenas quando o resultado não é totalmente determinada pelo primeiro operando. Estes só podem operar em escalares , não matrizes.

Outras respostas têm dado bons exemplos de idiomas com e sem avaliação de curto-circuito por isso não vou repeti-los.

Apenas um ponto interessante para acrescentar: Lisps como Clojure têm avaliação boolean curto-circuito, mas, além disso você pode muito trivialmente definir qualquer operador você gosta com a avaliação curto-circuito através do uso de macros <. / p>

Exemplo de uma operação de "ne" curto-circuito em 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top