2009-08-25 13 views
16
if((A) && (B)) 
{ 
    //do something 
} 
else 
    //do something else 

La domanda è, la frase immediatamente si interromperà se A è FALSE. B sarebbe anche stato valutato?Come viene valutata l'istruzione 'if (A && B)'?

Chiedo questo nel caso in cui B verificando la validità di un indice di array dice array [0] quando l'array è effettivamente vuoto e ha zero elementi. Quindi lanciare un segfault perché stiamo cercando di accedere a qualcosa che è fuori limite dell'array. Specificamente

if((array.GetElements() > 0) && (array[0])) 
    array[0]->doSomething(); 
else 
    //do nothing and return 

Questo può essere pericoloso se array [0] viene effettivamente valutata perché segfaults senza il primo controllo a sinistra del '& &'. La precedenza mi dice che il lato sinistro avrà sicuramente la precedenza ma non mi dice che non valuterà il lato destro se la sinistra è FALSE.

+0

L'altra forma canonica è 'if (p && p-> bar) {}'. Questo è anche sicuro. – MSalters

+0

Se si vuole solo "non fare nulla e tornare", si dovrebbe lasciare completamente il "else". Altrimenti, il compilatore si lamenterà che non ci sono istruzioni per andare con il resto (se il resto è l'ultima cosa nel blocco che lo racchiude) o, peggio, prendere la prossima affermazione e usarla come istruzione per inserire il blocco else . –

+0

Ho provato ad usare i commenti come segnaposto che significa: un po 'di codice andrà qui, ma non è abbastanza importante da includere nel mio esempio. La realtà della situazione è che c'è un codice che ritorna nello scope dell'altro ma anche il codice dopo l'ambito dell'altro. Spero che lo risolva – BuckFilledPlatypus

risposta

44

In C e C++, gli operatori && e || "cortocircuito". Ciò significa che valutano solo un parametro, se necessario. Se il primo parametro su && è falso, o il primo a || è true, il resto non verrà valutato.

Il codice che hai postato è sicuro, anche se mi chiedo perché includi un blocco vuoto else.

+0

Sì, il mio commento non è corretto, modificato in // non fare nulla e restituire, che è più preciso in questo caso. – BuckFilledPlatypus

+10

Vorrei aggiungere che se sovraccarichi l'operatore && o || nella tua classe, NON correvano più. Qualcosa da tenere a mente. –

+2

@ Kristo, non lo sapevo! Tuttavia, non penso che ci siano casi sane da sovraccaricare quell'operatore. Sovraccaricare l'operatore del cast bool sarebbe più utile, credo. – strager

-4

sì, se ((A) & & (B)) non riuscirà sulla prima clausola, se (A) viene valutata falsa.

questo si applica a qualsiasi lingua btw, non solo derivati ​​C. Per l'elaborazione con thread e parallelo questa è un'altra storia;)

+6

Non tutte le lingue. Alcune lingue, come Visual Basic, hanno operatori logici che non * cortocircuitano. –

+1

Vorrei sottolineare che questo non è stato il caso con VB per molto tempo, prima che fossero introdotti "OrElse" e "AndAlso". Anche adesso, "Or" e "E" non fanno corto circuito. Il motivo è che in precedenza gli operatori logici e bit "Or" e "And" erano gli stessi. – DevByDefault

+1

Alcune lingue, come Ada, hanno entrambe le opzioni disponibili ("AND"/"AND THEN" e "OR"/"O ELSE"). –

10

Si sta chiedendo l'operatore &&, non l'istruzione if.

short-circuits, il che significa che se durante il lavoro soddisfa una condizione che risulta in una sola risposta, smetterà di funzionare e utilizzerà quella risposta.

Quindi, 0 && x eseguirà 0, quindi terminare perché non c'è modo per l'espressione di valutare non zero indipendentemente da ciò che è il secondo parametro &&.

3

Sì, si chiama Short-circuit Evaluation.

Se la validità dell'istruzione booleana può essere assicurata dopo una parte della dichiarazione, il resto non viene valutato.

Questo è molto importante quando alcune delle istruzioni hanno effetti collaterali.

Problemi correlati