Выражение:
++i || ++j && ++k
Эквивалентно:
(++i) || ((++j) && (++k))
Объяснение:
++ i
вычисляется - (- 2) || ((++ j) && (++ k))
; ||
- (1)
; Так как ] 1 || something
возвращает истину, правый операнд не оценивается. Таким образом, приоритет &&
здесь не имеет значения. Это короткое замыкание гарантируется как в C, так и в C ++ соответствующими стандартами (см. Требуются ли логические операторы короткого замыкания? И порядок оценки? ).
Теперь попробуйте использовать подвыражение, например:
(++i || ++j) && ++k
Что эквивалентно:
((++i) || (++j)) && (++k)
Объяснение:
++ i
вычисляется - ((- 2) | | (++ j)) && (++ k)
; ||
вычисляется - (1) && (++ k)
++ k
оценивается - (1) && (1)
; Результат должен быть примерно таким. :
Error, line 2: 'm': undefined variable.
Редактировать: с этим исправлением нужно оценивать только ++ i
. Приоритет не определяет (и даже не влияет) порядок оценки. Приоритет означает, что выражение эквивалентно ++ i || (++ j && ++ k)
. Порядок оценки для ||
или &&
всегда таков, что вычисляется левый операнд, затем есть точка последовательности. После точки последовательности правый операнд оценивается тогда и только тогда, когда это необходимо для определения окончательного результата (т. Е. Правый операнд ||
оценивается, если левый операнд равен нулю; правый операнд &&
оценивается, если левый операнд не равен нулю).
В этом выражении вычисляется ++ i
, а затем, поскольку это левый операнд ||
и оценивается ненулевое значение, остальная часть выражения не оценивается.
В качестве пояснения:
#include <stdio.h>
int main()
{
if (-1)
printf ("-1!\n");
else
printf ("Not -1.\n");
return 0;
}
Отрицательные числа не являются ложными в C. Всегда сравнивайте булевы значения с 0 (или FALSE
), иначе вас может укусить if (worked == TRUE)
, выдавая ложноотрицательные значения.
-2 2 0 1
Ленивый.
#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);
}
Скомпилируйте, запустите и убедитесь сами.
gcc tmp.c -o tmp