C / C ++:将带有成员数组的结构/类按值传递给函数

Posted

技术标签:

【中文标题】C / C ++:将带有成员数组的结构/类按值传递给函数【英文标题】:C / C++ : passing a struct / class with a member array to a function by value 【发布时间】:2015-09-24 18:22:02 【问题描述】:
struct A
  int V[100];
;


void f(A a)


  a.V[0]=30;


int main()

  A a;
  a.V[0]=10;
  f(a);
  cout<<a.V[0];

我期望 30 作为输出,但我得到了 10。我知道,如果参数是按值传递的,数组(如果是类/结构的成员)也是通过引用传递的。相反,当成员时,它们似乎是通过副本传递的。 是真的吗?

【问题讨论】:

How to pass objects to functions in C++?的可能重复 C 还是 C++?选一个。这是两种不同的语言。 【参考方案1】:

将数组作为参数传递给函数会导致它衰减为指向第一个元素的指针,所以就像通过引用传递一样。

将一个对象包含一个数组(不是指针)按值传递给函数会导致该对象(包括数组)被复制到函数的参数中。

如果您想在调用站点看到该修改,请通过非常量引用传递。

【讨论】:

【参考方案2】:

您通过值传递变量a,并在函数f 中将内容更改为30。由于您不返回它并且不通过引用将其传递给函数,因此您对a 的更改不会影响主函数中a 的值。这就是为什么你得到 10 而不是 30 的原因。 这可能就是你想要的:

void f(A &a)

  a.V[0]=30;

【讨论】:

【参考方案3】:

我知道,如果参数是按值传递的,数组(如果是类/结构的成员)也是按引用传递的。

除非这是不正确

你把事情弄糊涂了。

数组的名称,当直接用作函数参数时,衰减为指向该数组[第一个元素]的指针。这并不意味着任何数组,无论在封装对象中嵌套多远,都会神奇地从一个值变成一个“引用”。

确实,您展示的代码是解决这个历史数组名称衰减惨败并获得数组的完整值语义的典型方法,例如std::array&lt;T, N&gt; 正是这个。

【讨论】:

【参考方案4】:

实际上,您将 struct A 类型的对象传递给函数,因此将创建一个空洞的新对象,包括您 class 中的 Array。所以你不会得到 30 作为结果。如果你只将一个数组传递给函数,那么你会被 Array 成员误导,这个值肯定会改变,但在你的情况下,你使用一个结构来包装你的数组。 作为一种解决方法,您应该使用 A 结构上的引用或指针作为函数参数。

【讨论】:

【参考方案5】:

C 只有传值。这适用于所有类型。

您感到困惑,因为“数组”实际上不能在 C 中“传递”——从某种意义上说,没有函数可以具有数组类型的参数。 C 标准规定,如果您尝试编写 array-of-T 类型的参数,编译器会将其视为您编写了指向T 类型的指针。因此,不可能有数组类型的参数。当您传递数组类型的表达式,并且编译器看到参数需要指针类型时,它会在按值传递之前将数组隐式转换为指向其第一个元素的指针。

另一方面,可以有一个结构类型的参数。

【讨论】:

以上是关于C / C ++:将带有成员数组的结构/类按值传递给函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥不允许将数组按值传递给 C 和 C++ 中的函数?

为啥要在 C 中声明一个只包含数组的结构?

我必须在 C 中创建一个带有指向数组的结构数组

C-MPI 发送创建的带有字符数组的 typedef 结构

使用带有结构/数组的头文件的指针问题,导致多重定义错误(C)

C:为啥你可以通过值传递(给函数)一个结构,而不是一个数组?