C++ 访问元素
示例
访问元素中的元素有两种主要方法std::vector
基于索引的访问
迭代器
基于索引的访问:
这可以通过下标运算符[]或成员函数来完成at()。
两者均会返回对元素中相应位置的引用std::vector(除非是vector<bool>),以便可以读取和修改该元素(如果向量不是const)。
[]和at()不同之处在于,[]它不能保证同时执行任何边界检查at()。访问元素index<0或index>=size为时未定义行为的元素[],而at()抛出std::out_of_range异常。
注意:为了清楚起见,以下示例使用C++11样式的初始化,但是运算符可用于所有版本(除非标记为C++11)。
std::vector<int> v{ 1, 2, 3 };//使用[]
int a = v[1]; //一个是2
v[1] = 4; //v现在包含{1,4,3}
//使用at()
int b = v.at(2); //b是3
v.at(2) = 5; //v现在包含{1,4,5}
int c = v.at(3); //引发std::out_of_range异常由于该at()方法执行边界检查并可能引发异常,因此它比慢[]。这将成为[]首选代码,在该代码中,操作的语义可确保索引处于范围内。在任何情况下,对向量元素的访问都在固定时间内完成。这意味着访问向量的第一个元素的时间(时间)与访问第二个元素,第三个元素等的代价相同。
例如,考虑此循环
for (std::size_t i = 0; i < v.size(); ++i) {
v[i] = 1;
}在这里,我们知道index变量i始终处于界限内,因此i对于每次调用都检查界限是否在CPU周期内是浪费的operator[]。
的front()和back()成员函数允许向量的第一和最后一个元素容易参考存取,分别。这些位置是经常使用的,特殊访问器比使用[]以下方法的替代方法更具可读性:
std::vector<int> v{ 4, 5, 6 }; //在C++11之前的版本中,这比较冗长
int a = v.front(); //a为4,v.front()等同于v[0]
v.front() = 3; //v现在包含{3,5,6}
int b = v.back(); //b为6,v.back()等同于v[v.size()-1]
v.back() = 7; //v现在包含{3,5,7}注意:调用front()或back()在空向量上是未定义的行为。您需要empty()在调用front()或之前使用成员函数(用于检查容器是否为空)检查容器是否为空back()。以下是使用'empty()'测试空向量的简单示例:
int main ()
{
std::vector<int> v;
int sum (0);
for (int i=1;i<=10;i++) v.push_back(i);//创建并初始化向量
while (!v.empty())//循环直到向量测试为空
{
sum += v.back();//保持连续运行
v.pop_back();//弹出将其从向量中删除的元素
}
std::cout << "total: " << sum << '\n';//将总数输出给用户
return 0;
}上面的示例创建了一个向量,该向量的序列从1到10。然后弹出向量的元素,直到向量为空(使用'empty()')以防止未定义的行为。然后计算向量中数字的总和并显示给用户。
该data()方法返回一个指针,该指针指向用来std::vector内部存储其元素的原始内存。在将向量数据传递给期望使用C样式数组的旧代码时,通常使用此方法。
std::vector<int> v{ 1, 2, 3, 4 }; //v包含{1、2、3、4}
int* p = v.data(); //p指向1
*p = 4; //v现在包含{4,2,3,4}
++p; //p指向2
*p = 3; //v现在包含{4,3,3,4}
p[1] = 2; //v现在包含{4,3,2,4}
*(p + 2) = 1; //v现在包含{4,3,2,1}