【问题标题】:Why is the return value of the fun function 8 instead of 7? [duplicate]为什么 fun 函数的返回值是 8 而不是 7? [复制]
【发布时间】:2020-01-16 05:47:19
【问题描述】:

参考Comma-Separated return arguments in C function [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

【问题讨论】:

  • 这种情况下命令流程是从左到右的,你也可以试试while(x=2,x&lt;3)来验证——这将是一个无限循环。
  • 感谢您展示我们为何尽量避免使用逗号运算符。
  • @Observer:好吧,我想我们可以将测试放在比我更多的循环形式的中间。

标签: c return-value comma


【解决方案1】:

语句return (x = x + 2, x + 1); 等价于:

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

【讨论】:

  • +1。并直接解决 OP 的困惑:声明 x = x + 2, x + 1; 等效于声明对 x = x + 2; x + 1;。只是声明x + 1; 实际上并没有做 任何事情,所以我们可以忽略该声明并说它等价于x = x + 2;。当你添加一个return 时,显然return x + 1; 语句不再是空操作,所以我们不能再忽略它了。 :-)
【解决方案2】:

在编写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,x+1)会产生副作用?
  • @AshishKumar 因为它改变了x 的值。并不是真正的“副作用”,因为它仍然是显式的,但它会导致 x 在逗号右侧有所不同。
  • @AshishKumar 逗号运算符显式地在左右操作数的求值之间有一个序列点。您可以保证在 x+1 之前评估 x=x+2。无论如何,不​​要写那样的蹩脚代码,并且通常避免使用, 运算符。
【解决方案3】:

return中的两部分分别求值,返回最后一条指令的结果:

起初我们有:

x = x + 2 // 7

现在x 在第二次评估之前更新为7:

x + 1 // 7 + 1 = 8

最后返回8。

为了更好地理解,考虑如下中间变量的情况:

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

【讨论】:

  • 这是 return 的副作用吗,因为这不是逗号运算符的标准行为?
  • 如果您没有将第一个表达式分配给x,那么只有最后一个表达式将被视为返回值
  • 用两个变量试试,它可以给你更好的主意:return (y = x + 2, y + 1)
  • 现在说得通了。
  • nitpick:逗号运算符计算两个部分并返回后者。它不是特定于 return 语句的,你会得到与 y=(x=x+2, x+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 先加 2,然后x 加 1 并返回结果。

【讨论】:

  • 按照这个逻辑,x 应该是 6,而不是 8。
  • 哦,你是对的
  • 查看我的编辑。你清楚为什么吗?
  • 没有。如果你说int y = (x=x+2, x+1),副作用也会发生。副作用是x+2 的值被分配给x(第一步,然后计算x+1)
  • 区别在于(x+2, x+1)和(x=x+2, x+1)
【解决方案5】:

这是运算符优先级的问题。

x=x+2,x+1 被评估为 (x=x+2), (x+1) 而不是 x=(x+2,x+1)

【讨论】:

    【解决方案6】:

    正如其他用户所说,命令流从左到右,在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,即从x 中减去5,但不将其结果保存在任何地方,x 的返回值将更改为3因此,确认等效性。

    【讨论】:

      【解决方案7】:

      逗号运算符在您的代码中引入了一个序列点。语句按以下顺序评估:

      1. x = x + 2,此时fun中的本地x为7。

      2. x + 1,计算结果为 8,并返回。

      为了澄清,这是一个显示运算符优先级的括号版本:

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

      左边的表达式被求值并且它的值被丢弃。右侧表达式的值就是返回的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 1970-01-01
        • 1970-01-01
        • 2019-05-08
        相关资源
        最近更新 更多