Понимание цепочки операторов назначения
Кто-нибудь может объяснить вывод кода ниже
int a=10;
a = a -= a+= a -= a += a;
output : 10
Я не могу понять, как это дает 10?
2 ответа
a += a
средства a = a + a
,
то же самое, a -= a
средства a = a - a
,
Я не уверен, какой путь уместен для запуска, но если я преобразую данный код справа, используя выше,
a += a > a = a + a;
a -= a += a > a = a - (a + a);
a+= a -= a += a > a = a + (a - (a + a ));
a -= a+= a -= a += a > a = a - (a + (a - (a + a)));
a = a -= a+= a -= a += a > a = a - a - a + a + a;
где -a -a + a + a
отменяет друг друга, в результате чего a = a
, который 10
,
Здесь работают несколько концепций.
- Первый - операторская ассоциативность
В языках программирования ассоциативность оператора - это свойство, которое определяет, как операторы с одинаковым приоритетом группируются при отсутствии скобок.
Assignment operator is right associative
оператор, означающий оценку выражения без скобок с несколькими операторами присваивания, мы бы начали оценку с правой стороны. Это определяет приоритет.
Ну, технически мы говорим о Addition assignment +=
а также Subtraction assignment -=
, что совпадает с оператором присваивания после раскрытия.
a = a -= a+= a -= a += a;
такой же как
a = (a -= (a+= (a -= (a += a))));
После того, как вы измените это выражение, становится ясно, каким будет ответ 10
- Второй - это L-Value и R-Value, просто
L-Value
это выражение, которое может появиться вleft hand side of an assignment
работа в выражении в соответствии с правилами языка программирования, аналогично дляR-Value
выражение, которое может появиться наright hand side of assignment
,
Многие популярные языки программирования позволяют выражения a = b
быть R-Value
выражение, которое возвращает значение L-Value
переменная с тем же типом.
Примечание. Все операторы в выражении имеют возвращаемое значение и имеют тип, подобный function
,
В a = b
, a
является L-Value
и, следовательно, возвращаемое значение и тип a
Так a = b = c
эквивалентно a = assign(b, c)
где TypeA assign(TypeA a, TypeB b)
Функция подписи может представлять операцию присваивания в большинстве случаев.
TypeA assign(TypeA a, TypeB b)
Оценка начинается слева направо для переменных. Это означает, что во время синтаксического анализа синтаксический анализатор начнет заменять переменные с их значением слева направо.
Например в
a += (a += a) => a = a + (a = a + a)
станетa = 10 + (a = 10 + 10)
до того, как компилятор начнет оценивать первый оператор.Первым оцениваемым оператором будет оператор с наивысшим приоритетом в самой внутренней скобке.
Имея в виду эти правила, мы можем увидеть оценку ниже
a = a -= a+= a -= a += a;
//after deciding precedence of operators
a = (a -= (a+= (a -= (a += a))));
//after addition assignment expantion
a = (a = a - (a = a + (a = a - (a = a + a))))
//First pass of parser
a = (a = 10 - (a = 10 + (a = 10 - (a = 10 + 10)))) //2nd pass, current a = 10
a = (a = 10 - (a = 10 + (a = 10 - (20)))) //3rd pass, current a = 20
a = (a = 10 - (a = 10 + (-10))) //4th pass, current a = -10
a = (a = 10 - (0)) //5th pass, current a = 0
a = 10 //6th pass, current a = 10