2012-05-03 7 views
3

Какой должен быть выход этой программы на C?Вывод следующей программы C

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

Данный вывод: х = 2 у = 1 г = 1
Я понимаю, выход для х, но не видеть, как у и г значения не увеличивается.

ответ

12

Это результат short-circuit evaluation.

++x Выражение вычисляется в 2, и компилятор знает, что 2 || anything всегда имеет значение 1 («истина»), независимо от того, что anything есть. Поэтому он не переходит к оценке anything, а значения y и z не меняются.

Если вы попытаетесь с

x=-1; 
y=z=1; 

Вы увидите, что y и zбудет увеличиваться, потому что компилятор должен оценить правую сторону или, чтобы определить результат выражения.

Редактировать: asaerl ответил на ваш последующий вопрос в комментариях сначала, поэтому я просто немного расправлю его правильный ответ.

Приоритет оператора определяет, как части, составляющие выражение, связываются вместе. Потому и имеет более высокий приоритет, чем OR, компилятор знает, что ты написал

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

вместо

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

Это оставляет поручено сделать или между ++x и ++y && ++z. На этом этапе, как правило, можно будет выбрать, будет ли он «предпочитать» сначала оценить одно или другое выражение - в соответствии со стандартом - и вы обычно не сможете зависеть от конкретного порядка. Этот порядок не имеет ничего общего с приоритетом оператора.

Однако специально для || и && Стандартной требует оценки будет всегда перейти слева направо, так что короткое замыкание может работать и разработчики могут зависеть от выражения RHS не вычисляется, если результат вычисления говорит lhs.

+1

Спасибо, что помогли, но не порядок приоритетности вступает в игру здесь? Значение ++ y && ++ z должно быть оценено сначала, прежде чем || ? – krishnang

+4

№ приоритета - порядок в разборе, а не порядок оценки. BTW, если '++ z' был оценен, это был UB. (изменение 'z' дважды) – asaelr

1

В C любая вещь, кроме 0, рассматривается как истина, а оценка для || начинайте слева направо.

Следовательно, компилятор проверяет первый левый операнд, и если он истинен, тогда компилятор не проверяет другие операнды. ex. A || B - В этом случае, если A истинно, тогда компилятор вернет только истину и не будет проверять, является ли B истинным или ложным. Но если A является ложным, то он проверяет B и возвращает соответственно, означает, что если B истинно, то вернет true или если B является ложным, тогда он вернет false.

В вашей программе компилятор сначала проверит ++ x (i.e 2), и что-либо другое, кроме 0, истинно в C. Следовательно, он не будет проверять/увеличивать другие выражения.

Смежные вопросы