如何将向量传递给函数参数(我需要指针吗?)
Posted
技术标签:
【中文标题】如何将向量传递给函数参数(我需要指针吗?)【英文标题】:How to pass a vector into a function parameter (do I need pointers?) 【发布时间】:2020-01-30 13:28:17 【问题描述】:当我们将向量传递给函数时,为什么我们不能像数组一样来做呢?
例如:
#include<bits/stdc++.h>
using namespace std;
void func(vector<int> vect)
vect.push_back(30);
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(vect);
for (int i = 0; i<vect.size(); i++)
cout << vect[i] << " ";
return 0;
在这个例子中,它运行良好。 但如果我这样做,为什么它不能像数组一样工作?
#include<bits/stdc++.h>
using namespace std;
void func(vector<int> *vect)
vect.push_back(30);
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(&vect[0]);
for (int i = 0; i<vect.size(); i++)
cout << vect[i] << " ";
return 0;
就像一个数组,为什么这不可能?
【问题讨论】:
编译器可能不太关心空白,但其他人会。请注意格式化您的代码以提高可读性,以便其他用户更容易理解您共享的代码。 您不能在代码中添加随机符号并期望它能够正常工作。任何good C++ book 都会解释什么是指针以及它是如何工作的。 数组很奇怪。该语言中没有其他东西可以像数组一样工作。 善意的建议:不要试图通过猜测事物的工作原理来学习 C++。std::vector
不是 c 数组,所以它的行为不同应该不会太令人惊讶
@AbhiSarkar #include <vector> #include <iostream>
-- 这需要很多时间吗?
【参考方案1】:
vect[0]
命名为 int
,而不是 std::vector<int>
。
&vect[0]
是 int *
,而不是 std::vector<int> *
。您不能使用 int *
调用期望 std::vector<int> *
的函数
您需要学习参考资料。
void func(vector<int> & vect) // use an existing std::vector<int>
vect.push_back(30);
【讨论】:
@foreknownas_463035818(假设 vect 非空),vect[0]
引用的某处有一个 int
。我在口语中使用“名称”
好吧,我没有注意到“names”和“is a”之间的细微差别,但它完全有道理【参考方案2】:
在这个函数调用中
func(&vect[0]);
实参表达式的类型为int *
,而函数参数的类型为std::vector<int> *
void func(vector<int> *vect)
并且没有从一种类型到另一种类型的隐式转换。
本质上,std::vector 类型的对象已经是一个封装在类中的指针。因此,通过引用传递 std::vector 类型的对象实际上同时传递了一个指向该向量内部指向的已分配数组的指针。
请注意,在您的问题中提供的第一个程序中,您正在按值传递向量 vect。
void func(vector<int> vect)
vect.push_back(30);
所以函数不会改变传递给函数的原始对象。如果要更改原始对象,则函数参数应具有引用类型,例如
void func(vector<int> &vect)
vect.push_back(30);
对于 C++ 17 中的标准类 std::string
进行了类似的操作。它是类 std::string_view
。您可以像处理数组一样将指针传递给 std::string 类型的对象的第一个元素。但是还需要传递指针所指向的字符数组的长度。
这是一个演示程序。
#include <iostream>
#include <string>
#include <string_view>
void func( std::string_view s )
std::string reversed_string( s.rbegin(), s .rend() );
std::cout << reversed_string << '\n';
int main()
std::string s( "Hello" );
func( &s[0], s.size() );
它的输出是
olleH
【讨论】:
非常好的教程。【参考方案3】:这很有可能,但是您传递的是向量的一个元素,而不是向量本身:
void func(vector<int> *vect)
vect->push_back(30); // <-- pointer type expression
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(&vect); // <-- pass the vector
for (size_t i = 0; i < vect.size(); i++) // <-- iterator should be size_t type
cout << vect[i] << " ";
return 0;
如果您想传递对向量元素的引用,您也可以这样做,请注意,该元素必须已经存在:
void func(int *vect_elem) //<-- pointer to int parameter
*vect_elem = 30; // <-- assign 30 to the vector element
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(&vect[0]); //<-- reference an existing element of the vector
for (size_t i = 0; i<vect.size(); i++)
cout << vect[i] << " ";
return 0;
在这种特殊情况下,您不需要指针,更好的选择是只使用引用,就像已经提到的那样,因为您不需要任何解除引用:
void func(vector<int> &vect) //<-- parameter reference
vect.push_back(30);
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(vect); // <-- pass the vector
for (size_t i = 0; i < vect.size(); i++)
cout << vect[i] << " ";
return 0;
void func(int &vect_elem) //<-- parameter reference
vect_elem = 30;
int main()
vector<int> vect;
vect.push_back(10);
vect.push_back(20);
func(vect[0]); //<-- pass the element
for (size_t i = 0; i<vect.size(); i++)
cout << vect[i] << " ";
return 0;
【讨论】:
@anastaclu 我想知道 &vec 和 &vec[0] 彼此不同或相同。 @AbhiSarkar&vec
是对向量的引用,这意味着您正在传递向量的地址,它允许您更改向量的所有元素,以及删除或添加元素, &vec[0]
,这里您传递的是对向量元素的引用,在这种情况下是第一个元素,这意味着您只能更改该元素的值,而不能更改向量本身。以上是关于如何将向量传递给函数参数(我需要指针吗?)的主要内容,如果未能解决你的问题,请参考以下文章