|
| 1 | +--- |
| 2 | +title: 3.7 指针类型 |
| 3 | +--- |
| 4 | + |
| 5 | +# 3.7 指针类型 |
| 6 | + |
| 7 | +指针(pointer)是 C++ 中的一种复合类型。指针类型是一种对象类型,具有大小、地址和对齐要求。指针类型的对象可以存储另一个对象的地址,从而实现对另一个对象的可变引用。 |
| 8 | + |
| 9 | +目前而言,读者可以将指针理解为存储了另一个对象的地址。指针类型的主要作用是提供对内存地址的直接访问和操作。 |
| 10 | + |
| 11 | +## 3.7.1 指针的声明与初始化 |
| 12 | + |
| 13 | +声明指针时,需要指定它所指向的数据类型,并在类型名后加上 `*`: |
| 14 | + |
| 15 | +```cpp |
| 16 | +int* p; // 声明一个指向 int 的指针 |
| 17 | +double* dp; // 声明一个指向 double 的指针 |
| 18 | +``` |
| 19 | + |
| 20 | +指针变量的初始化通常使用取地址符 `&`: |
| 21 | + |
| 22 | +```cpp |
| 23 | +int a = 10; |
| 24 | +int* p = &a; // p 存储变量 a 的地址 |
| 25 | +``` |
| 26 | + |
| 27 | +也可以使用 `auto` 关键字来自动推导指针类型: |
| 28 | + |
| 29 | +```cpp |
| 30 | +int a = 10; |
| 31 | + |
| 32 | +auto p1 = &a; // p1 的类型自动推导为 int* |
| 33 | +auto* p2 = &a; // p2 的类型明确为 int*,使用 auto* 明确这里是一个指针类型 |
| 34 | +``` |
| 35 | + |
| 36 | +## 3.7.2 指针的解引用 |
| 37 | + |
| 38 | +通过解引用操作符 `*`,可以访问指针所指向的对象,这是一种独特的[一元表达式](../02-program-structure/expression/unary-expr.md),表达式的结果是指针所指向的对象的值,并且指代这个对象(即是一个左值表达式): |
| 39 | + |
| 40 | +```cpp |
| 41 | +int a = 10; |
| 42 | +int* p = &a; |
| 43 | + |
| 44 | +*p = 20; // 修改 a 的值为 20,这和引用绑定是类似的 |
| 45 | +``` |
| 46 | + |
| 47 | +指针和引用的区别是指针是可变的引用,可以重新指向其他对象,而引用一旦绑定后就不能改变。 |
| 48 | + |
| 49 | +```cpp |
| 50 | +int a = 30; |
| 51 | +int* p = &a; |
| 52 | +int b = 40; |
| 53 | +p = &b; // p 现在指向 b,而不是 a |
| 54 | + |
| 55 | +*p = 50; // 修改 b 的值为 50 |
| 56 | +``` |
| 57 | + |
| 58 | +## 3.7.3 无效值、空指针与 nullptr |
| 59 | + |
| 60 | +指针可以默认初始化,类似于整数类型,此时指针的值是无效的。使用未初始化的指针导致未定义行为。 |
| 61 | +```cpp |
| 62 | +int* p; // 未初始化的指针,可能指向一个随机地址 |
| 63 | +*p = 10; // 错误,未定义行为 // [!code error] |
| 64 | +``` |
| 65 | + |
| 66 | +指针在未指向任何有效对象时,应该初始化为 `nullptr`,对 `nullptr` 的解引用也是未定义行为,但是在多数的实现中,发生对 `nullptr` 的解引用会确定性地立即导致程序崩溃,而不是产生完全未知的结果。 |
| 67 | + |
| 68 | +```cpp |
| 69 | +int* p = nullptr; // 推荐 |
| 70 | +*p = 10; // 错误,未定义行为 // [!code error] |
| 71 | +``` |
| 72 | + |
| 73 | +`nullptr` 是一个特殊的关键字,用来表示空指针值。它的类型是 `std::nullptr_t`,可以用来将任何指针类型值初始化为一个空指针值。 |
| 74 | + |
| 75 | +此外,也可以使用 `0` 或 `NULL` 来表示空指针值,但推荐使用 `nullptr`,因为它更安全且类型明确。 |
| 76 | + |
| 77 | +```cpp |
| 78 | +int* p1 = 0; // 旧式写法,表示空指针 |
| 79 | +int* p2 = NULL; // 旧式写法,表示空指针 |
| 80 | +``` |
| 81 | + |
| 82 | +C++ 规定,空指针值的指针和 `nullptr`、`0`、`NULL` 比较是相等的,例如: |
| 83 | + |
| 84 | +```cpp |
| 85 | +int* p = nullptr; |
| 86 | +p == 0; // true |
| 87 | +``` |
| 88 | + |
| 89 | +但需要注意,空指针的[值表示](./type-intro.md#值表示与对象表示)的字节不需要全都是 `0`。 |
| 90 | + |
| 91 | +实际使用中不推荐使用 `0` 或 `NULL`,它们可能导致严重的维护问题。原因我们在介绍了更多的内容后再来讨论。 |
0 commit comments