前面我们讨论过怎么访问vector内容器,其实deque容器访问元素方法与前者一样非常相似,都可以通过'[]'、迭代器、以及back()和front()来访问元素,不同点在于deque没有data()指针也不支持函数模板get()<T>访问,学过的3种序列式容器里只有array容器支持。原因在于函数模板get()<T>访问元素要求容器在编译时固定数组序列,deque底层是多个固定大小的内存块,当内存不够时会申请新的内存块,通常是pow(2,9)个,即512个字节,所以不允许函数模板访问元素。。读者可以跳转《如何访问STL库中vector容器内的元素?》类比学习,归纳总结。
和普通数组一样,deque也重载了'[]'运算符,我们可以通过'[]'访问deque内的元素:
#include<bits/stdc++.h> #include<deque>//使用deque容器,需要包含deque头文件 /* 如何访问deque容器内元素 */ using namespace std; /*方法1:由于'[]'运算符重载实现下标访问*/ void test() { deque<int> dq{1,2,3,4,5}; for(int i=0;i<5;++i) { cout << dq[i] << " "; } cout << '\n'; } int main(){ test(); return 0; }
编译后成功访问deque内元素:
编译结果不出所料,通过'[]'我们能够访问所有元素,但是严格禁止数组越界行为,即访问未存在的下标。
deque容器提供了at()这个成员函数进行元素访问,由于at函数内的参数是元素下标,范围是[0,deque.size()-1],所以也不要访问越界!
#include<bits/stdc++.h> #include<deque>//使用deque容器,需要包含deque头文件 /* 如何访问deque容器内元素 */ using namespace std; /*方法2:通过成员函数at()实现下标访问*/ void test() { deque<int> dq{1,2,3,4,5}; for(int i=0;i<5;++i) { cout << dq.at(i) << " ";//通过at成员函数访问,不过会多一步判断越界语句 } cout << '\n'; } int main(){ test(); return 0; }
众所周知'[]'(因为它没有进行索引检查)访问速度非常快,既然可以通过'[]'访问元素了那么为什么会出现at这个成员函数呢?原因很简单,通过'[]'访问,如果数组越界,会造成程序崩溃,而你不知道是哪里问题,需要逐一排查。而我们的at()会提示你错误原因,比如此时我访问一个arr里面没有的元素:
#include<bits/stdc++.h> #include<deque>//使用deque容器,需要包含deque头文件 using namespace std; /*通过at访问未存在的下标,导致报错*/ void test() { deque<int> dq; cout << dq.at(10)<< '\n'; } int main(){ test(); return 0; }
会出现这么一个报错:
terminate called after throwing an instance of 'std::out_of_range'
what(): deque::_M_range_check: __n (which is 10)>= this->size() (which is 0)
它的意思是容器内没有元素,而你却想访问第10个元素,简直是痴心妄想。在访问deque容器内元素,这里建议读者使用at()而非'[]',因为at()会进行边界检查,在出现数组越界时cout提示错误,而'[]'越界会造成未定义行为,如果是庞大的系统就不知道如何寻错了,养成这样一个好习惯。不过,一名合格的程序员对边界访问问题慎之又慎,不会犯数组越界错误。
c++虽然提供了get<n>这个函数模板进行元素访问,但是不能访问deque容器,这里演示一下:
#include<bits/stdc++.h> #include<deque> /* get<T,n>()不能访问deque容器内元素 */ using namespace std; /*deque不能通过get()函数模板进行元素访问*/ void test() { deque<int> dq{1,2,3,4,5}; cout << get<int,0>(dq); } int main(){ test(); return 0; }
报错为:[Error] no matching function for call to 'get(std::deque<int>&)
意思是通过get函数不能匹配deque<int>&,所以我们不能通过函数模板get<T,n>()来访问deque元素。
deque与vector不同,没有一个指向首地址的指针data(),所以不要使用data()区访问元素。
T* t = dq.data() ;//T是通用模板类型,t是指针,这里会报错因为deque没有data()指针
通常情况下我们可以通过迭代器访问deque,比如现在我们需要访问deque{1,2,3,4,5}的第5个元素:
#include<bits/stdc++.h> #include<deque> /* 如何访问deque容器内元素 */ using namespace std; void test() { deque<int> dq{1,2,3,4,5}; /*迭代器访问第5个元素*/ deque<int>::iterator it = dq.begin() ; for(int i=0;i<4;++i)it++; cout << *it << '\n'; } int main(){ test(); return 0; }
也是通过位置迭代器成功访问了。
如果需要访问首位元素,我们可以通过front()、back()访问:
#include<bits/stdc++.h> #include<deque> /* 如何访问deque容器内元素 */ using namespace std; void test() { deque<int> dq{1,2,3,4,5}; cout << "首位元素是: " << dq.front() << '\n'; cout << "尾位元素是: " << dq.back() << '\n'; } int main(){ test(); return 0; }
成功通过front()、back()访问deque首尾元素。
总结:我们总共学习了3种方法进行对deque的访问,分别是'[]'、迭代器、back()、front();不同于vector,deque没有data()指针,不同于array,deque不能通过get<T,n>()来访问元素。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程