Skip to content

Commit bffd159

Browse files
committed
Update: enhance clarity and correctness in pointer and reference type documentation
1 parent 4e86eec commit bffd159

File tree

2 files changed

+104
-5
lines changed

2 files changed

+104
-5
lines changed

src/zh/03-types/pointer-type.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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`,它们可能导致严重的维护问题。原因我们在介绍了更多的内容后再来讨论。

src/zh/03-types/reference-type/object-ref.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,31 @@
22
title: 3.5.1 对象引用
33
---
44

5-
**引用**是 C++ 中的一种特殊类型,它可以用来指代一个对象。例如:
5+
**引用**是 C++ 中的一种复合类型。引用必须用来指代一个对象。例如:
66

77
```cpp
88
int a = 42;
9-
int& b = a;
9+
int& b = a; // b 是一个整数类型的引用,它指代了对象 a
1010
```
1111

12-
在这个例子中,`b` 是一个整数类型的引用,它指代了对象 `a`一个对象的引用可以当做这个对象来使用,例如:
12+
一个对象的引用可以当做这个对象来使用,例如:
1313

1414
```cpp
1515
int a = 42;
1616
int& b = a;
1717

18-
b = 43; // 修改了 a 的值
18+
b = 43; // 通过对 b 赋值,修改了 a 的值
1919
```
2020

21-
在这个例子中,通过对 `b` 赋值,修改了 `a` 的值。
21+
引用必须要指代一个对象,不能默认初始化,也不能重新绑定到另一个对象。
22+
23+
```cpp
24+
int a = 42;
25+
int& b; // 错误,引用必须指代一个对象 // [!code error]
26+
int& c = a; // 正确,c 绑定到 a
27+
int d = 43;
28+
c = d; // 这是将 d 的值赋给 a,而不是将 c 绑定到 d
29+
```
2230

2331
除了一些特例外,引用总是当做指代的对象来使用(对于读取值或者写入值,一定是当做指代的对象来使用)。并且,在初始化之后,不能更改这种指代。
2432

0 commit comments

Comments
 (0)