2013-07-15 3 views
-3

В книгах и here указано, что приоритет приращения & Оператор декремента больше, чем тернарный оператор, но тогда почему в приведенном ниже коде значения как b, так и c не увеличиваются, а только Ь приращение (или с приращением в этом условии ложно)ошибка порядка и оценки приоритета оператора

int a=1,h; 
h = (a==1)?++b:++c; 
printf("%d%d",b,c); 

или даже для утверждений типа

++i&&++j||++k; // why not all the increment and decrement operator executes first 

пожалуйста, объясните, если я делаю некоторую концептуальную ошибку и извиняется за то, чтобы о нуб (если это дубликат, то, пожалуйста, перенаправить меня к первоначальному вопросу, я не нашел)

+15

Ну, я надеюсь, что эта путаница служит сильным сдерживающим фактором для написания такого кода. –

+4

О, «слишком локализован», куда вы пошли? :( –

+0

@sumitb У вас есть четкое представление о том, что делает тройной оператор? – Nbr44

ответ

2

Для h = (a==1)?++b:++c; см С11 6.5.15 Условный оператор p4 (курсив мой

оценивается первый операнд; существует точка последовательности между ее оценкой и оценкой второго или третьего операнда (в зависимости от того, что оценивается). Второй операнд оценивается только в том случае, если сначала сравнивает не равный 0; третий операнд оценивается только в том случае, если первое сравнивается с 0;

Это подтверждает, что ваше наблюдение, что только один из ++b и ++c выполнены правильно.

Для ++i&&++j||++k; см. Разделы C11 6.5.13, 6.5.14. И логические операторы OR и AND оценивают слева направо, пропуская оценку дальнейших выражений, как только результат известен (так, как только выражение оценивает ненулевое значение для ||, как только выражение оценивается до нуля для &&).

1

Тернарный оператор оценивает только операнд условия и операнд, который является истинным. Часть ++c в вашем случае не оценивается вообще.

Во втором случае не все операнды оцениваются, потому что операторы || и && выполняют так называемое «короткое замыкание», то есть, если все выражение не имеет шанса изменить его результат больше , остальные операнды не оцениваются.

4

Условное (?:), логическое соединение (&&) и логические дизъюнкции (||) операторы ленивый & крестик;. Они оценивают только операнды, необходимые для получения результата.

В случае условного оператора он оценивает только одну из двух ветвей; первый, если условие оценивается как true, или второе, если условие принимает значение false.

Логический оператор конъюнкции не будет оценивать выражение правой стороны, если выражение левой стороны оценивается как false, потому что результат будет ложным независимо от того, что. Оператор логического дизъюнкции работает аналогично, с той разницей, что он не будет оценивать правую сторону, если левая сторона вычисляет значение true: true || x всегда верно, независимо от x.


& dagger; Если вы не имеете дело с перегруженными && или ||. Перегруженные операторы не могут выполнять ленивую оценку операндов.

+0

@ShafikYaghmour, что никогда не бывает, он никогда не оценивает эти две ветви. –

+0

Ah. Условный оператор не может быть перегружен, так что это не будет применяться. Я переработаю его. –

+0

+1 Совершенно ясно. –

0

Приоритет не контролирует порядок оценки.. Он управляет только тем, как сгруппированы операторы и операнды.

Как операторы ||10, так и && вынуждают выравнивание слева направо и оба являются операторами короткого замыкания; если значение выражения можно определить из левого выражения, тогда правое выражение вообще не будет оцениваться.

Поэтому, учитывая выражение как

a++ || b++ && c++ 

если результат a++ не равен нулю, то результат будет верным независимо от результата b++ && c++, поэтому правая часть не оценивается вообще ,

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