ИЛИ и операция И в C

У меня есть сомнения в программе ниже.

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

Я получаю вывод как -2 2 0 1.

В операции ИЛИ, если 1-е значение истинно, то оно не будет оценивать 2-е, поэтому i = -2 и j =2. Затем следует операция И. Он проверит, чтобы оба значения были истинными. Итак, если k = 1, то m = 1. Таким образом, вывод должен быть -2 2 1 1. Я запускаю и проверяю и получаю вывод как -2 2 0 1 но я не мог понять как.


person Angus    schedule 25.06.2011    source источник
comment
@Mikola&Michael:Спасибо, что заставили меня понять.   -  person Angus    schedule 25.06.2011


Ответы (2)


Вы использовали короткое замыкание или. Поскольку ++i оценивается как -2, что не равно 0, происходит короткое замыкание, и остальная часть выражения не вычисляется. В результате ни j, ни k не увеличиваются.

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

РЕДАКТИРОВАТЬ: исправлена ​​ошибка с объяснением приоритета.

person Mikola    schedule 25.06.2011
comment
Я смотрю на код и не понимаю, почему m = 1 вместо -2, что является результатом ++i. - person Sophie Alpert; 25.06.2011
comment
Я не думаю, что 1 гарантировано, только ненулевое. m получает логический результат бинарной операции. - person Mat; 25.06.2011
comment
@Бен Альперт: Нет, || boolean или (в отличие от |). Он преобразует свои аргументы в логический тип (т. е. 0/1 int) и возвращает их. Если вы зададите ему любое ненулевое целое число в качестве одного из его операндов, он вернет 1. Если бы он сделал иначе, все бы испортилось (например, подумайте о том, что произойдет, если вы сделаете это с помощью И? Скажем, одно значение было бы 2 а другой было 4, вы бы получили 0!) - person Mikola; 25.06.2011
comment
Ах, я путал языки и думал, что это вернет первый аргумент. FWIW, 2 && 4 в JavaScript дает 4. - person Sophie Alpert; 25.06.2011
comment
@Ben Alpert: Честная ошибка, хотя действительно нужно задаться вопросом, почему javascript выбрал такое поведение вместо старой (и, возможно, более продуманной) семантики C? В любом случае, я не хочу начинать драку, так что, возможно, мне следует держать эти язвительные замечания при себе. :) - person Mikola; 25.06.2011
comment
Это на самом деле часто полезно; Руби делает то же самое. x = x || 17 установит x в 17, если x не определено (также если оно ложно). - person Sophie Alpert; 25.06.2011
comment
Не имеет значения, какая ассоциативность имеют логическое ИЛИ и логическое И, потому что они не имеют одинакового приоритета. Логическое И имеет более высокий приоритет, чем логическое ИЛИ. Именно поэтому ++k не оценивается. - person CB Bailey; 25.06.2011
comment
@Чарльз Бейли: Ок! Вы правы, +1. Я обновлю ответ. - person Mikola; 25.06.2011

Ничего после || не оценивается, так как результат выражения ++i не равен нулю.

person Michael Foukarakis    schedule 25.06.2011