2010-07-30 3 views
6

Je ne comprends pas la sortie du programme suivant:Veuillez expliquer un conflit apparent entre la préséance de && et || et le résultat réel d'une expression

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

La sortie est -2 2 0 1 au lieu de -2 3 1 1, ce qui implique que ++i a été évaluée (et a causé l'opérateur || à court circuit son côté droit) avant l'expression ++j && ++k qui semble contredire le fait que l'opérateur && a une priorité supérieure à ||.

Est-ce que quelqu'un pourrait expliquer pourquoi?

+1

Quel est le type de m? –

+0

m est de type entier Je sais que le anwer ... J'ai besoin explaination pourquoi k = 0 – anurag

+4

'' j' et K' ne sont jamais incrémenté parce que cette partie de l'expression est court-circuitée. '++ i' est vrai, donc le reste de l'expression n'est pas évalué. –

Répondre

2

L'expression:

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

équivaut à:

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

Explication:

  1. ++i est évalué - (-2) || ((++j) && (++k));
  2. L'opérateur || est évalué - (1);

Étant donné que 1 || anything est vrai, l'opérande de droite n'est pas évalué.Ainsi, la précédence && n'a pas d'importance ici. Ce court-circuit est garanti en C et C++ par les normes correspondantes (voir Is short-circuiting logical operators mandated? And evaluation order?).

Maintenant, essayez d'utiliser une sous-expression, comme ceci:

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

ce qui équivaut à:

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

Explication:

  1. ++i est évalué - ((-2) || (++j)) && (++k);
  2. || est évaluée - (1) && (++k)
  3. ++k est évaluée - (1) && (1);
  4. Evalue true;
3

-2 2 0 1

Lazy.

#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); 

} 

Compilez, courez et voyez par vous-même.

gcc tmp.c -o tmp 
+0

Mes pensées exactement – Tom

+1

Shouldnt && s'exécute d'abord en raison de la plus haute priorité? – anurag

+0

Non. C'est très bien expliqué dans la réponse de Jerry Coffin. Le PO et d'autres ont juste un problème de compréhension. –

22

La sortie devrait être quelque chose comme:

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

Edit: avec qui fixe, seul le ++i doit être évaluée. La préséance ne détermine pas (ou même affecte) l'ordre d'évaluation. La préséance signifie que l'expression est équivalente à ++i || (++j && ++k). L'ordre d'évaluation pour || ou && est toujours que l'opérande gauche est évaluée, alors il y a un point de séquence. Après le point de séquence, l'opérande droit est évalué si et seulement si nécessaire pour déterminer le résultat final (ie, l'opérande droit || est évalué si l'opérande gauche est évalué à zéro, l'opérande droit de && est évalué si l'opérande gauche a été évaluée à non nul).

Dans cette expression, ++i est évaluée, puis parce que c'est l'opérande gauche de || et évalué non nul, aucun des autres éléments de l'expression n'est évalué.

+1

+1 pour me faire rire. Je suis d'accord. : D –

+0

Il était à l'origine tous d'une ligne, avec le m faisant partie de la déclaration avec le reste. En le décomposant, l'éditeur a apparemment divisé les lignes, en insérant l'erreur. –

+0

@James - Même lorsqu'il s'agissait d'un seul paquebot, il y avait un '; 'entre le k et le m. –

0

En guise d'explication:

#include <stdio.h> 

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

Les nombres négatifs ne sont pas faux en C. comparer toujours les valeurs booléennes à 0 (ou FALSE) ou vous pouvez faire piquer par if (worked == TRUE) donnant des faux négatifs.

Questions connexes