在 C++ 中通过引用传递结构数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8798448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:07:43  来源:igfitidea点击:

Passing an array of structs by reference in C++

c++arrays

提问by Nate

So I'm still rather new to programming/C++, and still trying to wrap my head around pointers and passing by reference and everything. A program I'm trying to figure out now needs to pass an array of structs to another function. I've gotten it working by just passing the array directly there. It seems to work fine. However, what I'm concerned about is that I believe I'm passing it by value, and I understand that it's better to pass structs by reference, so you're not making a copy of the struct every time...

所以我对编程/C++ 还是比较陌生,并且仍然试图将我的头脑围绕在指针和通过引用传递等等方面。我试图找出的一个程序现在需要将一个结构数组传递给另一个函数。我只是通过直接在那里传递数组来让它工作。它似乎工作正常。但是,我担心的是,我相信我是按值传递它的,而且我知道按引用传递结构更好,因此您不必每次都复制该结构...

Anyway, here's a basic example of what I'm doing:

无论如何,这是我正在做的事情的一个基本示例:

struct GoldenHelmet {
    int foo;
    string bar;
    };

void pass (GoldenHelmet ofMambrino[], int size);

int main () {
    GoldenHelmet ofMambrino[10];
    int size = sizeof(ofMambrino) / sizeof(ofMambrino[0]);
    ofMambrino[1].foo = 1;
    pass(ofMambrino, size);
    cout << ofMambrino[2].foo << endl;
    return 0;
}

void pass (GoldenHelmet ofMambrino[], int size) {
    ofMambrino[2].foo = 100;
    ofMambrino[2].bar = "Blargh";
}

From what I understand, it works because arrays are already pointers, right? But the way I have that configured, am I still passing a copy of the struct and everything to the pass() function? I've tried to pass it by reference, but it doesn't seem to want to work any way I've tried.

据我了解,它之所以有效是因为数组已经是指针,对吗?但是按照我的配置方式,我是否仍然将结构的副本和所有内容传递给 pass() 函数?我试图通过引用传递它,但它似乎不想以我尝试过的任何方式工作。

回答by Kerrek SB

The C++ way:

C++方式:

#include <array>

typedef std::array<GoldenHelmet, 10> Helmets;

void pass(Helmets &);

int main()
{
   Helmets h;
   h[1].foo = 1;
   pass(h);
   //...
}

void pass(Helmets & h)
{
   h[2].foo = 100;
   // ...
}

Indeed, we pass the array by reference.

事实上,我们通过引用传递数组。

回答by Benjamin Lindley

This syntax:

此语法:

void pass (GoldenHelmet ofMambrino[], int size)

is actually quite confusing. Because you are not passing an array, you are passing a pointer. They are not the same thing though, don't get confused. This oddity only applies to function parameters. The above is exactly identical to this:

实际上是相当混乱。因为您没有传递数组,所以您传递的是一个指针。虽然它们不是一回事,但不要混淆。这种奇怪的现象只适用于函数参数。以上与此完全相同:

void pass (GoldenHelmet * ofMambrino, int size)

It's actually impossible to pass an array by value, unless it is a sub-object of another object. You can pass them by reference, you need to include the size though, but you can do that using a template:

实际上不可能按值传递数组,除非它是另一个对象的子对象。您可以通过引用传递它们,但您需要包括大小,但您可以使用模板来做到这一点:

template<int N>
void pass (GoldenHelmet (&ofMambrino)[N])

回答by Jesse Good

These are all possible, but none of them are pass by value. Just think of ofMambrinoas being the address of the beginning of the array, and that is what you are passing.

这些都是可能的,但没有一个是按值传递的。只需将其ofMambrino视为数组开头的地址,这就是您要传递的地址。

void pass (GoldenHelmet ofMambrino[], int size)
void pass (GoldenHelmet ofMambrino[10], int size)
void pass (GoldenHelmet *ofMambrino, int size)
void pass (GoldenHelmet (&ofMambrino)[10], int size)

回答by dasblinkenlight

Arrays are represented and passed as pointers, so you are not copying anything here. In contrast, if you were passing a singlestruct, it would be passed by value.

数组以指针形式表示和传递,因此您不会在此处复制任何内容。相反,如果您传递的是单个struct,则它将按值传递。

Below is a code snippet to illustrate this last point:

下面是一个代码片段来说明最后一点:

void passByVal (GoldenHelmet ofMambrino) {
    ofMambrino.foo = 100;
    ofMambrino.bar = "Blargh";
}

void passByRef (GoldenHelmet& ofMambrino) {
    ofMambrino.foo = 100;
    ofMambrino.bar = "Blargh";
}

int main() {
    GoldenHelmet h;
    passByVal(h); // h does not change
    passByRef(h); // fields of h get assigned in the call
}

回答by Cemal Inanc

First of all array is not pointers. We refer this as a pointer in the argument list because when we use

首先数组不是指针。我们将其称为参数列表中的指针,因为当我们使用

int x[ ]

x is actually const pointer that points the beginning of the array. And when you pass this to a function you send the adress of the memory that is beginning of the array. Thats why when you make a change in your function, you make change in the adress of your variable in the caller section actually. This is actualy simulated call by reference not call by reference. But effect is same with call by reference because you are working on memory locations. For this reason when you send array of your struct you pass actually adress of your array of structs. Thats why when you change value on this, you actually change your structs.

x 实际上是指向数组开头的常量指针。当你把它传递给一个函数时,你会发送数组开头的内存地址。这就是为什么当您对函数进行更改时,实际上会更改调用者部分中变量的地址。这实际上是通过引用模拟调用而不是通过引用调用。但效果与按引用调用相同,因为您正在处理内存位置。因此,当您发送结构数组时,实际上传递的是结构数组的地址。这就是为什么当你改变这个值时,你实际上改变了你的结构。

To use call by reference, one thing you must to do is to define your function prototype like

要使用按引用调用,您必须做的一件事是定义您的函数原型,例如

void f(int &param)

and when calling function, it is same with the others.

调用函数时,与其他函数相同。

To summarize:

总结一下:

int main()
{
     int x;

     // simulated call by reference that use adress of variable, 
     // lets say adress of x is 19ff 
     f(&x);     // actually you send 19ff

     f(x);      // call by reference that use reference of variable

}

// simulated call by reference
void f(const int *y)
{
    // when you use like *y=10, you are writing on memory area 19ff, you actually 
    // change memory area that is belong to x in the main

}

// call by reference
void f(const int &y)
{
}