我是C ++ stdlib的初学者。我学习了stdlib教程,并使用stdlib列表创建的邻接列表实现了“Graph中连接组件的数量”。我想知道如何通过引用dfs
函数传递这个列表数组?另外,我的一个朋友说,默认情况下它将通过引用传递。这是真的吗?请澄清。哪一个是对的?
例如:
list<int> L[v];
dfs(L[v],k);
void dfs(list<int> List, int index);
void dfs(list<int> L, int);
(或)
list<int> L[v];
dfs(L,k);
void dfs(list<int> *L, int index);
void dfs(list<int> *, int);
答案 0 :(得分:2)
我想知道如何通过引用dfs函数传递这个列表数组?另外,我的一个朋友说,默认情况下它将通过引用传递。
不完全。
首先,让我们忘记std::list
;这只是令人困惑的问题。
假装您正在传递int
数组:
void foo(int[] x);
int main() {
int x[5];
foo(x);
}
这里没有引用,默认情况下C ++参数是复制,但是因为数组无法复制,并且因为数组的名称衰减为指向第一个元素的指针的名称你正在传递一个[副本] 指针而不是数组本身。
事实上,void foo(int[] x)
对于等效的void foo(int* x)
来说是误导性的句法糖。
特别注意 - 在两个情况下 - 函数foo
不知道原始数组的维度。
这是一种老式的,你可以传递对数组的实际引用:
void foo(int (&x)[5]);
int main() {
int x[5];
foo(x);
}
现在我们可以将同样的逻辑应用于std::list
:
void foo(std::list<int>*); // pointer to one or more lists, OR
void foo(std::list<int> (&)[5]); // reference to an array of five lists
无论如何,混合标准容器和阵列似乎很奇怪;如果由于某种原因确实需要自动存储持续时间,则首选数组std::vector
或静态分配数组的包装(如std::array
或之前的boost::array
)。
另外,您的调用语法错误。
我的函数调用:dfs(L [v],k); 我的函数定义:void dfs(list List,int index);
这会从列表数组中传递单个列表,并通过值/复制进行传递。
答案 1 :(得分:1)
要通过引用传递,请使用&
:
void dfs(const vector< list<int> >& L, int index);
// ...
vector< list<int> > L(v);
dfs(L, k);
非内置类型的对象通常通过引用传递给const以避免复制。传递值是所有类型的默认值,您必须明确指定引用语义。请注意,我使用了vector
而不是C数组,这通常是首选。
答案 2 :(得分:1)
假设您有一个实际的列表数组:
std::list<int> matrix[N];
要将整个数组传递给函数,您可以执行以下两项操作之一。 C方式是将指针传递给第一个元素以及数组的大小:
return_type
dfs( std::list<int> const * array, std::size_t size, int key ); // signature
dfs( matrix, N, k ); // caller
C ++方式......好吧,有不同的C ++方式。我建议不要使用数组,而是使用向量(因为我们在它,所以也将列表更改为向量):
return_type
dfs( std::vector< std::vector<int> > const & adj, int key ); // signature
std::vector< std::vector<int> > adj_list;
dfs( adj_list, k );
如果你真的想继续使用数组和列表并通过引用传递,那么语法将是:
const int N = 10;
return_type
dfs( std::list<int> (&adj)[N], int k );
std::list<int> adj_list[N];
dfs( adj_list, k );
请注意,在这种情况下,数组N
的大小在编译时是固定的(通过使用模板可以使其更通用,但它仍将在编译时解析)。
我建议您将数据结构重新设计为矢量矢量。
答案 3 :(得分:-1)
如果您的列表数组声明如下:
list<int> L[v];
然后通过引用传递的正确方法是:
void dfs(list<int> & L, int index);
您的函数调用将如下所示:
dfs(L[v], k);
答案 4 :(得分:-1)
仅供参考,C ++中的默认值是pass-by-copy / value。
让我们调整您的代码以使用传统的传递引用方法:
list<int> L[v];
dfs(L,k);
void dfs(list<int>& L, int index);
void dfs(list<int>& , int);
当然,&
可以放在参数类型或参数名称附近。
此方法基本上传递指针。在执行list<int>* L
时,您将获得的指针不同。这就是为什么它被引用引用。
在dfs(list<int>& L, int index)
内,您将使用/访问L
,就像它是常规变量一样。
我认为this blog帖子解释得很好。