C++动态内存、迭代器、字符串及字符特性全解析
立即解锁
发布时间: 2025-08-22 00:46:20 阅读量: 2 订阅数: 13 


C++编程语言第三版:全面解析与实践
### C++ 动态内存、迭代器、字符串及字符特性全解析
#### 1. 动态内存分配
在 C++ 中,动态内存分配是一个重要的概念。我们可以使用 `new` 运算符来分配内存,并且可以通过特定的方式处理可能出现的异常。例如:
```cpp
if (int* q = new (nothrow) int[1000000]) {
// allocation succeeded
}
else {
// allocation failed
}
```
上述代码使用 `new (nothrow)` 来分配一个包含 1000000 个整数的数组,这种方式不会抛出异常。如果分配成功,`q` 会指向分配的内存;如果失败,`q` 会为 `nullptr`。
从 C 语言继承而来,C++ 还提供了一套用于动态内存分配的函数接口,这些函数可以在 `<cstdlib>` 中找到:
| 函数 | 功能 |
| ---- | ---- |
| `void* malloc(size_t s);` | 分配 `s` 字节的内存 |
| `void* calloc(size_t n, size_t s);` | 分配 `n` 倍 `s` 字节的内存,并初始化为 0 |
| `void free(void* p);` | 释放由 `malloc()` 或 `calloc()` 分配的内存 |
| `void* realloc(void* p, size_t s);` | 将 `p` 指向的数组大小更改为 `s`;如果无法更改,则分配 `s` 字节的内存,将 `p` 指向的数组复制到新内存中,并释放 `p` |
不过,建议优先使用 `new`、`delete` 和标准容器,而避免使用这些 C 风格的内存分配函数。因为这些函数处理的是未初始化的内存,特别是 `free()` 不会调用所释放内存的析构函数。例如,使用 `new` 分配对象,然后使用 `free()` 删除对象会引发问题。如果确实需要使用 `realloc()`,可以考虑使用标准容器,通常这样更简单且效率相当。
此外,库中还提供了一组用于高效操作字节的函数,这些函数在 `<cstring>` 中,将 `void*` 指针视为 `char*` 指针:
| 函数 | 功能 |
| ---- | ---- |
| `void* memcpy(void* p, const void* q, size_t n);` | 复制非重叠区域的 `n` 个字节 |
| `void* memmove(void* p, const void* q, size_t n);` | 复制可能重叠区域的 `n` 个字节 |
| `void* memchr(const void* p, int b, size_t n);` | 类似于 `strchr()`,在 `p[0]` 到 `p[n-1]` 中查找 `b` |
| `int memcmp(const void* p, const void* q, size_t n);` | 类似于 `strcmp()`,比较字节序列 |
| `void* memset(void* p, int b, size_t n);` | 将 `n` 个字节设置为 `b`,并返回 `p` |
许多实现为这些函数提供了高度优化的版本。
#### 2. 迭代器与分配器的使用建议
以下是一些关于迭代器和分配器的使用建议:
1. **选择合适的迭代器**:编写算法时,要确定所需的迭代器类型,以提供可接受的效率,并仅使用该类型迭代器支持的运算符来表达算法。
2. **利用重载优化算法**:当算法的参数提供了比最小支持更多的功能时,使用重载来提供更高效的实现。
3. **使用 `iterator_traits`**:使用 `iterator_traits` 为不同的迭代器类别表达合适的算法。
4. **注意流迭代器的使用**:在访问 `istream_iterator` 和 `ostream_iterator` 之间要记得使用 `++`。
5. **使用插入器避免溢出**:使用插入器来避免容器溢出。
6. **调试时增加检查**:在调试期间使用额外的检查,之后仅在必要的地方移除检查。
7. **优先使用前置自增**:优先使用 `++p` 而不是 `p++`。
8. **利用未初始化内存**:使用未初始化内存来提高扩展数据结构的算法性能。
9. **使用临时缓冲区**:使用临时缓冲区来提高需要临时数据结构的算法性能。
10. **谨慎编写自定义分配器**:在编写自己的分配器之前要三思。
11. **避免使用 C 风格分配函数**:避免使用 `malloc()`、`free()`、`realloc()` 等。
12. **模拟模板的 `typedef`**:可以使用为 `rebind` 所用的技术来模拟模板的 `typedef`。
#### 3. 字符串的基本概念
字符串是字符的序列。标准库 `string` 提供了许多字符串操作,如下标访问、赋值、比较、追加、连接和子字符串搜索等。虽然标准库 `string` 并非完美,但它能满足许多需求,并且辅助函数也易于提供,因此在大多数情况下,应优先使用标准库 `string`。
从 C 语言继承而来,C++ 也有将字符串视为以零结尾的 `char` 数组的概念,以及一组用于操作此类 C 风格字符串的函数。
#### 4. 字符集与字符特性
“字符” 是一个有趣的概念。在编程中,字符与数值之间存在对应关系,但不同字符集可能会导致同一字符有不同的数值,而且并非每个字符集都为每个字符提供值。C++ 程序员通常假设标准美国字符集(ASCII)可用,但也考虑到某
0
0
复制全文
相关推荐










