Почему возвращаемое значение функции удовольствия 8 вместо 7?

Со ссылкой на разделенные запятыми возвращаемые аргументы в функции 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

Ответы

Ответ 1

Оператор return (x = x + 2, x + 1); эквивалентен:

x = x + 2; // x == 7
return x + 1; // returns 8

Ответ 2

При записи return (x=x+2,x+1) первое выражение оценивается первым, поэтому вычисляется x=x+2, в результате чего значение x равно 7 в качестве побочного эффекта. Затем второе выражение вычисляется и возвращается, следовательно, функция возвращает x + 1, следовательно, возвращает 8.

Если бы вы написали return (x+2,x+1);, результат был бы 6, потому что первое выражение x+2 не имеет побочного эффекта.

Ответ 3

Обе части в return оцениваются соответственно, и возвращается результат последней инструкции:

Сначала мы имеем:

x = x + 2 // 7

Теперь x обновляется до 7 перед второй оценкой, которая дает:

x + 1 // 7 + 1 = 8

и наконец вернитесь 8.

Для лучшего понимания рассмотрим случай промежуточной переменной следующим образом:

return (y = x + 2, y + 1);

Ответ 4

В 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, и результат возвращается.

Ответ 5

Как заявили другие пользователи, поток команд идет слева направо, а в случае 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 и, следовательно, подтверждая эквивалентность.

Ответ 6

Это вопрос приоритета оператора.

x=x+2,x+1 оценивается как (x=x+2), (x+1), а не как x=(x+2,x+1)

Ответ 7

Оператор запятой вводит точку последовательности в ваш код. Заявления оцениваются в следующем порядке:

  1. x = x + 2, в этот момент локальный x в fun равен 7.

  2. x + 1, который оценивается как 8, и возвращается.

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

return (x=x+2),x+1;

Левое выражение вычисляется, и его значение выбрасывается. Правое значение выражения - это то, что возвращается.