当前位置: 首页 > 知识库问答 >
问题:

当将变量分配给自身的引用时,在修改变量和函数调用返回变量之间,结果应该是什么?

仲孙兴平
2023-03-14
#include <iostream>

int& addOne(int& x)
{
    x += 1;
    return x;
}

int main()
{
    int x {5};
    addOne(x) = x;
    std::cout << x << ' ' << addOne(x);
}

我目前正在学习左值和右值,并做了一些实验,结果似乎是矛盾的。https://godbolt.org/z/KqsGz3Toe产生了“5 6”的输出,Clion和Visual Studio也是如此,但是https://www.onlinegdb.com/49mUC7x8U产生"6 7"的结果

我认为,因为addOne调用x作为引用,它会显式地将x的值更改为6,尽管它被称为左值。正确的结果应该是什么?

共有1个答案

韩单弓
2023-03-14

因为C 17指定了计算的顺序,所以赋值的右侧首先计算,并且

所以在

addOne(x) = x;

首先计算右侧的值,生成5。然后调用函数addOne,它对x做什么并不重要,因为它返回对它的引用,右边的值5被分配给它。

然后排队

std::cout << x << ' ' << addOne(x);

我们首先计算并输出x,得到5,然后调用addOne,得到6

输出56是自C17以来唯一正确的输出。

在C17之前,赋值运算符两边的求值顺序是不排序的。

在同一个标量上(在赋值的右侧)进行未排序的标量修改通常会导致未定义的行为。

但是,由于您将x的增量放入函数中,另外一条规则说函数体的执行只是与调用上下文中的其他计算不确定地排序,这就节省了这一点。这意味着该行将不再具有未定义的行为,但是赋值双方的计算发生的顺序可以是左优先或右优先。

这意味着我们不知道是先计算x,然后再计算addOne(x),还是反过来计算。

因此,在该行之后,x可能是56

然后排队

std::cout << x << ' ' << addOne(x);

17世纪之前,同样的问题也适用。

因此,可能的程序输出可以是以下任一种:

5 6
6 6
6 7
7 7

如果您使用的是GCC或Clang,则可以向编译器指定使用带有-std=c17标志的c17(或c20等更新版本),如果您使用的是MSVC,则可以指定使用/std:c17。默认情况下选择哪个标准版本取决于编译器和编译器版本。

 类似资料:
  • 问题内容: SQL Server(2000/2005)函数获取表名和字段名作为参数,并从函数内的动态查询返回结果。结果应分配给变量,该变量将在存储过程中进一步使用。如何实现呢? 我收到错误消息:“只能从函数中执行函数和扩展存储过程。” 问题答案: 我不确定这如何与函数一起使用,但是如果您有一个存储过程返回一个结果集,则可以使用INSERT EXEC语句将其插入到表变量中。 只要字段匹配,那将起作用

  • 问题内容: 很多人说评论中的要求太多,这让我犹豫不决,但是我仍然没有在他们的答案中找到解决方案,主要是因为(1)他们通常使用jQuery,而(2)问题通常包含我不理解的技术。 我有一个函数,里面有一个变量。变量被分配了一个功能。我敢肯定,这个概念不是AJAX独有的,但这是我正在使用的上下文(如果有区别的话)。 我想将变量传递给函数。但是,由于没有原始函数声明,如何指定参数?我能做到吗? 问题答案:

  • 问题内容: 假设我有一个功能 现在,我想将函数分配给一个名为的变量,这样,如果我使用,它将再次调用该函数。如果我只是做作业,它就会返回。 问题答案: 您根本不调用该函数。 括号告诉蟒蛇,你调用的函数,所以当你把它们放在那里,它调用的功能,并指定值 返回 的(在这种情况下)。

  • 问题内容: 第一个System.out打印 2 并且应该打印,而第二个System打印 65 。我已经用这种语言编程了一年多了,据我所知这是不可能发生的!有什么帮助吗? 上面的代码在两行上都显示 9 。 问题答案: 当你这样做,之前仅仅是一个参考阵列, NO 新阵列已创建并分配给。因此,当您查看自己的价值时,基本上就是查看的价值,反之亦然。只是的别名。这就是为什么在第二张照片中您得到65。 检查该

  • 问题内容: 我使用此辅助函数来接收我的请求的JSON结果: 我将它作为Web应用程序中url的一部分提供了一些字符串,例如’/ api / getusers’,因此看起来像。现在我需要包含JSON数据,我从URL接收将被分配给我的变量,所以它看起来像这样的字符串结果:。然后,我将处理此JSON数据。问题在于返回响应变量。它是未定义的。谢谢! 问题答案: 这是一个异步操作,这意味着从服务器返回后很长

  • 我是helm的新手,我希望能够使用配置映射和共享环境变量将gitlab项目变量写入文件。 我为每个环境(其中