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;
全部评论

相关推荐

点赞 收藏 评论
分享
正在热议
# 牛客帮帮团来啦!有问必答 #
1151163次浏览 17148人参与
# 通信和硬件还有转码的必要吗 #
11193次浏览 101人参与
# 不去互联网可以去金融科技 #
20333次浏览 255人参与
# 和牛牛一起刷题打卡 #
18888次浏览 1635人参与
# 实习与准备秋招该如何平衡 #
203348次浏览 3625人参与
# 大厂无回复,继续等待还是奔赴小厂 #
4970次浏览 30人参与
# OPPO开奖 #
19192次浏览 267人参与
# 通信硬件薪资爆料 #
265877次浏览 2484人参与
# 国企是理工四大天坑的最好选择吗 #
2220次浏览 34人参与
# 互联网公司评价 #
97668次浏览 1280人参与
# 简历无回复,你会继续海投还是优化再投? #
25034次浏览 354人参与
# 0offer是寒冬太冷还是我太菜 #
454815次浏览 5124人参与
# 国企和大厂硬件兄弟怎么选? #
53895次浏览 1012人参与
# 参加过提前批的机械人,你们还参加秋招么 #
14635次浏览 349人参与
# 硬件人的简历怎么写 #
82284次浏览 852人参与
# 面试被问第一学历差时该怎么回答 #
19393次浏览 213人参与
# 你见过最离谱的招聘要求是什么? #
28057次浏览 248人参与
# 学历对求职的影响 #
161224次浏览 1804人参与
# 你收到了团子的OC了吗 #
538669次浏览 6386人参与
# 你已经投递多少份简历了 #
344169次浏览 4963人参与
# 实习生应该准时下班吗 #
96965次浏览 722人参与
# 听劝,我这个简历该怎么改? #
63517次浏览 622人参与
牛客网
牛客企业服务