C++基础第3章:数组、vector与字符串(3)——vector、string

1.std::vector

在这里插入图片描述

1.1.是C++标准库中的一个类模板

也就是说,std::vector首先是一个类,其次是一个模板类,也就是传入不同的模板参数,可以得到不同的类。

1.2.与内建数组相比更侧重于易用性

C/C++为了性能考虑对内建数组的很多行为进行了限制,比如不允许数组的复制。而vector为了易用性牺牲了一部分性能,允许复制。其次vector可以在运行期间改变元素个数,这个对于内建数组是不支持的,内建数组的大小在编译期间就确定了。

int a[3];   // 编译期间确定内建数组大小
std::vector<int> b;   // 没有初始化,那么默认b的大小是0,也就是里面没有任何元素,此时是不能访问b的!

// 数组不允许复制,vector允许
int a1[3] = a;   // 错误
std::vector<int> b1 = b;  // 正确,允许复制

1.3.构造与初始化

  1. 聚合初始化:因为在语言的发展过程中是先出现了内建数组,后来出现了vector,因此为了保证和内建数组一些特性相同,有聚合初始化的方式。
int a[3] = {1, 2, 3};
std::vector<int> b = {1, 2, 3};
std::vector<int> c{1, 2, 3};// 等价于std::vector<int> c = {1, 2, 3};
  1. 其他初始化方式
  • 缺省初始化:vector是一个模板类,使用默认构造函数就是缺省初始化,此时数组中元素个数是0,此时不能访问数组中的元素,否则会导致内存错误!
  • 初始化元素个数:使用std::vector<int> b(3)这种方式,即在()中写入要初始化的数组元素个数。此时数组中的所有元素会被初始化成默认值,如果是int类型那么会被初始化成0.
  • 同时初始化元素个数和默认值:使用std::vector<int> b(3, 1),此时元素个数是3,每个元素的默认值都是1.
  • 注意 :注意区分简写的聚合初始化(使用{}构造) 与 同时初始化元素个数和默认值(使用()构造) 的区别!
// 1.缺省,数组大小是0,此时不能访问!
std::vector<int> a;    
// 2.初始化元素个数,此时元素会被初始化成默认值
std::vector<int> b(3);
// 3. 同时初始化元素个数和默认值
std::vector<int> c(3, 1);     // 3个元素,都是1
// 注意和聚合初始化的简写方式区分!
std::vector<int> d{3, 1};     // 两个元素,分别是3和1

1.4.其他方法

  • 获取元素个数size,判断是否为空empty
  • 插入删除元素push_backpop_back
  • vector比较:= <等,就是逐个比较每个元素的大小

1.5.元素的索引与遍历

在这里插入图片描述

  1. 使用[]索引和使用at方法:二者的区别是使用[]和数组一样,可能会存在访问越界的错误,但是这个错误在编译期间是不会被发现的,只有运行期间会报错内存访问错误。而at方法加入了内存检测机制,在运行期间报错的时候,会明确指出来你所索引的范围超过了vector的size,这样对程序来说更加友好。
std::vector<int> a(3);
std::cout << a[20];     // 报错提示不明显
std::cout << a.at(20);   // 报错明确提示是因为索引超过了vector的size
  1. 使用std::begin(x)/std::end(x)获得首位迭代器,或者使用内建的begin()/end()方法获得首位迭代器访问元素。注意,这里得到的是迭代器,而如果是内建数组的话,得到的就是指向数组起止位置的指针。

1.6.迭代器

  • 模拟指针的行为
  • 包含多种类别的迭代器,每种类别的迭代器支持的操作不同。
  • 比如vector对应的是随机访问类型的迭代器,支持的操作如下:
    (1)解引用与下标访问:与数组类似
    (2)移动
    (3)两个迭代器相减求距离
    (4)两个迭代器比较大小
std::vector<int> a = {1, 2, 3};
auto begin = a.begin();
auto end = a.end();

*begin;     // 解引用
begin[0];   // 访问第0个元素
end - begin;    // 得到vector的长度

1.7.vector相关的其他内容

在这里插入图片描述

  1. 在vector中添加元素可能使迭代器失效,如下代码假设在for循环中修改了vector,那么起止迭代器可能失效。
std::vector<int> a = {1, 2, 3};
auto begin = a.begin();
auto end = a.end();

for(; begin != end; begin++)
{
	a.push_back(4);
}

类似可能是迭代器失效的函数还有:
在这里插入图片描述

  1. 多维vector
// 多维vector,定义比内建数组要复杂一些
std::vector<std::vector<int>> x;
x.push_back(vector<int>());
x[0].push_back(1);
std::cout << x[0][0];

// 优势:可以让每个vecotr的维度不相等
std::vectro<std::vector<int>> x = {{1, 2, 3}, {1, 2}}; 

2.std::string

在这里插入图片描述

疑问 :为什么std::cout << ptr会直接输出这个指针的内容?不应该写成std::cout << *ptr吗?这个问题在前面讲使用指针对内建数组的外部声明的时候就提到过,这里又出现了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值