我正在使用C++编程。如果我有一个函数void foo(vector<int> test)
并在程序中调用它,那么这个向量会被按值传递还是按引用传递?我不确定,因为我知道向量和数组很相似,而像void bar(int test[])
这样的函数会按引用(指针?)而不是按值传递test变量。我的猜测是,如果我想避免按值传递,则需要显式地通过指针/引用传递向量,但我不确定。
我正在使用C++编程。如果我有一个函数void foo(vector<int> test)
并在程序中调用它,那么这个向量会被按值传递还是按引用传递?我不确定,因为我知道向量和数组很相似,而像void bar(int test[])
这样的函数会按引用(指针?)而不是按值传递test变量。我的猜测是,如果我想避免按值传递,则需要显式地通过指针/引用传递向量,但我不确定。
在C++中,除非你使用&
运算符指定,否则东西都是按值传递的(请注意,该运算符也用作“取地址”运算符,但在不同的上下文中)。这一点已经有充分的文档说明,但我仍然要再次强调:
void foo(vector<int> bar); // by value
void foo(vector<int> &bar); // by reference (non-const, so modifiable inside foo)
void foo(vector<int> const &bar); // by const-reference
你也可以选择传递指向 vector 的指针 (void foo(vector<int> *bar)
),但除非你知道自己在做什么并且确定这是正确的方法,否则不要这样做。
另外,vector 和数组是不同的!内部,vector 跟踪一个数组,处理了其内存管理,但许多其他 STL 容器也有类似功能。你不能将 vector 传递给期望指针或数组的函数,反之亦然(但你可以获取底层数组的指针并使用它)。vector 是通过其成员函数提供很多功能的类,而指针和数组是内置类型。此外,vector 是动态分配的(这意味着大小可能在运行时确定和更改),而 C 风格的数组是静态分配的(其大小是固定的,必须在编译时知道),这限制了它们的使用。
我建议你先阅读一些关于 C++ 的一般知识(特别是关于数组衰减的知识),然后看以下程序,它说明了数组和指针之间的区别:
void foo1(int *arr) { cout << sizeof(arr) << '\n'; }
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; }
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; }
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; }
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foo1(arr);
foo2(arr);
foo3(arr);
foo4(arr);
}
foo3
行为背后的目的/思路是什么?在编译时已知数组大小的情况下,为什么需要进行衰减? - QuaternionsRockfoo1
、foo2
和foo3
是100%等价的。在这三个函数中,参数arr
都是指针类型。在foo2
和foo3
中声明看起来像数组以及"数组大小"的事实完全被忽略了。这是从C
继承下来的怪癖。 - bolovvector
在功能上和一个数组相同。但是,对于语言来说,vector
是一种类型,而 int
也是一种类型。对于函数参数,任何类型的数组(包括 vector[]
)都被视为指针。vector<int>
与 int[]
不同(对于编译器来说)。vector<int>
不是数组、引用或指针,它是按值传递的,因此会调用复制构造函数。
因此,您必须使用 vector<int>&
(最好加上 const
,如果函数不修改它)作为引用来传递它。
void foo(vector<int> test)
在这里,vector是按值传递的。
根据上下文,还有更多可以传递vector的方式:
1) 引用传递:这将允许函数foo更改vector的内容。与按值传递相比更有效率,因为避免了复制vector。
2) 常量引用传递:当您不希望函数更改向量的内容时,这既有效又可靠。