Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitee0a266

Browse files
Shude Lichangkun
Shude Li
authored andcommitted
update: ch04, std::array section (changkun#57)
* doc(04): update std::array section* doc(04): update desc* doc(04): update std::array* doc(04): remove unprint symbols* doc(04): update
1 parent8604e6c commitee0a266

File tree

1 file changed

+54
-6
lines changed

1 file changed

+54
-6
lines changed

‎book/zh-cn/04-containers.md

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,65 @@ order: 4
1919
1. 为什么要引入`std::array` 而不是直接使用`std::vector`
2020
2. 已经有了传统数组,为什么要用`std::array`?
2121

22-
先回答第一个问题,`std::vector`太强大了,以至于我们没有必要为了去敲碎一个鸡蛋而用一个钉锤。使用`std::array`保存在栈内存中,相比堆内存中的`std::vector`,我们就能够灵活的访问这里面的元素,从而获得更高的性能;同时正是由于其堆内存存储的特性,有些时候我们还需要自己负责释放这些资源
22+
先回答第一个问题,`std::vector`不同,`std::array`对象的大小是固定的,如果容器大小是固定的,那么可以优先考虑使用`std::array` 容器。另外由于`std::vector` 是自动扩容的,当存入大量的数据后,并且对容器进行了删除操作,容器并不会自动归还被删除元素相应的内存,这时候就需要手动运行`shrink_to_fit()` 释放这部分内存
2323

24-
而第二个问题就更加简单,使用`std::array`能够让代码变得更加现代,且封装了一些操作函数,同时还能够友好的使用标准库中的容器算法等等,比如`std::sort`
24+
```cpp
25+
std::vector<int> v;
26+
std::cout <<"size:" << v.size() << std::endl;// 输出 0
27+
std::cout <<"capacity:" << v.capacity() << std::endl;// 输出 0
28+
29+
// 如下可看出 std::vector 的存储是自动管理的,按需自动扩张
30+
// 但是如果空间不足,需要重新分配更多内存,而重分配内存通常是性能上有开销的操作
31+
v.push_back(1);
32+
v.push_back(2);
33+
v.push_back(3);
34+
std::cout <<"size:" << v.size() << std::endl;// 输出 3
35+
std::cout <<"capacity:" << v.capacity() << std::endl;// 输出 4
36+
37+
// 这里的自动扩张逻辑与 Golang 的 slice 很像
38+
v.push_back(4);
39+
v.push_back(5);
40+
std::cout <<"size:" << v.size() << std::endl;// 输出 5
41+
std::cout <<"capacity:" << v.capacity() << std::endl;// 输出 8
42+
43+
// 如下可看出容器虽然清空了元素,但是被清空元素的内存并没有归还
44+
v.clear();
45+
std::cout <<"size:" << v.size() << std::endl;// 输出 0
46+
std::cout <<"capacity:" << v.capacity() << std::endl;// 输出 8
47+
48+
// 额外内存可通过 shrink_to_fit() 调用返回给系统
49+
v.shrink_to_fit();
50+
std::cout <<"size:" << v.size() << std::endl;// 输出 0
51+
std::cout <<"capacity:" << v.capacity() << std::endl;// 输出 0
52+
```
53+
54+
而第二个问题就更加简单,使用`std::array` 能够让代码变得更加“现代化”,而且封装了一些操作函数,比如获取数组大小以及检查是否非空,同时还能够友好的使用标准库中的容器算法,比如`std::sort`
2555

26-
`std::array` 会在编译时创建一个固定大小的数组,`std::array` 不能够被隐式的转换成指针,使用`std::array` 很简单,只需指定其类型和大小即可:
56+
使用`std::array` 很简单,只需指定其类型和大小即可:
2757

2858
```cpp
29-
std::array<int,4> arr= {1,2,3,4};
59+
std::array<int,4> arr = {1, 2, 3, 4};
60+
61+
arr.empty(); // 检查容器是否为空
62+
arr.size(); // 返回容纳的元素数
63+
64+
// 迭代器支持
65+
for (auto &i : arr)
66+
{
67+
// ...
68+
}
69+
70+
// 用 lambda 表达式排序
71+
std::sort(arr.begin(), arr.end(),[](int a, int b) {
72+
return b < a;
73+
});
74+
75+
// 数组大小参数必须是常量表达式
76+
constexprint len =4;
77+
std::array<int, len> arr = {1, 2, 3, 4};
3078

31-
int len = 4;
32-
std::array<int, len> arr = {1,2,3,4}; // 非法, 数组大小参数必须是常量表达式
79+
// 非法,不同于 C 风格数组,std::array 不会自动退化成 T*
80+
//int*arr_p = arr;
3381
```
3482
3583
当我们开始用上了 `std::array` 时,难免会遇到要将其兼容 C 风格的接口,这里有三种做法:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp