在C++中通过引用传递一个结构体数组
所以我对编程/ C++还是比较陌生,仍然试图围绕着指针并通过引用和所有事物传递。我试图找出一个程序现在需要将一个结构数组传递给另一个函数。我只是直接将数组传递给了它。它似乎工作正常。然而,我所关心的是我相信我是通过价值传递它的,并且我明白最好通过引用来传递结构,所以你不会每次都复制一个结构体......在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()函数?我试图通过引用来传递它,但它似乎并不想以我尝试过的任何方式工作。
这句法:
void pass (GoldenHelmet ofMambrino[], int size)
其实相当混乱。因为你没有传递一个数组,所以你正在传递一个指针。尽管如此,他们不是一回事,不要感到困惑。这种古怪只适用于功能参数。以上内容与此完全相同:
void pass (GoldenHelmet * ofMambrino, int size)
实际上不可能通过值传递数组,除非它是另一个对象的子对象。您可以通过引用传递,你需要,虽然有大小,但你可以做到这一点使用模板:
template<int N>
void pass (GoldenHelmet (&ofMambrino)[N])
为什么我们需要一个模板? 'void pass(GoldenHelmet(&h)[10])'有什么问题? – 2012-01-10 04:19:06
@Kerrek:我没有说你需要一个模板。我说过“你需要包括尺寸,但你可以使用模板来做到这一点”。你选择了明确它的大小,我选择了使用模板。 – 2012-01-10 04:22:00
@Benjamin谢谢,这开始变得更有意义。所以如果我传递一个指针而不是整个数组,我真的需要担心通过引用传递它吗?如果我只是单纯地传递一个结构体,我可以看到通过引用传递的好处。但是如果我只是传递指针,他们真的对传递引用有任何好处? – Nate 2012-01-10 04:23:01
数组表示并作为指针传递,因此您不在此处复制任何内容。相反,如果您通过单一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
}
的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;
// ...
}
事实上,我们通过引用传递数组。
这些都是可能的,但他们都不是按值传递。试想一下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)
完美,这清理了很多。它也解释了为什么我需要传递大小,因为如果我只是指向数组开头的地址,我需要跟踪数组的长度。 – Nate 2012-01-10 04:31:33
@Nate:的确,当我第一次开始学习时,我总是想知道为什么没人告诉我“它只是地址”。 – 2012-01-10 04:39:23
首先数组不是指针。我们将其作为参数列表中的指针,因为当我们使用
int x[ ]
x实际上是指向数组的开始的常量指针。当你将这个传递给一个函数时,你发送了数组开头的内存的地址。这就是为什么当你改变你的函数时,你实际上在调用者部分的变量的地址上做了改变。这是真实的模拟呼叫,不作参考。但是,由于您正在处理内存位置,所以效果与通过引用的调用相同。出于这个原因,当你发送你的结构数组时,你实际上传递了你的结构数组的地址。这就是为什么当你改变这个价值时,你实际上改变了你的结构。
要参照使用电话,有一件事你必须做的是确定样
void f(int ¶m)
和调用函数时,它一样的是他人的函数原型。
总结:
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)
{
}
数组不是指针。重复这个过程直到你晕倒,然后回到这个网站去阅读当时发布的答案。 – 2012-01-10 04:13:38
@NiklasBaumstark不,答案将在C++ :) – dasblinkenlight 2012-01-10 04:14:07
@Kerrek SB谢谢澄清。我正在阅读[这篇文章](http://forums.devshed.com/c-programming-42/how-to-passing-arrays-of-structures-61159.html),它似乎暗示着数组是指针。我想我需要继续关注它。无论如何,现在要阅读回复,感谢大家的帮助。 – Nate 2012-01-10 04:20:01