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

Passing an array of structs by reference in C++

本文关键字:一个 数组 结构 C++ 引用      更新时间:2023-10-16

所以我对编程/C++还是很陌生的,我仍然在努力理解指针和通过引用传递等等。我正在试图弄清楚的一个程序现在需要将一个结构数组传递给另一个函数。我只是把数组直接传递到那里,就可以让它工作了。它似乎运行良好。然而,我担心的是,我相信我是按值传递的,而且我知道通过引用传递结构体更好,所以你不会每次都复制结构体。。。

总之,这里有一个我正在做的基本示例:

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";
}

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

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;
   // ...
}

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

此语法:

void pass (GoldenHelmet ofMambrino[], int size)

实际上相当令人困惑。因为您不是在传递数组,而是在传递指针。不过,它们不是一回事,不要混淆。这种奇怪现象只适用于函数参数。以上内容与此完全相同:

void pass (GoldenHelmet * ofMambrino, int size)

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

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

这些都是可能的,但没有一个是按值传递的。只需将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)

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

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

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
}

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

int x[ ]

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

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

void f(int &param)

调用函数时,和其他函数一样。

总结:

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)
{
}
相关文章: