认识、使用C++vector和array

简介: 认识、使用C++vector和array

前言:


 指针的基础用法分了近三篇文章,结合数组、结构、共用体、字符串一起学习。相信读者已经掌握了指针的基本知识,我们来补充一下在涉及指针第一篇内容里提到的,在C++中,用vector和array模板替代数组的使用。


1.vector模板

1.1vector简介

 vector模板类是在C++98新增的标准模板库(STL)提供的,它是动态数组的替代品(new typename[element];)。既然和动态数组有关,所以用vector模板类创建数据对象的时候,最后要记得使用数组格式释放掉相应的自由存储空间(堆区)。接下来我们来讲如何创建vector对象。


1.2创建vector类对象


 首先,使用vector模板要使用头文件vector,vector的名称空间在std里面,使用编译指令using就可以啦,需要声明的声明好后,就可以使用vetor创建对象。


 vi,vt,这里并不是英语里的不及物和及物动词的意思,碰巧这么起而已(doge)。vi是一个vector<int>的对象。这句话可以这样理解,vector是类,用类创建的对象,是什么样的?vector<int>样的,就像char ch;用char创建一个ch对象一样,只是char是基本类型,我们更常说,ch是一个char类型的变量。


 由于vector对象的大小可以根据我们的输入自动调整,所以可以在声明的时候,不指定数组的元素个数是可以的。而用静态联编创建数组int arr[元素个数];的时候,元素个数不能给0。



2.array模板

2.1array简介

 array是在C++11中新增加的,如果想使用长度固定的数组,使用array是一个更好的选择。vector的效率相比于数组是稍低的。我们说C、C++在数组进行访问的时候,对索引值不敏感,也就是可能超出数组的范围越界访问了而不报错。为了寻求功能更强大,更安全的长度固定的数组,我们引进了array类。


2.2创建array类对象

 

一样的,需要引用头文件为<array>才能使用array模板,名称空间位于std。


 因为array是在C++11新增的,此时C++将使用列表初始化成为通用的一种方法,而在C98下vector对象不能使用列表初始化。


3.比较中学习


 我们使用数组创建了arr1,vector创建了arr2,array创建了arr3、arr4。


 vector对象不能被初始化,通过数组表示法来赋值,我们可以把vector创建的对象arr2当成一个数组,用数组表示法来使用,array对象也一样可以用。


 arr4 = arr3;当数组元素一样,个数相同时,array类的对象是可以相互赋值的。我们看到打印arr4[2] = 3.14内容,可以记得更深刻一些。


 arr1的地址是0x008FF780,arr2的地址是0x00ACF758。这两个地址相差很大,这是因为,arr1数组是在栈区内存上的,vector是在堆区(动态数组替代品,动态开辟的空间在堆区)内存上的。我们只需要知道,栈区和堆区是内存中两块相对独立的内存块,地址相差很大就可以了。


 补充:堆区也叫内存池。


 而arr1与arr3、arr4相差不大,甚至可以看到arr3、arr4两者几近是靠在一起创建的,当然也不是连续的,只是比较起arr2很近。这是因为array创建的数组,也和arr1性质上也是相同的,固定长度的数组,局部,所以都是在栈区上开辟空间。


 看到arr1[-1],相信大部分读者都反应过来说,数组arr1越界访问了。是的,我们看到右边窗口说代码退出是3,这是异常退出的意思,3是个错误代码信息的编号,代码退出0才是正常的。我们主要不是想讨论这个,而是说,结果是不是还是跑出来了?arr1[2]的地址是0x00FF780,arr[-1]是*(arr1-1)的意思,它们相差三个元素的位置,每个元素是double类型,算下来恰是地址0x8FF768。这里想告诉大家的是,C、C++没有检索下标使用有效性的这个保护机制,如果有编译器它都不让你跑起来,而这里是跑完再报错,但内容还是被改了。


4.怎么避免数组越界访问

 第一:足够细心。第二:让代码健壮一点。


 人难免会不经意的写出一个bug,所以为了保护好代码,适当加入写监督的机制。这里讲的是对C++中的vector类和array类使用at成员函数,来是程序在运行的时候,捕获非法索引的情况,程序默认中断。


 使用的例子:array<int, 5> arr1;  arr1.at(5);

 读者可能会问,那和前面报错有什么区别,我一样找不出原因呀,请注意,C和C++没有捕获这种索引值越界的。在一个工程中,当我们越界访问的时候,没有报错,且没有终止(但一般都会),最后输出一个奇怪的结果,试问几万行里的代码,要怎么找bug。不过介于博主知识有限,可能这个at成员报错会有提示在第几行呀,或者是我们自己添加一些可以快速定位到位置等等。大家知道这么一回事就可以啦,在日后的学习中,懂得更多!


 还有一点就是,使用at()的代价是需要额外的时间去让编译器检查,这也是C和C++允许我们使用任何一个索引值的原因所在。另外这些类还有成员函数,begin()、end()。让我们确定开头和结尾这个边界,以免超过这个范围。这里就不细说啦,认识认识。


 好啦,到这就讲完了,希望读者读完有所收获。


 如果本文有内容、排版上的错误,请在下边评论区留言哈。求点赞,求点赞,求点赞!你的点赞是我更新的动力~

相关文章
|
21天前
|
C++
c++的学习之路:13、vector(2)
c++的学习之路:13、vector(2)
24 0
|
2月前
|
编译器 C++
C++:vector增删查改模拟实现
C++:vector增删查改模拟实现
56 0
|
2月前
|
存储 C++ 容器
【C++】vector的底层剖析以及模拟实现
【C++】vector的底层剖析以及模拟实现
|
2月前
|
编译器 C++ 容器
【C++练级之路】【Lv.7】【STL】vector类的模拟实现
【C++练级之路】【Lv.7】【STL】vector类的模拟实现
|
2月前
|
存储 算法 测试技术
C++:Vector的使用
C++:Vector的使用
|
2月前
|
存储 算法 C++
【C/C++ Vector容量调整】理解C++ Vector:Reserve与Resize的区别与应用
【C/C++ Vector容量调整】理解C++ Vector:Reserve与Resize的区别与应用
68 1
|
5天前
|
编译器 C++ Windows
【C++】vector问题解决(非法的间接寻址,迭代器失效 , memcpy拷贝问题)
不使用memcpy函数不就可以了,然后我们使用简单粗暴的赋值拷贝,这样就不会发生浅拷贝问题了!!!
15 1
|
7天前
|
算法 C++ 容器
【C++/STL】vector(常见接口、模拟实现、迭代器失效)
【C++/STL】vector(常见接口、模拟实现、迭代器失效)
10 0
|
20天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
|
20天前
|
编译器 C++
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析