简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解C++之向容器中添加nullptr空指针,容器size()会增大吗?为什么?
通过C++的20个容器类进行实验,看看有什么结果?
2.C++ 容器类介绍
C++提供了多种容器,以下是常用的20个容器及其举例:
-
数组 (array):固定大小的连续存储空间。例如:int numbers[5] = {1, 2, 3, 4, 5}。
-
向量 (vector):可变大小的动态数组。例如:vector numbers = {1, 2, 3, 4, 5}。
-
列表 (list):双向链表。例如:list numbers = {1, 2, 3, 4, 5}。
-
堆栈 (stack):后进先出 (LIFO) 的数据结构。例如:stack numbers; numbers.push(1); numbers.push(2);。
-
队列 (queue):先进先出 (FIFO) 的数据结构。例如:queue numbers; numbers.push(1); numbers.push(2);。
-
双端队列 (deque):两端都可以进行插入和删除操作的队列。例如:deque numbers = {1, 2, 3, 4, 5}。
-
集合 (set):不重复元素的无序集合。例如:set numbers = {1, 2, 3, 4, 5}。
-
映射 (map):键-值对的集合,根据键进行查找。例如:map<string, int> studentScores = {{“Alice”, 90}, {“Bob”, 85}}。
-
哈希表 (unordered_map):基于哈希函数实现的映射容器。例如:unordered_map<string, int> studentScores = {{“Alice”, 90}, {“Bob”, 85}}。
-
树 (tree):一种层次结构,如二叉搜索树 (binary search tree) 或红黑树 (red-black tree)。例如:BST树。
-
堆 (heap):一种优先级队列,按照特定规则进行元素的插入和删除。例如:priority_queue numbers; numbers.push(1); numbers.push(2);。
-
栈 (array-based stack):基于数组的栈实现。例如:stack numbers; numbers.push(1); numbers.push(2);。
-
单向链表 (forward_list):单向链表的容器。例如:forward_list numbers = {1, 2, 3, 4, 5}。
-
多重集合 (multiset):允许重复元素的集合。例如:multiset numbers = {1, 2, 2, 3, 4, 4, 4}。
-
多重映射 (multimap):允许重复键的映射容器。例如:multimap<string, int> studentScores = {{“Alice”, 90}, {“Bob”, 85}, {“Alice”, 95}}。
-
哈希集合 (unordered_set):基于哈希函数实现的集合容器。例如:unordered_set numbers = {1, 2, 3, 4, 5}。
-
字符串 (string):字符串容器。例如:string str = “Hello, world!”。
-
位集合 (bitset):固定大小的位集合容器。例如:bitset<8> bits = 8;。
-
链式哈希集合 (unordered_multiset):基于哈希函数实现的允许重复元素的集合容器。例如:unordered_multiset numbers = {1, 2, 2, 3, 4, 4, 4}。
-
链式哈希映射 (unordered_multimap):基于哈希函数实现的允许重复键的映射容器。例如:unordered_multimap<string, int> studentScores = {{“Alice”, 90}, {“Bob”, 85}, {“Alice”, 95}}。
3.实例
v1.0
#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <forward_list>
#include <unordered_set>
#include <string>
#include <bitset>using namespace std;int main() {// arrayarray<int*, 5> arr = {nullptr};cout << "Array size: " << arr.size() << endl;// vectorvector<int*> vec;cout << "Vector size: " << vec.size() << endl;vec.push_back(nullptr);cout << "Vector size: " << vec.size() << endl;// listlist<int*> lis;cout << "List size: " << lis.size() << endl;lis.push_back(nullptr);cout << "List size: " << lis.size() << endl;// stackstack<int*> sta;cout << "Stack size: " << sta.size() << endl;sta.push(nullptr);cout << "Stack size: " << sta.size() << endl;// queuequeue<int*> que;cout << "Queue size: " << que.size() << endl;que.push(nullptr);cout << "Queue size: " << que.size() << endl;// dequedeque<int*> deq;cout << "Deque size: " << deq.size() << endl;deq.push_back(nullptr);cout << "Deque size: " << deq.size() << endl;// setset<int*> se;cout << "Set size: " << se.size() << endl;se.insert(nullptr);cout << "Set size: " << se.size() << endl;// mapmap<int*, int> ma;cout << "Map size: " << ma.size() << endl;ma[nullptr] = 0;cout << "Map size: " << ma.size() << endl;// unordered_mapunordered_map<int*, int> ump;cout << "Unordered Map size: " << ump.size() << endl;ump[nullptr] = 0;cout << "Unordered Map size: " << ump.size() << endl;// array-based stackstack<int*, vector<int*>> abs;cout << "Array-based Stack size: " << abs.size() << endl;abs.push(nullptr);cout << "Array-based Stack size: " << abs.size() << endl;// forward_listforward_list<int*> flis;cout << "Forward List size: " << distance(flis.begin(), flis.end()) << endl;flis.push_front(nullptr);cout << "Forward List size: " << distance(flis.begin(), flis.end()) << endl;// multiset multiset<int*> mse;cout << "Multiset size: " << mse.size() << endl;mse.insert(nullptr);cout << "Multiset size: " << mse.size() << endl;// multimapmultimap<int*, int> mmap;cout << "Multimap size: " << mmap.size() << endl;mmap.insert({nullptr, 0});cout << "Multimap size: " << mmap.size() << endl;// unordered_setunordered_set<int*> use;cout << "Unordered Set size: " << use.size() << endl;use.insert(nullptr);cout << "Unordered Set size: " << use.size() << endl;// stringstring str;cout << "String size: " << str.size() << endl;str.push_back('\0');cout << "String size: " << str.size() << endl;// bitsetbitset<1> bits;cout << "Bitset size: " << bits.size() << endl;bits[0] = 0;cout << "Bitset size: " << bits.size() << endl;// unordered_multisetunordered_multiset<int*> umse;cout << "Unordered Multiset size: " << umse.size() << endl;umse.insert(nullptr);cout << "Unordered Multiset size: " << umse.size() << endl;// unordered_multimapunordered_multimap<int*, int> ummap;cout << "Unordered Multimap size: " << ummap.size() << endl;ummap.insert({nullptr, 0});cout << "Unordered Multimap size: " << ummap.size() << endl;return 0;
}
打印结果:
Array size: 5
Vector size: 0
Vector size: 1
List size: 0
List size: 1
Stack size: 0
Stack size: 1
Queue size: 0
Queue size: 1
Deque size: 0
Deque size: 1
Set size: 0
Set size: 1
Map size: 0
Map size: 1
Unordered Map size: 0
Unordered Map size: 1
Array-based Stack size: 0
Array-based Stack size: 1
Forward List size: 0
Forward List size: 1
Multiset size: 0
Multiset size: 1
Multimap size: 0
Multimap size: 1
Unordered Set size: 0
Unordered Set size: 1
String size: 0
String size: 1
Bitset size: 1
Bitset size: 1
Unordered Multiset size: 0
Unordered Multiset size: 1
Unordered Multimap size: 0
Unordered Multimap size: 1
v2.0
#include <iostream>
#include <vector>
#include <cstring>int main() {std::vector<std::string*> buf;printf("size = %ld\n",buf.size());buf.push_back(nullptr);printf("size = %ld\n",buf.size());return 0;
}
打印结果:
size = 0
size = 1
4.实验结果
<1>.当将 nullptr 添加到 std::vectorstd::string* 中时,实际上是将一个空指针的地址添加到了容器中,并不是将空指针本身存储到容器中。
<2>.在这种情况下,使用 buf.push_back(nullptr) 是合法的,因为 std::vectorstd::string* 可以存储指针类型的元素。所以在执行完 buf.push_back(nullptr) 后,容器中会存储一个空指针的地址。
<3>.因此,当你打印 buf.size() 时,结果为 1,表示容器中有一个元素,即空指针。
<4>.注意,虽然空指针本身不占用任何内存空间,但是指针的地址存储在容器中占用了一个元素的位置