C++ STL array容器和普通数组的比较
和 C++ 普通数组存储数据的方式一样,C++ 标准库保证使用 array 容器存储的所有元素一定会位于连续且相邻的内存中,通过如下代码也可以验证这一点:
其实,代码中的 &a[0] 还可以用 array 模板类提供的 data() 成员函数来替换:
另外,当两个 array 容器满足大小相同并且保存元素的类型相同时,两个 array 容器可以直接直接做赋值操作,即将一个容器中的元素赋值给另一个容器。比如:
不仅如此,在满足以上 2 个条件的基础上,如果其保存的元素也支持比较运算符,就可以用任何比较运算符直接比较两个 array 容器。示例如下:
总之,读者可以这样认为,array 容器就是普通数组的“升级版”,使用普通数组能实现的,使用 array 容器都可以实现,而且无论是代码功能的实现效率,还是程序执行效率,都比普通数组更高。
#include <iostream> #include <array> using namespace std; int main() { array<int, 5>a{1,2,3}; cout << &a[2] << " " << &a[0] + 2 << endl; return 0; }输出结果为:
004FFD58 004FFD58
可以看到,a 容器中 &a[2] 和 &a[0] + 2 是相等的。因此在实际编程过程中,我们完全有理由去尝试,在原本使用普通数组的位置,改由 array 容器去实现。举个例子,我们完全可以使用 array 容器去存储 char* 或 const char* 类型的字符串:用 array 容器替换普通数组的好处是,array 模板类中已经封装好了大量实用的方法,在提高开发效率的同时,代码的运行效率也会大幅提高。
#include <iostream> #include <array> using namespace std; int main() { array<char, 50>a{1,2,3}; strcpy(&a[0], "https://www.xinbaoku.com/stl"); printf("%s", &a[0]); return 0; }输出结果为:
https://www.xinbaoku.com/stl
注意,array 容器的大小必须保证能够容纳复制进来的数据,而且如果是存储字符串的话,还要保证在存储整个字符串的同时,在其最后放置一个\0
作为字符串的结束符。此程序中,strcpy() 在拷贝字符串的同时,会自动在最后添加\0
。其实,代码中的 &a[0] 还可以用 array 模板类提供的 data() 成员函数来替换:
#include <iostream> #include <array> using namespace std; int main() { array<char, 50>a{1,2,3}; strcpy(a.data(), "https://www.xinbaoku.com/stl"); printf("%s", a.data()); return 0; }此程序和上面程序的输出结果完全相同。
文章前面提到,使用 array 容器代替普通数组,最直接的好处就是 array 模板类中已经为我们写好了很多实用的方法,可以大大提高我们编码效率。例如,array 容器提供的 at() 成员函数,可以有效防止越界操纵数组的情况;fill() 函数可以实现数组的快速初始化;swap() 函数可以轻松实现两个相同数组(类型相同,大小相同)中元素的互换。注意,容器的迭代器和指针是不能混用的,即上面代码中不能用 a.begin() 来代替 &a[0] 或者 a.data[],这可能会引发错误。
#include <iostream> #include <array> using namespace std; int main() { array<char, 50>addr1{"https://www.xinbaoku.com"}; array<char, 50>addr2{ "https://www.xinbaoku.com/stl" }; addr1.swap(addr2); printf("addr1 is:%s\n", addr1.data()); printf("addr2 is:%s\n", addr2.data()); return 0; }运行结果为:
addr1 is:https://www.xinbaoku.com/stl
addr2 is:https://www.xinbaoku.com
另外,当两个 array 容器满足大小相同并且保存元素的类型相同时,两个 array 容器可以直接直接做赋值操作,即将一个容器中的元素赋值给另一个容器。比如:
#include <iostream> #include <array> using namespace std; int main() { array<char, 50>addr1{ "https://www.xinbaoku.com" }; array<char, 50>addr2{ "https://www.xinbaoku.com/stl" }; addr1 = addr2; printf("%s", addr1.data()); return 0; }运行结果为:
https://www.xinbaoku.com/stl
不仅如此,在满足以上 2 个条件的基础上,如果其保存的元素也支持比较运算符,就可以用任何比较运算符直接比较两个 array 容器。示例如下:
#include <iostream> #include <array> using namespace std; int main() { array<char, 50>addr1{ "https://www.xinbaoku.com" }; array<char, 50>addr2{ "https://www.xinbaoku.com/stl" }; if (addr1 == addr2) { std::cout << "addr1 == addr2" << std::endl; } if (addr1 < addr2) { std::cout << "addr1 < addr2" << std::endl; } if (addr1 > addr2) { std::cout << "addr1 > addr2" << std::endl; } return 0; }运行结果为:
addr1 < addr2
两个容器比较大小的原理,和两个字符串比较大小是一样的,即从头开始,逐个取两容器中的元素进行大小比较(根据 ASCII 码表),直到遇到两个不相同的元素,那个元素的值大,则该容器就大。总之,读者可以这样认为,array 容器就是普通数组的“升级版”,使用普通数组能实现的,使用 array 容器都可以实现,而且无论是代码功能的实现效率,还是程序执行效率,都比普通数组更高。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算