Perché “k” non viene incrementato nell’istruzione “m = ++ i && ++ j || ++ k “quando” ++ i && ++ j “viene valutato come vero?

Non sono le singole espressioni in un’espressione AND / OR logica composita che si suppone debbano essere valutate prima che gli operatori logici vengano applicati al loro risultato? Perché ++k non è intatto nella condizione m = ++i && ++j || ++k m = ++i && ++j || ++k per il seguente programma:

  #include 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; } 

Risultato: -2,3,0,1

Ma mi aspetto che l’output -2,3,1,1

Dovresti evitare di codificare un codice così illeggibile. In realtà è analizzato come

 m = (++i && ++j) || ++k; 

Quindi una volta j >= 0 la condizione ++j è sempre vera, quindi ++k non viene valutato poiché && è una scorciatoia e quindi ma || è una scorciatoia o altro (quindi non possono valutare il loro operando giusto).

Così && viene valutato come segue: l’operando di sinistra viene valutato, se è falso viene restituito e quindi solo quando è vero (cioè non uguale a 0 ) l’operando di destra viene valutato e restituito come risultato valutato del && . Allo stesso modo || viene valutato come segue: viene valutato l’operando di sinistra. Se è vero (diverso da zero) diventa il risultato del || ; altrimenti l’operando di destra viene valutato ed è il risultato del || espressione.

In particolare, quando si codifica if (x > 0 && 20/x < 5) la divisione non viene mai tentata per x==0 .

Leggi anche gli operatori di wikipedia in C & C ++ e valutazione del cortocircuito e pagine di valutazione lazy ; e si prega di prendere diverse ore per leggere un buon libro di programmazione C.

Gli operatori logici hanno una valutazione di cortocircuito, cioè non appena viene determinato un valore per l’espressione, il resto dell’espressione non viene valutato.

ad esempio m = ++i && ++j || ++k; m = ++i && ++j || ++k; in questo ++ i -> true, ++ j -> true (non valore zero), quindi m = true && true || ++k; m = true && true || ++k;

ora vero && vero è vero così

 m = true || ++k 

Come nell’operatore OR se 1 lato è vero, l’altro non viene valutato, quindi il risultato è vero.

Quindi k non è incrementato.

Questa è una scorciatoia per operatori logici, nel tuo caso operatore || . Quando il primo operando è true , è imansible che il secondo operando abbia un impatto sul risultato. Sarà sempre vero, non importa quale possa essere il secondo operando. Quindi il secondo operando non viene valutato.

Lo stesso vale per l’operatore logico && , se il primo operando risulta false . Il secondo operando non ha importanza, il risultato sarà sempre false e il secondo operando non sarà valutato.

&& e || sono operatori logici, e li stai usando fuori dal contesto che è strano (ok per C / C ++ ma avresti errori di tipo in Java o C #).

Hai appena scoperto gli operatori di cortocircuito: non è necessario valutare l’intera espressione se “sai” che è vero. ie i e j non sono zero quindi non devi fare nulla con k dato che sai che l’espressione è vera.

m = ++ i && ++ j || ++ k;

Sopra la riga di codice esegue ++ i e ++ j prima e non esegue ++ k poiché è scritta dopo || (O)

Gli operatori logici non vengono eseguiti quando l’istruzione precedente è vera già in caso di || e falso in caso di &&

Quindi k è intatto