文章目录
- C++ | C++ STL array容器
- C++ array(`STL array`)容器用法详解
- `array`容器成员函数汇总
- 实例1
- C++ STL array随机访问迭代器
- `array` 支持迭代器的成员函数
- `begin()/end()` 和 `cbegin()/cend()`
- 实例2
- `rbegin()`/`rend()` 和 `crbegin()`/`crend()`
- 实例3
- C++ STL `array`容器访问元素的几种方式
- 访问array容器中单个元素
- 访问array容器中多个元素
- C++ array容器:普通数组的“升级版”
- 实例4
- 实例5
- 实例6
- 实例7
- 实例8
C++ | C++ STL array容器
C++ array(STL array
)容器用法详解
array 容器是 C++ 11 标准中新增的序列容器(std::array),简单地理解,它就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。在使用上,它比普通数组更安全,且效率并没有因此变差。
和其它容器不同,array
容器的大小是固定的,无法动态的扩展或收缩,这也就意味着,在使用该容器的过程无法借由增加或移除元素而改变其大小,它只允许访问或者替换存储的元素。标准手册
#include <array>
using namespace std; // 默认使用std命名空间
template < class T, size_t N > class array;
T
:包含的元素的类型。别名为成员类型array::value_type
。
N
:数组的大小,以元素数表示(必须为常量)。
std::array<double, 10> values; // 创建具有 10 个 double 类型元素的 array 容器,初始化为0
std::array<double, 10> values = {0.5, 1.0, 1.5, 2.0, 2.5};
array
容器成员函数汇总
成员函数 | 功能 |
| 返回指向容器中 |
| 返回指向容器 |
| 返回指向最后一个元素的随机访问迭代器。 |
| 返回指向第一个元素之前一个位置的随机访问迭代器。 |
| 和 |
| 和 |
| 和 |
| 和 |
| 返回容器中当前元素的数量,其值始终等于初始化 |
| 返回容器可容纳元素的最大数量,其值始终等于初始化 |
| 判断容器是否为空,和通过 |
| 返回容器中 |
| 返回容器中第一个元素的直接引用,该函数不适用于空的 |
| 返回容器中最后一个元素的直接应用,该函数同样不适用于空的 |
| 返回一个指向容器首个元素的指针。利用该指针,可实现复制容器中所有元素等类似功能。 |
| 将 |
| 交换 |
实例1
/*******************************************************************
* > File Name: array-begin.cpp
* > Create Time: 2021年09月28日 22:33:02
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
std::array<int, 5> myarray = {2, 16, 77, 34, 50};
std::cout << "myarray contains:";
/*auto使编译器自动判定变量的类型,输出容器中的所有值*/
for(auto it = myarray.begin(); it != myarray.end(); ++it){
std::cout << ' ' << *it;
}
//使用 get() 重载函数输出指定位置元素
std::cout << endl << get<3>(myarray) << endl;;
return 0;
}
编译、运行:
PS D:\study\cplusplus\day11> make
g++ -o array-begin array-begin.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day11> .\array-begin.exe
myarray contains: 2 16 77 34 50
C++ STL array随机访问迭代器
array
支持迭代器的成员函数
| 返回指向容器中第一个元素的正向迭代器;如果是 |
| 返回指向容器最后一个元素之后一个位置的正向迭代器;如果是 |
| 返回指向最后一个元素的反向迭代器;如果是 |
| 返回指向第一个元素之前一个位置的反向迭代器。如果是 |
| 和 |
| 和 |
| 和 |
| 和 |
begin()/end()
和 cbegin()/cend()
实例2
/*******************************************************************
* > File Name: array-iterator.cpp
* > Create Time: 2021年09月28日 23:08:10
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
array<int, 5> values;
int h = 1;
#if 0
auto first = values.begin(); // OK
auto last = values.end(); // OK
#else
auto first = std::begin(values); // OK
auto last = std::end (values); // OK
#endif
/* 初始化容器 */
while(first != last){
*first = h;
++first; // ++ 指的是迭代器向右移动一位
h++;
}
first = values.begin();
while(first != last){
cout << *first << " ";
++first; // ++ 指的是迭代器向右移动一位
}
cout << endl;
auto first1 = values.cbegin();
while(first1 != values.cend()){
/* 可以使用 const 类型迭代器访问元素 */
cout << *first1 << " "; //不能用来修改元素
++first1; // ++ 指的是迭代器向右移动一位
}
cout << endl;
return 0;
}
编译、运行:
PS D:\study\cplusplus\day11> make
g++ -o array-iterator array-iterator.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day11> .\array-iterator.exe
1 2 3 4 5
1 2 3 4 5
rbegin()
/rend()
和 crbegin()
/crend()
实例3
/*******************************************************************
* > File Name: array-iterator1.cpp
* > Create Time: 2021年09月28日 23:25:10
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
/* 定义一个数组容器values */
array<int, 5> values = {1, 25, 33, 16, 10};
auto first = values.rbegin();
auto last = values.rend();
while(first != last){
cout << *first << ' ';
++first; // ++ 指的是迭代器向左移动一位
}
cout << endl;
return 0;
}
编译、运行:
PS D:\study\cplusplus\day11> make
g++ -o array-iterator1 array-iterator1.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day11> .\array-iterator1.exe
10 16 33 25 1
C++ STL array
容器访问元素的几种方式
访问array容器中单个元素
- 通过
容器名[]
的方式直接访问和使用容器中的元素。
values[4] = values[3] + 2.O*values[1];
- 使用
array
容器提供的at()
成员函数。
values.at (4) = values.at(3) + 2.O*values.at(1);
- 使用
get<n>
模板函数获取容器元素。
array<string, 5> words{ "one","two","three","four","five" };
cout << get<3>(words) << endl; // Output words[3]
- 通过
data()
成员函数得到指向容器首个元素的指针。
array<int, 5> words{1,2,3,4,5};
cout << *( words.data()+1); // Output words[1]
访问array容器中多个元素
-
array
容器提供的size()
函数能够返回容器中元素的个数(函数返回值为size_t
类型)。
double total = 0;
/* 逐个提取容器中的元素,并计算它们的和 */
for(size_t i = 0 ; i < values.size() ; ++i){
total += values[i];
}
- 通过调用
array
容器的empty()
成员函数,即可知道容器中有没有元素。
if(values.empty()){
std::cout << "The container has no elements.\n";
} else{
std::cout << "The container has "<< values.size()<<"elements.\n";
}
- 对于任何可以使用迭代器的容器,都可以使用基于范围的循环。
double total = 0;
for(auto&& value : values){
total += value;
}
C++ array容器:普通数组的“升级版”
-
array
容器存储的所有元素位于连续且相邻的内存中
实例4
/*******************************************************************
* > File Name: array.cpp
* > Create Time: 2021年10月 1日 19:57:20
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
array<int, 5>a{1, 2, 3};
cout << &a[2] << " " << &a[0]+2 << endl;
return 0;
}
编译、运行:
PS D:\study\cplusplus\day12> make
g++ -o array array.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day12> .\array.exe
0xffffcbe8 0xffffcbe8
可以看到,a
容器中 &a[2]
和 &a[0] + 2
是相等的。因此在实际编程过程中,我们完全有理由去尝试,在原本使用普通数组的位置,改由 array
容器去实现。
用
array
容器替换普通数组的好处是,array
模板类中已经封装好了大量实用的方法,在提高开发效率的同时,代码的运行效率也会大幅提高。
- 使用
array
容器去存储char*
或const char*
类型的字符串
实例5
/*******************************************************************
* > File Name: array2.cpp
* > Create Time: 2021年10月 1日 20:11:14
******************************************************************/
#include <iostream>
#include <cstring>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
array<char , 50>a{1,2,3};
strcpy(&a[0], "https://blog.cs.net/");
printf("%s\n", &a[0]);
return 0;
}
编译:
PS D:\study\cplusplus\day12> .\array2.exe
https://blog.cs.net/
array
容器的大小必须保证能够容纳复制进来的数据,存储字符串的话,还需要在末尾放置一个’\0
'做为字符串的结束符。strcpy()
在拷贝字符串的同时,会自动在最后添加\0
。
实例6
/*******************************************************************
* > File Name: array-data.cpp
* > Create Time: 2021年10月 1日 21:43:52
******************************************************************/
#include <iostream>
#include <array>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
array<char , 50>a{1,2,3};
strcpy(a.data(), "This is a test.");
printf("%s\n", a.data());
return 0;
}
运行:
PS D:\study\cplusplus\day12> .\array-data.exe
This is a test.
-
swap()
对两个相同数组(类型相同,大小相同)中元素的进行互换
实例7
/*******************************************************************
* > File Name: array-swap.cpp
* > Create Time: 2021年10月 1日 22:29:59
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
array<char, 50>addr1{"123456"};
array<char, 50>addr2{"ABCDEF"};
addr1.swap(addr2);
printf("addr1 is: %s\n", addr1.data());
printf("addr2 is: %s\n", addr2.data());
return 0;
}
运行:
PS D:\study\cplusplus\day12> .\array-swap.exe
addr1 is: ABCDEF
addr2 is: 123456
- 当两个
array
容器满足大小相同并且保存元素的类型相同时,两个array
容器可以直接直接做赋值操作,即将一个容器中的元素赋值给另一个容器。
实例8
/*******************************************************************
* > File Name: array-to-array.cpp
* > Create Time: 2021年10月 1日 22:57:49
******************************************************************/
#include <iostream>
#include <array>
using namespace std;
int main(int argc, char* argv[])
{
array<char, 50>addr1{"123456"};
array<char, 50>addr2{"ABCDEF"};
addr1 = addr2;
printf("%s\n",addr1.data());
return 0;
}
运行:
PS D:\study\cplusplus\day12> .\array-to-array.exe
ABCDEF
当两个 array
容器满足大小相同并且保存元素的类型相同时,如果其保存的元素也支持比较运算符,就可以用任何比较运算符直接比较两个 array
容器。
两个容器比较大小的原理,和两个字符串比较大小是一样的,即从头开始,逐个取两容器中的元素进行大小比较(根据 ASCII
码表),直到遇到两个不相同的元素,那个元素的值大,则该容器就大。