如果一个参数同时按值传递和按引用传递,会发生什么?它是否会被修改?

4
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("BAC.TXT");
void eval(int a, int b, int &rez)
{
    rez = a + b;
}
int main()
{
    int nr;
    int s;
    fin >> s;
    while (fin >> nr)
        eval(s, nr, s);
    cout << s << '\n';
    return 0;
}

所以我有这段代码。我从文件中读取数字,并使用给定的函数“eval”跟踪它们的总和。在这种情况下,将参数传递两次而不是使用另一个变量可能被认为是糟糕的代码(虽然我不确定是否在我的情况下是糟糕的代码)。我的问题是:这会改变变量s的值吗?再次说明,我通过值传递一次,通过引用传递一次!我已经在我的电脑上编写了代码,它确实更改了s的值。现在我的问题是:为什么?如果我用正确的方式问这个问题:背后发生了什么?


5
as的一个副本。rez就是s本身。我不清楚你对此还有什么疑问。 - François Andrieux
4个回答

6
事实上,as 的一个副本并不影响问题本质。也许这是你感到困惑的原因,但它只是一个副本。考虑你可以像下面这样调用函数:
auto temp = s;
eval(temp,nr,s);

为了获得完全相同的结果。在函数rez内部,有一个对s的引用,因此对它的修改将反映在main中的s上。换句话说,rezs的别名,而as没有任何关系,它们只是恰好持有相同的值。

3
这个问题与函数参数和引用/指针的行为有关。
当你将一个值传递给函数时,它会将你给定的值复制到函数内部的一个局部变量中。
在你的例子中,当你传递's'时,它就像在主函数中执行'int a = s'一样,将其复制到'a'中(这就是发生的情况)。
引用也是如此。当您将's'传递给第三个参数时,它会执行以下操作:
int &rez = s
通过引用传递时,它类似于获取变量的地址而不是值本身,并将该地址复制到一个已解除引用的本地变量中。(指针相关)
因此,该值会发生改变。
请查看关于指针和引用的视频以更好地理解主题:'the Cherno Project' youtube频道上的
Pointers
References

但是引用与指针密切相关,OP 应该掌握指针以完全理解引用及其背后的知识。 - Narice
1
说实话,我完全不同意,但我理解你的观点是完全有效的 ;) - 463035818_is_not_a_number

2

简短回答:是的,s将被更改。

长话短说:让我稍微重写一下你的代码片段,以说明在调用函数期间函数参数发生了什么:

#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("BAC.TXT");
void eval(int a, int b, int &rez)
{
    rez = a + b;
}
int main()
{
    int nr;
    int s;
    fin >> s;
    while(fin >> nr) {
        int a = s;
        int b = nr;
        s = a + b;
    }
    cout << s << '\n';
    return 0;
}

所以,基本上,ab 只是分别复制了 snr。然而,res 就是 s。"最初的回答"

1

我的看法是,我期望以下操作:

  1. s 复制到新变量 l_S 中。
  2. nr 复制到新变量 l_Nr 中。
  3. &s 复制到新变量 l_Ptr 中。
  4. l_Nrl_S 相加。
  5. 将结果保存在 *l_Ptr 中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接