Ответ 1
Оператор return (x = x + 2, x + 1);
эквивалентен:
x = x + 2; // x == 7
return x + 1; // returns 8
Со ссылкой на разделенные запятыми возвращаемые аргументы в функции C [duplicate] ,
x=x+2,x+1;
будет оцениваться как
x=x+2;
Однако, в случае следующего кода
#include<stdlib.h>
#include<stdio.h>
int fun(int x)
{
return (x=x+2,x+1); //[A]
}
int main()
{
int x=5;
x=fun(x);
printf("%d",x); // Output is 8
}
Не должно быть строки [A], должно оцениваться как
x=x+2;
давая x = 7
Оператор return (x = x + 2, x + 1);
эквивалентен:
x = x + 2; // x == 7
return x + 1; // returns 8
При записи return (x=x+2,x+1)
первое выражение оценивается первым, поэтому вычисляется x=x+2
, в результате чего значение x равно 7 в качестве побочного эффекта. Затем второе выражение вычисляется и возвращается, следовательно, функция возвращает x + 1, следовательно, возвращает 8.
Если бы вы написали return (x+2,x+1);
, результат был бы 6, потому что первое выражение x+2
не имеет побочного эффекта.
Обе части в return
оцениваются соответственно, и возвращается результат последней инструкции:
Сначала мы имеем:
x = x + 2 // 7
Теперь x
обновляется до 7
перед второй оценкой, которая дает:
x + 1 // 7 + 1 = 8
и наконец вернитесь 8
.
Для лучшего понимания рассмотрим случай промежуточной переменной следующим образом:
return (y = x + 2, y + 1);
В QA вы удобно связываете состояния
Оператор запятой вычисляет ряд выражений. Значение группа запятых - это значение последнего элемента в списке.
поэтому значение
x+2,x+1;
- это x+1
, побочных эффектов нет.
Пример кода:
#include<stdio.h>
int main(int argc, char * argv){
int x;
x = 0;
x = (x+2, x+1);
printf("%d\n", x);
return 0;
}
приводит к 1
при запуске.
Тем не менее, когда вы делаете
return (x=x+2, x+1)
у вас есть побочный эффект: x
сначала увеличивается на два, затем x
увеличивается на 1, и результат возвращается.
Как заявили другие пользователи, поток команд идет слева направо, а в случае return
он возвращает значение в крайнем правом операторе. То, что написано перед этим оператором и разделено запятыми, ничем не отличается от строчных выражений. Пример:
return (x = x + 2, x = x - 5, x + 1);
Приведенный ниже код дает тот же результат:
x = x + 2;
x = x - 5;
return x + 1;
Для x = 0
это вернет -2
. Обратите внимание, что для обоих кодов, если мы изменим x = x - 5
на x - 5
, т.е. мы вычитаем 5
из x
, но не сохраняем его результат где-либо, возвращаемое значение x
изменится на 3
и, следовательно, подтверждая эквивалентность.
Это вопрос приоритета оператора.
x=x+2,x+1
оценивается как (x=x+2), (x+1)
, а не как x=(x+2,x+1)
Оператор запятой вводит точку последовательности в ваш код. Заявления оцениваются в следующем порядке:
x = x + 2
, в этот момент локальный x
в fun
равен 7.
x + 1
, который оценивается как 8, и возвращается.
Чтобы уточнить, здесь заключенная в скобки версия, показывающая приоритет оператора:
return (x=x+2),x+1;
Левое выражение вычисляется, и его значение выбрасывается. Правое значение выражения - это то, что возвращается.