@@ -50,16 +50,16 @@ int a2 = x2;
50
50
``` cpp
51
51
return_type function_name ( parameter_list ) statement
52
52
```
53
- 其中,**return_type** 表示函数的返回类型,是一个表示类型的描述符;**function_name** 表示函数的名称 ,是一个描述符;**parameter_list** 是函数的参数列表;**statement** 表示函数的函数体,是一个复合语句。
53
+ 其中,**return_type** 表示函数的返回类型,是一个表示类型的描述符;**function_name** 表示函数的名字 ,是一个描述符;**parameter_list** 是函数的参数列表;**statement** 表示函数的函数体,是一个复合语句。
54
54
55
55
**返回值**是函数计算的结果,**返回类型**表示返回值的类型(返回值在后面[返回语句](#返回语句)中介绍)。
56
56
57
57
**函数名**是一个用来代指函数的标识符,函数名可以用来调用函数。注意,函数并不是一个对象,不能使用赋值表达式来给函数赋值。
58
58
59
59
**参数列表**可以为空,或者是一个用逗号分隔的参数声明列表,形式是:
60
60
61
- - ① `参数声明`
62
- - ② `参数声明列表 , 参数声明`
61
+ - `参数声明`
62
+ - `参数声明列表 , 参数声明`
63
63
64
64
这里面,每个参数声明的形式是 `类型 标识符` 或者 `类型`(后者省略标识符)。
65
65
@@ -94,7 +94,7 @@ int sqrt(int x) {
94
94
function_name ( argument_list )
95
95
```
96
96
97
- 这里,**function_name** 是函数的名称 ,**argument_list** 是参数列表。
97
+ 这里,**function_name** 是函数的名字 ,**argument_list** 是参数列表。
98
98
99
99
其中,参数列表是用逗号分隔的表达式序列,形式是:
100
100
@@ -243,7 +243,7 @@ void add_a(int x) {
243
243
}
244
244
245
245
add_a(2); // 正确:add_a 是无返回值函数
246
- int b = add_a(2); // [ !code error ] // 错误:add_a 是无返回值函数,没有返回值,这个初始化语句是错误的
246
+ int b = add_a(2); // 错误:add_a 是无返回值函数,没有返回值,这个初始化语句是错误的 // [ !code error ]
247
247
```
248
248
::: info void 类型
249
249
`void` 类型没有值,不能进行任何运算操作,也不能声明 `void` 类型的对象。此外,`void` 类型有其他的性质,我们会在后面的章节中介绍。
@@ -268,16 +268,30 @@ int foo(bool a) {
268
268
return a;
269
269
}
270
270
271
- int r = foo(42); // r 的值是 1,用 42 初始化参数 a 被转换为 true,true 被转换为 1
271
+ int r = foo(42); // r 的值是 1
272
272
```
273
273
274
+ 这里,` int r = foo(42); ` 进行了这样的过程:
275
+
276
+ 1 . 使用 ` 42 ` 初始化 ` foo ` 函数的参数 ` a ` , 这会将 ` a ` 初始化为 ` true `
277
+ 2 . 执行 ` foo ` 函数
278
+ 1 . 执行 ` return a; ` 语句,返回 ` a ` 的值,即 ` true `
279
+ 2 . 使用 ` true ` 初始化返回值,这会将 ` true ` 转换为 ` 1 `
280
+ 3 . 将 ` 1 ` 赋值给 ` r `
281
+
282
+ 最终,` r ` 的值是 ` 1 ` 。
283
+
284
+ ::: info 实际的过程
285
+ 注意,实际生成的代码并不需要像人这样去理解这个过程。最终生成的代码可能简单的判断一下 ` a ` 是否为 ` 0 ` ,然后直接返回 ` 1 ` 。以非常高的效率等效完成这个过程。这是编译器的工作。
286
+ :::
287
+
274
288
## 前向声明
275
289
276
290
类似于一个对象的名字必须要在声明之后才能使用,函数的名字也必须在定义之后才能调用。例如:
277
291
278
292
``` cpp
279
293
int sqrt (int x) {
280
- add_sqrt_counter(); // [ !code error] // 错误:add_sqrt_counter 函数还没有定义
294
+ add_sqrt_counter(); // 错误:add_sqrt_counter 函数还没有定义 // [ !code error]
281
295
int a = x;
282
296
while (a * a > x) {
283
297
a = (a + x / a) / 2;
@@ -299,7 +313,7 @@ void add_sqrt_counter() {
299
313
```cpp
300
314
return_type function_name ( expression_list ) ;
301
315
```
302
- 其中,** return_type** 是函数的返回类型,** function_name** 是函数的名称 ,** expression_list** 是参数列表。
316
+ 其中,** return_type** 是函数的返回类型,** function_name** 是函数的名字 ,** expression_list** 是参数列表。
303
317
304
318
读者可以将函数的前向声明的形式理解为把函数体改成一个分号 ` ; ` 。
305
319
@@ -329,11 +343,11 @@ void foo(int x, bool y); // 符合语法的前向声明
329
343
330
344
void foo(int x, bool); // 符合语法得前向声明
331
345
332
- void foo(int, int); // [!code error] // 错误:参数列表类型不一致
346
+ void foo(int, int); // 错误:参数列表类型不一致 // [!code error]
333
347
334
- void foo(bool, int); // [!code error] // 错误:参数列表类型不一致(顺序也必须一致)
348
+ void foo(bool, int); // 错误:参数列表类型不一致(顺序也必须一致) // [!code error]
335
349
336
- int foo(int x, bool y); // [!code error] // 错误:返回值类型不一致
350
+ int foo(int x, bool y); // 错误:返回值类型不一致 // [!code error]
337
351
338
352
void foo(int, bool y) { // 函数定义
339
353
// ...
0 commit comments