2012-05-03 3 views
3

Quelle devrait être la sortie de ce programme C?Sortie du programme C suivant

#include<stdio.h> 
int main(){ 
    int x,y,z; 
    x=y=z=1; 
    z = ++x || ++y && ++z; 
    printf("x=%d y=%d z=%d\n",x,y,z); 
    return 0; 
} 

La sortie est donnée: x = 2 y = 1 z = 1
Je comprends la sortie pour x, mais ne vois pas comment les valeurs y et z ne vous laissez pas incrémenté.

Répondre

12

Ceci est le résultat de short-circuit evaluation.

L'expression ++x est évaluée à 2, et le compilateur sait que 2 || anything renvoie toujours 1 (« vrai »), peu importe ce que anything est. Par conséquent, il ne procède pas à l'évaluation anything et les valeurs de y et z ne changent pas.

Si vous essayez avec

x=-1; 
y=z=1; 

Vous verrez que y et zseront être incrémentée, car le compilateur doit évaluer le côté droit du OU pour déterminer le résultat de l'expression.

Editer: asaerl a répondu à votre question de suivi dans les commentaires d'abord, donc je vais juste développer un peu sa bonne réponse.

La priorité de l'opérateur détermine la manière dont les parties qui composent une expression sont liées ensemble. Parce ET a une priorité supérieure OU, le compilateur sait que vous avez écrit

++x || (++y && ++z) 

au lieu de

(++x || ++y) && ++z 

Cela laisse chargé de faire une ou entre ++x et ++y && ++z. À ce stade, il serait normalement libre de choisir s'il «préférerait» évaluer l'une ou l'autre expression en premier - selon la norme - et vous ne seriez normalement pas en mesure de dépendre de l'ordre spécifique. Cette commande n'a rien à voir avec la priorité des opérateurs.

Toutefois, en particulier pour || et && la norme exige que l'évaluation sera toujours passer de gauche à droite afin que court-circuit peut fonctionner et les développeurs peuvent dépendent de l'expression rhs pas évalué si le résultat de l'évaluation dit le lhs.

+1

Merci, cela a aidé, mais l'ordre de préséance n'est-il pas en jeu ici? Ce qui signifie que ++ y && ++ z devrait être évalué en premier, avant le || ? – krishnang

+4

Non. La priorité est l'ordre dans l'analyse, pas l'ordre d'évaluation. BTW, si «++ z» a été évalué, il était UB. (changeant 'z' deux fois) – asaelr

1

En C, toute chose autre que 0 est considérée comme vraie, Et l'évaluation pour le || commencez de gauche à droite.

Par conséquent, le compilateur vérifie la première opérande gauche et si elle est vraie, le compilateur ne vérifie pas les autres opérandes. ex. A || B - Dans ce cas, si A est vrai, alors le compilateur retournera vrai seulement, et ne vérifiera pas si B est vrai ou faux. Mais si A est faux alors il vérifie B et retourne en conséquence signifie que si B est vrai alors retournera vrai ou si B est faux alors il retournera faux.

Dans votre programme, le compilateur vérifie d'abord ++ x (i.e 2) et tout autre que 0 est vrai dans C. Il ne vérifie pas/n'augmente pas d'autres expressions.