O que é "curto-circuito" em C como idiomas?


14

Ouvi falar do termo "curto-circuito" usado em C, C ++, C #, Java e muitos outros. O que isso significa e em que cenário seria usado?


6
Existe um artigo da Wikipedia sobre o conceito: en.wikipedia.org/wiki/Short-circuit_evaluation É uma otimização na avaliação do &&operador.
wirrbel

1
@ wirrbel Eu acredito que se aplica ||também ... pelo menos deveria.
Radu Murzea

1
@RaduMurzea Indeed. Contraste ||e &&para &e |para ver a diferença sutil. Tem um programa simples avaliar 1 || printf("yay");vs 0 || printf("yay");e 1 | printf("yay");vs 0 | printf("yay");para ver as differeces
wirrbel

Respostas:


35

Curto-circuito em C é quando um operador lógico não avalia todos os seus argumentos.

Tomemos, por exemplo &&, e , é óbvio que 0 && WhoCaresisso será falso, não importa o que WhoCaresseja. Por isso, C apenas pula a avaliação WhoCares. O mesmo vale 1 || WhoCares, sempre será verdade. Por isso, podemos escrever código como

CanFireMissiles && FireMissiles()

Dessa forma, evitamos fazer alguma operação potencialmente impossível. Se não podemos disparar os mísseis, certamente não queremos tentar. Isso é comumente usado com ponteiros, especialmente ponteiros de arquivo.

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

Isso ocorre de várias outras maneiras úteis para evitar computação desnecessária

 isFileReady() || getFileReady()

Isso evita o trabalho extra se não for necessário.


1
A qualquer momento, se eu respondi a sua pergunta você pode verificar a caixa de seleção ao lado dele para marcar a sua pergunta como respondida
Daniel Gratzer

7
Eu não amo CanFireMissiles && FireMissiles(), pois me faz suspeitar que você está abusando de curto-circuito para provocar efeitos colaterais. Eu sinto que você está escondendo ações de forma condicional. Esse código é melhor escrito como if(CanFireMissiles){FireMissiles();}ou if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}.
18713 Brian

2
Eu diria que o único uso é ocultar os efeitos colaterais. Geralmente não é do tipo "Explodir uma cidade", mas coisas como desreferenciar um ponteiro ou usar recursos do sistema também são feitas dessa maneira em C com bastante frequência. Veja a página da Wikipedia, a seção inteira em uso é "Ocultando efeitos colaterais"
Daniel Gratzer

2
@jozefg, você também pode usá-lo para evitar operações caras como IsInCache(value) || IsInDatabase(value), onde o IsInDatabase pode levar tempo (especialmente se o uso de um dispositivo móvel e a latência da rede for um problema).
mgw854

4

"Curto-circuito" normalmente se refere à " Avaliação de curto-circuito ", que é um conceito geral, não apenas específico de C.

Avaliação de operadores booleanos da esquerda para a direita; portanto, quaisquer termos que tornarão os outros termos desnecessários serão úteis. Portanto, você pode verificar uma condição que exclua outras condições posteriormente, permitindo uma avaliação parcial das operações lógicas, em vez de avaliar a coisa toda.

Exemplo:

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

Um exemplo mais complexo:

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

8
Curto-circuito significa menos economia de tempo, mas mais não ser avaliado. Uma função que não está sendo avaliada também não terá o efeito colateral, caso seja avaliada.
Pieter B

Você sabe, isso == 0não é apenas desnecessário, pode realmente confundir algumas pessoas.
Deduplicator

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.