C++基础: vector 容器及其遍历与越界问题

主要参考: 遍历的几种方式及性能对比; 一个非常隐蔽的越界错误



vector类称作向量类, 它实现了动态的数组, 用于元素数量变化的对象数组. 索引下标从0开始, 元素个数可以动态变化.

构造函数与初始化

  • vector() 空向量
  • vector(int nSize) 声明元素个数
  • vector(int nSize, const T& t) 声明元素个数, 且值均为t。
  • vector<T> a 声明元素类型为模板类T
  • vector(const vector&) 复制构造函数。
vector<int> a;
vector<int> a(5);
vector<int> a(5, 0);
vector<int> b(a);

增加与删除函数

  • a.push_back(const T& t)) 末尾追加元素
  • a.pop_back() 删除末尾元素
  • a.clear() 清空所有元素
  • a.inset 插入
  • a.erase 删除
a.push_back(10);
a.push_back(20);
a.push_back(30);    // [10, 20, 30]

a.pop_back();       // [10, 20]

auto index1 = find(a.begin(), a.end(), 20);
a.insert(index1, 0); // [10, 0, 20]

vector<int> ::iterator index2 = find(a.begin(), a.end(), 20);
a.erase(index2);     // [10, 0]

a.clear();

索引与遍历

  • a.at(int index) 索引index位置(引用)
  • a.front() 首元素的引用
  • a.back() 尾元素的引用
  • a.begin() 指向首元素的指针
  • a.end() 指向末尾的指针, 并不是尾元素
  • a.rbegin() 反向迭代器的起始指针
  • a.rend() 反向迭代器的终止指针

索引

vector<int> a(3, 0);            // [0, 0, 0]

a.front() = 10;
a.at(1) = 20;
a.back() = 30;                  // [10, 20, 30]

迭代器遍历

  • 正向:
auto iter1 = a.begin();
while(iter1 != a.end())
{
    *iter1 += 1;
    cout << *iter1 << ", ";     // [11, 21, 31]
    iter1++;
}
cout << endl;
  • 反向:
auto iter2 = a.rbegin();
while(iter2 != a.rend())
{
    *iter2 += 1;
    cout << *iter2 << ", ";     // [32, 22, 12]
    iter2++;
}
cout << endl;

下标遍历

for(int i = 0; i < a.size(); i++)
{
    a[i] += 1;
    cout << a[i] << ", ";       // [13, 23, 33]
}
cout << endl;

auto 输出

for(auto x : a)
{
    cout << x << ", ";          // [13, 23, 33], 对源数据无影响
}
cout << endl;

注: 三种遍历方法的Release实时运行差别很小, 同样高效. 点击访问参考博文

其他函数

  • a.empty() 判断是否为空
  • a.size() 返回元素的个数
  • a.capacity() 返回预分配内存中所能容纳的最多元素数 点击访问参考博文
  • a.max_size() 返回所能容纳的最多元素数
vector<int> a(5);                       
cout << a.size() << endl;           // 5 
cout << a.capacity() << endl;       // 5
cout << a.max_size() << endl;       // 1073741823

vector<int> b;
cout << b.size() << endl;           // 0
cout << b.capacity() << endl;       // 0
cout << b.max_size() << endl;       // 1073741823

越界问题

在这里插入图片描述

  • 下标越界,如本例的 a[5], 但程序Debug报错, Release不报错, 输出该地址中存储值. 点击访问参考博文
  • 隐蔽型越界, 如以下代码. 当size=0时, 减一操作是危险的. 因为a.size()是无符号整数,根据C++的规则表达式a.size()-1也是个无符号整数,而-1转成无符号数的值是4294967295, 显然越界, 应该避免使用a.size()-1. Java等语言没有无符号类型, 也就避免了这一问题. 点击访问参考博文
vector<int> a;
for(int i = 0; i <= a.size() - 1; i++)
{
    cout << a[i] << endl;
}

其他问题

  • static索引变量问题:
    在这里插入图片描述
    如图所示, 由于static变量只初始化一次, 有固定内存, 相当于全局变量, 所以并不能按照意图在每次调用函数时都被赋值为3, 只会在反复++, 最后造成越界. 应该改正为:
static int index;
index = 3;

猜你喜欢

转载自blog.csdn.net/Augurlee/article/details/103434626
今日推荐