Это (обратите внимание на оператор запятой ):
#include <iostream>
int main() {
int x;
x = 2, 3;
std::cout << x << "\n";
return 0;
}
выходы 2 .
Однако, если вы используете return
оператор запятой, это:
#include <iostream>
int f() { return 2, 3; }
int main() {
int x;
x = f();
std::cout << x << "\n";
return 0;
}
Выходы 3 .
Почему оператор запятой ведет себя иначе с return
?
Ответы:
В соответствии с приоритетом оператора , оператор запятой имеет более низкий приоритет, чем
operator=
, поэтомуx = 2,3;
эквивалентен(x = 2),3;
. (Приоритет оператора определяет, как оператор будет привязан к своим аргументам, более жестко или менее жестко, чем другие операторы, в соответствии с их приоритетами.)Обратите внимание, что выражение запятой
(x = 2),3
здесь, а не2,3
.x = 2
сначала оценивается (и его побочные эффекты завершаются), затем результат отбрасывается, затем3
оценивается (фактически ничего не делает). Вот почему значениеx
есть2
. Обратите внимание, что3
это результат всего выражения запятой (т.е.x = 2,3
), он не будет использоваться для присвоенияx
. (Измените его наx = (2,3);
,x
будет назначено с3
.)Для получения
return 2,3;
, выражение запятой2,3
,2
вычисляются затем его результат отбрасывается, а затем3
вычисляется и возвращаются как результат всего выражения запятой, который возвращается в обратном заявлении позже.Дополнительная информация о выражениях и утверждениях
x = 2,3;
это выражение выражение ,x = 2,3
это выражение здесь.return 2,3;
это оператор перехода ( оператор возврата ),2,3
это выражение здесь.источник
for
циклах, когда, как ни странно, он может сделать код более понятным при численных вычислениях.i += 1, j += 2
цикла for. Кто-то решил, что грамматика C ++ (или, скорее, грамматика C, поскольку эта часть была скопирована оттуда) уже достаточно сложна, не пытаясь определить, что приоритет запятой выше, чем присваивание, когда вы пишете,x = 2, 3
но ниже, когда вы пишетеx = 2, y = 3
!Оператор запятой (также известный как разделение выражений ) оценивается слева направо. Так
return 2,3;
эквивалентноreturn 3;
.Оценка
x = 2,3;
происходит(x = 2), 3;
из-за приоритета оператора . Оценка по-прежнему выполняется слева направо, и все выражение имеет значение 3 с побочным эффектомx
принятия значения 2.источник
return 2,3
иreturn (2,3)
они такие же. Я считал, что первое должно быть(return 2),3
.return 2
- это утверждение (например, сформированноеfor,while,if
), а не выражение. Вы не можете написать, например,f(return 2)
или2+return 2
. Итак,(return 2),3
синтаксически неверно.return 2, 3
что меня интерпретируют как(return 2), 3
.return
может встречаться только в следующих случаях: (a)return
expression_opt;
и (b)return
braced-init-list;
.Это утверждение:
x = 2,3;
состоит из двух выражений :
> x = 2 > 3
Так как приоритет операторов ,
=
имеет больший приоритет , чем запятая,
, поэтомуx = 2
вычисляются и после3
. Тогдаx
будет равно2
.В
return
вместо:int f(){ return 2,3; }
Синтаксис языка:
return <expression>
Примечание
return
не является частью выражения.Таким образом, в этом случае будут оцениваться два выражения:
> 2 > 3
Но
3
будет возвращен только второй ( ).источник
<expression>
как явно необязательный (с точки зрения грамматики).x=2,3
. Оба литерала2
и3
находятся внизу дерева синтаксического анализа, как и идентификаторx
. Это все индивидуально допустимые выражения. Оператор приоритет означает , что=
происходит ниже в дереве разбора, и объединяет в себе два выраженияx
и2
в четвертое выражениеx=2
. Наконец, пятое выражение образовано оператором запятой, соединяющим его две стороныx=2
и3
. Однако вы неправильно указываете, что приоритет оператора определяет порядок оценки. Это не так. Порядок оценки определяется правилами последовательности.Попробуйте применить упрощенный подход, просто выделив приоритет круглыми скобками:
( x = 2 ), 3;
return ( 2, 3 );
Теперь мы можем видеть, что бинарный оператор "" работает одинаково в обоих случаях, слева направо.
источник
x = 2, 3
это само по себе выражение, а дляreturn
негоreturn <expression>
. Вы читаете их как(x = 2, 3)
и(2, 3)
.