← 目录 / 第八章 · 函数 / 8.1 函数基础
函数是将特定功能的代码打包封装、起名复用的机制。好的函数让程序结构清晰,有效避免重复代码。本节先搞清楚函数是怎么"写出来"、怎么"用起来"的。
8.1.1
函数是对实现某一功能的代码进行模块化封装。定义格式如下:
| 组成部分 | 说明 | 是否必须 |
|---|---|---|
| 返回值类型 | 函数执行完毕后返回的数据类型,如 int、double、string 等 | ✅ 必需(无返回值写 void) |
| 函数名 | 调用函数时使用的名字,命名规则同变量名 | ✅ 必需 |
| 参数列表 | 调用时传入的数据,需指定类型和名称,多个参数用逗号分隔 | 可选(无参数时留空) |
| 函数体 | 花括号 {} 内要执行的具体代码 | ✅ 必需 |
| return 语句 | 返回计算结果并结束函数;返回值类型为 void 时可省略 | 视返回类型而定 |
| 1 | // 示例1:计算两数之和(有返回值) |
| 2 | int Add(int a, int b) // 返回类型 int,两个 int 参数 |
| 3 | { |
| 4 | int result = a + b; |
| 5 | return result; // 返回计算结果 |
| 6 | } |
| 7 | |
| 8 | // 示例2:打印问候语(无返回值) |
| 9 | void Greet(string name) // 返回类型 void,表示不返回值 |
| 10 | { |
| 11 | cout << "Hello, " << name << "!" << endl; |
| 12 | // 无需 return |
| 13 | } |
void 函数虽然不需要"返回值",但仍然可以写 return;(不跟任何值)——作用是提前结束这个函数、不再往下执行,这和"省略 return,让函数自然执行到最后一行结束"效果是一样的,只是多了一个"随时提前退出"的选择。比如在 Greet 函数里,如果发现 name 是空字符串,就可以写 if (name.empty()) return; 提前退出,不再继续打印问候语。Add、GetMax、PrintResult)。多个参数即使类型相同也不能省略类型声明,必须写 int a, int b,不能写 int a, b。8.1.2
调用函数就是使用函数的功能来执行代码或获取返回值。在函数名后跟圆括号,括号内传入实参,多个参数用逗号分隔。
三种调用方式看起来不太一样,但本质是同一件事:暂时离开当前执行位置,跳转去执行函数体里的代码,执行完毕后(如果有返回值)带着结果回到原来的位置,紧接着刚才暂停的地方继续往下执行。第一种和第二种调用因为有返回值,"回来"的时候手里带着一个值,可以存起来或者直接参与运算;第三种是 void 函数,"回来"的时候两手空空,只是单纯地把控制权交还给 main。
| 1 | int Add(int a, int b) // a、b 是形参(定义处) |
| 2 | { return a + b; } |
| 3 | |
| 4 | int main() |
| 5 | { |
| 6 | int x = 3, y = 5; |
| 7 | int sum = Add(x, y); // x、y 是实参(变量) |
| 8 | Add(10, 20); // 10、20 也是实参(字面量) |
| 9 | return 0; |
| 10 | } |
8.1.3
C++ 要求函数必须先定义(或声明)后调用。如果函数定义在 main() 之后,需要在前面写函数声明(也叫函数原型),提前告诉编译器这个函数的存在。
| 概念 | 格式 | 作用 |
|---|---|---|
| 函数声明(原型) | 返回类型 函数名(参数列表); | 告诉编译器函数"长什么样",没有具体实现代码 |
| 函数定义(实现) | 返回类型 函数名(参数列表) { 函数体 } | 给出函数的完整实现代码 |
| 1 | #include <iostream> |
| 2 | using namespace std; |
| 3 | |
| 4 | int Add(int a, int b); // ← 函数声明(只写函数头,不写函数体) |
| 5 | // 参数名可省略:int Add(int, int); |
| 6 | |
| 7 | int main() |
| 8 | { |
| 9 | cout << Add(3, 5) << endl; // 正常调用 |
| 10 | return 0; |
| 11 | } |
| 12 | |
| 13 | int Add(int a, int b) // ← 函数定义(在 main 之后也没问题) |
| 14 | { |
| 15 | return a + b; |
| 16 | } |
int Add(int, int); 完全合法),但为了代码的可读性,通常还是建议保留参数名,尤其是参数比较多、或者光看类型猜不出用途的时候——比如 int Add(int a, int b); 一眼就能看出两个参数分别是什么,比只写类型的 int Add(int, int); 更容易让别人(包括未来的自己)看懂这个函数是干什么用的。