2010-07-30 12 views
6

non capisco l'output del seguente programma:Si prega di spiegare un conflitto apparente tra la precedenza di && e || e il risultato effettivo di un'espressione

#include<stdio.h> 

int main() 
{ 
    int i=-3, j=2, k=0, m; 
    m = ++i || ++j && ++k; 
    printf("%d %d %d %d\n", i, j, k, m); 
    return 0; 
} 

L'uscita è -2 2 0 1 anziché -2 3 1 1, implicando che ++i stata valutata (e provocato l'operatore || a breve circuito sul lato destro) prima dell'espressione ++j && ++k che sembra contraddire il fatto che l'operatore && ha precedenza superiore a ||.

Qualcuno potrebbe spiegare perché?

+1

Qual è il tipo di m? –

+0

m è di tipo integer so che l'Anwer ... ho bisogno di spiegazione perché è k = 0 – anurag

+4

'' j' e k' non sono mai incrementato perché quella parte dell'espressione è in corto circuito. '++ i' è vero, quindi il resto dell'espressione non viene valutato. –

risposta

2

L'espressione:

++i || ++j && ++k 

è equivalente a:

(++i) || ((++j) && (++k)) 

Spiegando:

  1. ++i viene valutata - (-2) || ((++j) && (++k));
  2. L'operatore || viene valutato - (1);

Poiché 1 || anything si verifica true, l'operando destro non viene valutato.Pertanto, la precedenza && non importa qui. Questo cortocircuito è garantito sia in C che in C++ dagli standard pertinenti (vedere Is short-circuiting logical operators mandated? And evaluation order?).

Ora, provare a utilizzare un sotto-espressione, in questo modo:

(++i || ++j) && ++k 

che è equivalente a:

((++i) || (++j)) && (++k) 

Spiegando:

  1. ++i viene valutata - ((-2) || (++j)) && (++k);
  2. || viene valutata - (1) && (++k)
  3. ++k viene valutata - (1) && (1);
  4. Valutazione true;
3

-2 2 0 1

pigro.

#include <stdio.h> 

int main() 
{ 

int i=-3,j=2,k=0; 
int m=++i||++j&&++k; 

printf("%d %d %d %d",i,j,k,m); 

} 

Compilare, correre e vedere per conto proprio.

gcc tmp.c -o tmp 
+0

I miei pensieri esattamente – Tom

+1

Shouldnt && devono essere eseguiti prima a causa della precedenza più alta? – anurag

+0

No. Questo è molto ben spiegato nella risposta di Jerry Coffin. L'OP e altri hanno solo un problema di comprensione. –

22

L'output dovrebbe essere qualcosa del tipo:

Error, line 2: 'm': undefined variable. 

Edit: con quello fissato, solo il ++i dovrebbero essere valutati. La precedenza non determina (o addirittura influisce) l'ordine di valutazione. Precedenza significa che l'espressione è equivalente a ++i || (++j && ++k). L'ordine di valutazione per || o && è sempre che l'operando di sinistra viene valutato, quindi c'è un punto di sequenza. Dopo il punto di sequenza, l'operando di destra viene valutato se e solo se necessario per determinare il risultato finale (cioè, l'operando di destra di || viene valutato se l'operando di sinistra è valutato a zero, l'operando di destra di && viene valutato se l'operando di sinistra è valutato a non-zero).

In questa espressione, viene valutato ++i, quindi poiché è l'operando di sinistra di || e valutato diverso da zero, nessuno del resto dell'espressione viene valutato.

+1

+1 per avermi fatto ridere. Sono d'accordo. : D –

+0

Originariamente era una sola riga, con il m facente parte della dichiarazione con il resto. Quando si rompe, l'editor sembra dividere le righe, inserendo l'errore. –

+0

@James - Anche quando si trattava di un solo liner c'era un ';' tra il k e il m. –

0

A titolo di spiegazione:

#include <stdio.h> 

int main() 
{ 
    if (-1) 
     printf ("-1!\n"); 
    else 
     printf ("Not -1.\n"); 
    return 0; 
} 

numeri negativi non sono false in C. confrontare sempre i valori booleani a 0 (o FALSE) oppure si può ottenere morso da if (worked == TRUE) dando falsi negativi.

Problemi correlati