Skip to content

Commit 2089bc4

Browse files
committed
Update: improve discription
1 parent bf686cb commit 2089bc4

File tree

4 files changed

+87
-16
lines changed

4 files changed

+87
-16
lines changed

src/zh/02-program-structure/function.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ int sqrt_x2 = sqrt(x2);
171171
//... 依此类推
172172
```
173173
174+
::: info 形式参数与实际参数
175+
在描述函数调用的时候,例如 `int sqrt_x2 = sqrt(x2);` ,人并不喜欢称呼 `sqrt(x2)` 中的 `x2` 叫什么“函数调用表达式的直接子表达式”。它被用来初始化函数的参数,所以干脆直接就叫做“参数”。
176+
177+
称 `x2` 为“参数”当然是没有错的,但是,这样就会带来一个混淆——`int sqrt(int x)` 中的 `x` 也叫“参数”,并且显然不是一个东西,在这个函数调用中,`x` 是从 `x2` 初始化而来的另一个对象。为了避免这种混淆,我们通常称呼 `int sqrt(int x)` 中的 `x` 为“形式参数”,称呼 `sqrt(x2)` 中的 `x2` 为“实际参数”。或者更简略的称呼为“形参”和“实参”。当然,在没有混淆的语境中,称呼 `x2` 为“参数”更符合人的直觉。
178+
:::
179+
174180
::: info 省略标识符的参数
175181
在参数列表中,如果省略了标识符,那么这个参数是一个匿名参数,这样的参数在函数体中是无法访问的。例如:
176182
```cpp
@@ -183,7 +189,6 @@ int f(int) {
183189
```cpp
184190
int a = f(42);
185191
```
186-
这种形式的使用方式我们会在后面的章节中介绍。
187192
:::
188193

189194
## 无返回值函数

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

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,67 @@ int add(int,int); // 函数声明,为了简便起见,省略了函数体
9494
9595
## 在返回值中使用函数引用
9696
97-
::: important TODO: 补充内容
98-
:::
97+
函数引用也可以作为函数的返回值,例如:
98+
```cpp
99+
using binary_int_func = int(int, int);
100+
101+
binary_int_func& get_add() {
102+
return add;
103+
}
104+
105+
auto& add_ref = get_add(); // add_ref 是 add 函数的引用
106+
int result = add_ref(1, 2); // 调用 add 函数
107+
```
108+
109+
在这里,`get_add` 函数返回了 `add` 函数的引用,然后我们可以通过 `add_ref` 来调用 `add` 函数。
110+
111+
当然,`get_add` 可以调用再紧跟调用,不需要额外的变量:
112+
```cpp
113+
int result = get_add()(1, 2); // 调用 add 函数
114+
```
115+
116+
结合之前提到[switch 语句](../../02-program-structure/statements.md#switch-语句)的例子,我们可以把 `get_add` 函数进一步扩展:
117+
```cpp
118+
using binary_int_func = int(int, int);
119+
120+
int add(int a, int b) {
121+
return a + b;
122+
}
123+
124+
int sub(int a, int b) {
125+
return a - b;
126+
}
127+
128+
int mul(int a, int b) {
129+
return a * b;
130+
}
131+
132+
int div(int a, int b) {
133+
return a / b;
134+
}
135+
136+
int no_such_operator(int a, int b) {
137+
return 0;
138+
}
139+
140+
binary_int_func& get_func(char op) {
141+
switch (op) {
142+
case '+':
143+
return add;
144+
case '-':
145+
return sub;
146+
case '*':
147+
return mul;
148+
case '/':
149+
return div;
150+
default:
151+
return no_such_operator;
152+
}
153+
}
154+
```
155+
156+
这样,我们就可以通过 `get_func` 来获取不同的函数引用,然后调用这些函数。例如:
157+
158+
```cpp
159+
int result = get_func('+')(1, 2); // 调用 add 函数
160+
```

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ int a = 1;
9696
auto& ref = a; // ref 是 int& 类型
9797
```
9898

99-
### 函数参数中的左值引用
99+
### 在函数参数中使用左值引用
100100

101101
可以在函数参数中使用左值引用,来修改作为参数传入的对象:
102102
```cpp
@@ -130,7 +130,7 @@ safe_divide(a, b, c); // c 的值变为 5
130130
但是,在工程中,我们一般不希望函数修改传入的参数,因此这种传出参数的方式在使用时应充分注释,或遵循一定的代码规范,以免造成误解。
131131
:::
132132

133-
### 函数返回值中的左值引用
133+
### 在函数返回值中使用左值引用
134134

135135
可以在返回值中使用左值引用,例如:
136136
```cpp
@@ -196,7 +196,7 @@ auto&& ref2 = 1; // ref2 是 int&& 类型
196196

197197
这一原理及其应用会在后面的章节中详细介绍。
198198

199-
### 函数参数中的右值引用
199+
### 在函数参数中使用右值引用
200200

201201
类似于左值引用,右值引用也可以用在函数参数中,例如:
202202
```cpp
@@ -217,6 +217,10 @@ set_a_to(a + 1); // a + 1 是纯右值表达式
217217
set_a_to(a); // [!code error] // 错误,a 是左值表达式
218218
```
219219
220+
### 在函数返回值中使用右值引用
221+
222+
::: important TODO 补充内容
223+
:::
220224
221225
## 常量左值引用
222226

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,20 @@ auto a = 42;
8989
auto b = a;
9090
```
9191

92-
此外,`auto`也可以用于函数参数和返回值的类型推导
92+
此外,`auto`也可以用于函数返回值的类型推导
9393

9494
```cpp
95-
auto sqrt(auto x) {
96-
auto a = x;
97-
while (a * a > x) {
98-
a = (a + x / a) / 2;
99-
}
100-
return a;
95+
int x = 0;
96+
97+
auto doubled_x() {
98+
x *= 2;
99+
return x;
101100
}
102101

103-
// 由于 42 是 int 类型,x 的类型也是 int
104-
// 因此 foo 返回值的类型推导为 int,a 的类型也是 int
105-
auto a = foo(42);
102+
// 由于 x 是 int 类型
103+
// 因此 doubled_x 的返回值类型是 int
104+
// 因此 a 的类型是 int
105+
auto a = doubled_x();
106106
```
107107

108108
对于目前的内容而言,读者可能会觉得 `auto` 的使用并不是很有必要,甚至会觉得 `auto` 的使用会使代码变得不够清晰。但是在后面的章节中,我们会逐渐看到 `auto` 的使用能够让复杂的程序变得简洁明了且更易维护。

0 commit comments

Comments
 (0)