Почему вывод ниже указанной программы 0
not 20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
Почему вывод ниже указанной программы 0
not 20
?
#include <stdio.h>
int main()
{
int i = 10, j = 0;
if (i || (j = i + 10))
/* do something */;
printf("%d\n",j);
}
Да, это понятие называется Short-Circuit (в логическом выражении операторов &&
, ||
).
В случае любого логического выражения (включая ||
, &&
) выражение завершения остановки компилятора сразу после вычисления результата (и сохранения выполнения).
Метод короткого замыкания:
!0 || any_expression
== 1
, поэтому any_expression
не нужно оценивать.
И потому что в вашем выражении i
не ноль, а его 10, так что вы можете подумать, если consdition (i || (j = i + 10))
равно как i
.
Логический оператор OR:
Оператор||
гарантирует оценку слева направо; Eсть после точки начала первого операнда. Если первый операнд сравниваетunequal
с0
, второй операндnot
оценены.
Аналогично для && (и оператор):
0 && any_expression
== 0
, поэтому any_expression
не нужно оценивать.
В вашем выражении:
(i || (j = i + 10) )
------------
^
| Could evaluate if i is 0,
as i = 10 (!0 = true), so j remains unchanged as second operand is not evaluated
Для оператора или ||
ответ оператора может быть равен 0, 1. Чтобы сохранить выполнение, оценка прекращается, как только находят результаты. Поэтому, если первый операнд отличен от нуля, результат будет 1
(как указано выше) для выражения. Поэтому для первого операнда i = 10
сравнивается неравномерно с 0, второй операнд (j = i + 10)
не оценивается, поэтому j
остается 0
, поэтому вывод вашего кода 0
.
Примечание. Поведение короткого замыкания не только присутствует в C, но концепция является общей для многих языков, таких как Java, С++, Python. (но не все, например, VB6).
В C гарантируется, что короткое замыкание логических выражений всегда было особенностью C. Это было верно, когда Деннис Ричи разработал и реализовал первую версию C, которая по-прежнему верна в стандарте C 1989 года и остается верной в C99 стандарт.
Связанная запись: Является ли короткое замыкание логическими операторами, заданными в C/С++? И порядок оценки?
||
является оператором short-circuit - если левая сторона оценивается как true, тогда правая сторона не должна быть оценены. Итак, в вашем случае, поскольку i
- true, выражение j = i + 10
не оценивается. Если вы установите для параметра i
значение 0, то правая часть будет оценена,
В if (i || (j = i + 10))
существует два булевых выражения для оценки. Дело в том, что первое верно, поэтому нет необходимости вычислять второе. Это чисто игнорируется.
потому что ||
является оператором короткого замыкания (так же как и оператор &&
).
поэтому в (i || j = i+10)
, i
равно 10, левая часть ||
истинна, выражение j = i+10
не произошло, в результате j=0
.