2

在下面的按值调用示例中,我无法理解为什么这段代码没有将 5 的值更改为 6。

第 11 行调用函数 changeValue 的值为 6,所以我认为应该输出 6,但仍然输出 5?

#include <iostream>
using namespace std;

void changeValue(int value);

int main()
{
  int value = 5;
  changeValue(value);

  cout << "The value is : " << value << "." << endl;

  return 0;
}

void changeValue(int value)
{
  value = 6;
}

// This doesn't change the value from 5 to 6. 5 is output?
4

6 回答 6

9

当您通过传递函数参数时,对象的副本将传递给函数而不是原始对象。除非您明确指定函数的参数,否则在 C/C++ 中始终按值传递。

你的功能:

void changeValue(int value)

value按值接收参数,简而言之,创建in的副本main()并将其传递给函数,函数对该值而不是valuein 进行操作main()

如果要修改原始文件,则需要使用pass by reference

void changeValue(int &value)

现在对原始的引用(别名)value被传递给函数并且函数对其进行操作,从而反映了main().

于 2012-06-09T09:02:32.530 回答
1

当前观察到的行为是因为按值传递意味着实际上将值的副本(具有值的新整数)传递给函数。

您必须通过引用传递。为此,changeValue 函数将如下所示:

void changeValue(int& value)

其余代码将保持不变。

通过引用传递变量意味着将int value声明的相同main传递给changeValue函数。

或者,您可以传递指向valuechangeValue函数的指针。但是,这也需要更改调用函数的方式。

int main()
{
    int value = 5;

    changeValue(&value);

    ...

    return 0;
}

void changeValue(int* value)
{
    *value = 6;
}
于 2012-06-09T09:03:18.170 回答
1

的值value没有改变,因为int你传递给函数的值被复制到函数的堆栈帧中,然后它被改变,当函数退出时,副本被销毁。的堆栈帧中的原始main文件没有更改,因为它被复制到changeValue.

如果你想改变它,你应该传递一个对 an 的引用int,就像这样void changeValue(int& value),它表示该值不会被复制到函数中,而只是传递原始值的别名。

于 2012-06-09T09:03:55.710 回答
1

我将这个答案作为另一种思考编写函数和按值传递参数的方式。

您也可以通过以下方式编写此代码。即按值传递参数,修改函数中的本地副本,不改变原始值,并返回改变后的值。

int changeValue(int val)
{
  val = 6;
  return val;
}

int main()
{
int value = 5;

value = changeValue(value);

cout << "The value is : " << value << "." << endl;

return 0;
}

我并没有以任何方式表明我对您的程序的建议比通过引用更好。相反,这只是学习函数式编程语言(Clojure)的方式正在影响我的思维方式。

此外,在 Python 等语言中,您不能修改标量参数。您只能返回一个新值。所以我的回答更像是在 C/C++ 中以不同方式思考事物的练习。

于 2012-06-09T13:26:34.430 回答
0

和:

副本分配了 6,但不返回更改。

如果要更改值,则需要一些参考或指针:

尝试使用方法签名,如:

void changeValue(int& value)

这可能会达到你的预期

于 2012-06-09T09:04:52.903 回答
0

这是因为changeValue ()函数的变化是局部的。当您可以将 mainchangeValue (value)中变量的内容value复制到函数的名为value(相同名称)的形式参数中时。同名并不意味着两者相同。您在函数内部访问的值是您在 main 中的值的副本。

要更改,您需要通过引用或指针传递它

void changeValue (int *val)
{
  *val = 6;
}

changeValue (&value)主要调用

这是有效的,因为 main 中的变量地址value被传递,并且这个地址值被复制到val函数中。通过这样做*val,我们可以得到复制到的地址的内容val,这实际上是valuemain 中的内容。

或者

void changeValue (int &val)
{
  val = 6;
}
于 2012-06-09T09:04:54.050 回答