2016-05-08 4 views
0

Рассмотрим код:Comma оператор используется присваивание

int i, j; 
i = (i = 1, j = 3); 
i++; 
cout<<i<<" "<<j; 

Это печатное 4 3 (C++ 14).

Я прочитал, что оператор запятой оценивает выражение слева и возвращает его справа. Теперь, если это правильно, я хочу знать, что такое возвращаемое значение j = 3? Это rvalue? Или ссылка на lvalue?

Как это работает?

+0

Прошу прощения за 3 дополнительные строки, но есть минимальный предел слов, который, вероятно, не должен применяться в этом случае, так как я считаю, что мой вопрос достаточно ясен. –

ответ

0

Оператор присваивания возвращает lvalue, относящийся к левому операнду. Он группируется справа налево. ([expr.ass]). Обратите внимание, что высказывание о возврате ссылки на lvalue не имеет смысла - оно либо возвращает значение lvalue, либо нет.

Оператор запятой выполняет вычисления значений и побочные эффекты из левого операнда, отбрасывает их, а затем делает то же самое для правильного операнда. ([expr.comma])

Так рефакторинге оператор запятой выдаст следующий эквивалентный код:

i = 1;  // left operand, value discarded 
i = j = 3; // right operand, value preserved 
i++; 

, а затем рефакторинга назначение соединения будет производить следующее еще эквивалентный код:

i = 1; 
j = 3;  // rightmost assignment 
i = j;  // leftmost assignment 
i++; 
2

Для того, чтобы вычислить (i = 1, j = 3), он вычисляет слева направо выражения, разделенные запятой, и возвращает значение последнего (самого правого) выражения. Поэтому он вычисляет i = 1 (i становится 1), затем вычисляет j = 3 (j становится 3), затем возвращает 3.

После вычисления (i = 1, j = 3), который вернул 3, он выполняет назначение, которое устанавливает я до 3.

Тогда я ++ вычисляется, который устанавливает я до 4.

Тогда я и J печатаются.

2

Я хочу знать, что такое возвращаемое значение j = 3?

Операции присваивания * возвращает (или «оценивает») ссылку на левую часть операции, в данном случае j.

Так i = (i = 1, j = 3); идентична:

i = 1; 
j = 3; 
i = j; 

* Для встроенных типов, что есть. Пользовательские operator= перегрузки могут возвращать то, что они хотят, хотя рекомендуется возвращать ссылку на *this, так как это ожидаемое поведение среди программистов на С ++.

+0

поэтому, если я увеличиваю i на 1, это означает, что j также должен увеличиваться, так как вы сказали, что он возвращает ** ссылку **! поэтому строка 3 должна читать i = & j ;? –

+0

@SaurabhRaje Он возвращает ссылку, но ссылочное значение __copied__ равно 'i' (поскольку' i' не является ссылочной переменной). Кроме того, не путайте '& variable' с' type & ', первый является адресом-оператора, последний объявляет ссылочный тип. – emlai

+0

да, я знаю разницу, но я думал, что компилятор может неявно вводить его в ссылку, так как я даю адрес памяти ia. Это просто догадка, я мог бы быть ужасно ошибкой –

Смежные вопросы