C++: 函数基础
最后更新:2026-08-26
前面的课程里,所有代码都写在
main函数里。但如果程序变大,
main函数会变得很长、很难维护。函数就是解决这个问题——把代码分成一个个小模块,每个模块负责一个功能。
1. 什么是函数?
(1) 1.1 生活中的函数
| 生活场景 | 程序中的对应 |
|---|---|
| 你按电视遥控器的"开机"键 | 调用 turnOnTV() 函数 |
| 电视自动完成一系列操作(通电、搜台、显示画面) | 函数体里的代码 |
| 你不需要知道电视内部怎么工作 | 函数的"封装"特性 |
函数就是一段完成特定任务的代码块,你可以反复调用它。
(2) 1.2 为什么需要函数?
不用函数(坏例子):
#include <iostream>
int main() {
// 计算第一个矩形的面积
double width1 = 5.0, height1 = 3.0;
double area1 = width1 * height1;
std::cout << "面积1:" << area1 << std::endl;
// 计算第二个矩形的面积
double width2 = 7.0, height2 = 2.5;
double area2 = width2 * height2;
std::cout << "面积2:" << area2 << std::endl;
// 计算第三个矩形的面积
double width3 = 4.0, height3 = 6.0;
double area3 = width3 * height3;
std::cout << "面积3:" << area3 << std::endl;
return 0;
}
用函数(好例子):
#include <iostream>
// 定义函数
double calculateArea(double width, double height) {
return width * height;
}
int main() {
std::cout << "面积1:" << calculateArea(5.0, 3.0) << std::endl;
std::cout << "面积2:" << calculateArea(7.0, 2.5) << std::endl;
std::cout << "面积3:" << calculateArea(4.0, 6.0) << std::endl;
return 0;
}
对比:
| 不用函数 | 用函数 |
|---|---|
| 代码重复(复制粘贴) | 代码复用(只写一次) |
| 改逻辑要改多处 | 只改函数体一处 |
| 难以维护 | 易于维护 |
2. 函数的定义
(1) 2.1 基本语法
ReturnType functionName(parameterList) {
// function body
return returnValue; // if return type is not void
}
(2) 2.2 各部分含义
| 部分 | 含义 | 示例 |
|---|---|---|
| 返回类型 | 函数返回的值的类型 | int、double、void(不返回) |
| 函数名 | 函数的名字(遵循变量命名规则) | calculateArea、printHello |
| 参数列表 | 函数接收的输入(可以为空) | (double w, double h) |
| 函数体 | 函数要执行的代码 | { return w * h; } |
| return | 返回结果给调用者 | return area; |
▶ 示例 1:定义一个简单的函数(难度⭐)
#include <iostream>
// 函数定义:计算两个数的和
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(3, 5); // 调用函数
std::cout << "3 + 5 = " << result << std::endl;
return 0;
}
输出:
3 + 5 = 8
3. 函数的调用
(1) 3.1 调用语法
函数名(实参列表);
| 术语 | 含义 | 示例 |
|---|---|---|
| 函数的定义 | 写函数的代码 | int add(int a, int b) { ... } |
| 函数的调用 | 使用函数 | add(3, 5); |
| 形参 | 函数定义时的参数(形式参数) | int a, int b |
| 实参 | 函数调用时传入的值(实际参数) | 3, 5 |
💡 重点: 实参会复制给形参(后面会讲学引用,那时就不复制了)。
4. 返回值
(1) 4.1 return 语句
return 有两个作用:
- 返回结果给调用者
- 结束函数的执行(后面的代码不会执行)
#include <iostream>
int max(int a, int b) {
if (a > b) {
return a; // 结束函数,返回 a
} else {
return b; // 结束函数,返回 b
}
std::cout << "这行永远不会执行" << std::endl; // 死代码
}
int main() {
std::cout << "最大值:" << max(10, 20) << std::endl;
return 0;
}
(2) 4.2 没有返回值的函数(void)
如果函数不需要返回值,返回类型写 void:
#include <iostream>
void printWelcome() { // void 表示不返回任何值
std::cout << "========== 欢迎使用 ==========" << std::endl;
std::cout << "这是 void 函数,不需要 return" << std::endl;
}
int main() {
printWelcome(); // 调用 void 函数,不需要接收返回值
return 0;
}
💡 提示: void 函数里也可以写 return;(不带值),用来提前结束函数。
void printIfPositive(int x) {
if (x <= 0) {
return; // 提前结束函数
}
std::cout << x << " 是正数" << std::endl;
}
5. 函数原型(函数声明)
(1) 5.1 问题:函数必须先定义,后调用
#include <iostream>
int main() {
std::cout << add(3, 5) << std::endl; // ❌ 错误:编译器还没看到 add 的定义
return 0;
}
int add(int a, int b) {
return a + b;
}
编译错误信息:
error: 'add' was not declared in this scope
(2) 5.2 解决方法:函数原型
函数原型(也叫函数声明)告诉编译器"有这样一个函数",具体的函数体可以在后面定义。
#include <iostream>
int add(int a, int b); // 函数原型(分号结尾!)
int main() {
std::cout << add(3, 5) << std::endl; // ✅ 编译器知道 add 存在
return 0;
}
int add(int a, int b) { // 函数定义
return a + b;
}
💡 规则:
- 函数原型以分号结尾
- 参数名可以省略,只写类型:
int add(int, int); - 但建议保留参数名,增加可读性
6. 实战:计算器函数版
▶ 示例 2:用函数实现计算器(难度⭐⭐)
#include <iostream>
#include <iomanip>
// 函数原型
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);
int main() {
double num1, num2;
char op;
std::cout << "请输入第一个数字:";
std::cin >> num1;
std::cout << "请输入运算符(+ - * /):";
std::cin >> op;
std::cout << "请输入第二个数字:";
std::cin >> num2;
std::cout << std::fixed << std::setprecision(2);
switch (op) {
case '+':
std::cout << "结果:" << add(num1, num2) << std::endl;
break;
case '-':
std::cout << "结果:" << subtract(num1, num2) << std::endl;
break;
case '*':
std::cout << "结果:" << multiply(num1, num2) << std::endl;
break;
case '/':
if (num2 != 0) {
std::cout << "结果:" << divide(num1, num2) << std::endl;
} else {
std::cout << "错误:除数不能为 0!" << std::endl;
}
break;
default:
std::cout << "错误:不支持的运算符!" << std::endl;
break;
}
return 0;
}
// 函数定义
double add(double a, double b) {
return a + b;
}
double subtract(double a, double b) {
return a - b;
}
double multiply(double a, double b) {
return a * b;
}
double divide(double a, double b) {
return a / b;
}
输出:
请输入第一个数字:
请输入运算符(+ - * /):
请输入第二个数字:
结果:
结果:
结果:
结果:
错误:除数不能为 0!
错误:不支持的运算符!
7. 常见错误
(1) 7.1 忘记写函数原型
错误:
int main() {
foo(); // ❌ 编译器还不知道 foo 是什么
return 0;
}
void foo() {
std::cout << "Hello" << std::endl;
}
修复: 加函数原型:
void foo(); // ✅ 函数原型
int main() {
foo();
return 0;
}
void foo() {
std::cout << "Hello" << std::endl;
}
(2) 7.2 函数原型与函数定义不一致
错误:
int foo(int a); // 原型:返回 int
int main() {
foo(5);
return 0;
}
double foo(int a) { // ❌ 错误:定义时返回 double,与原型不一致
return a + 0.5;
}
(3) 7.3 忘记写 return
错误:
int add(int a, int b) {
int sum = a + b;
// ❌ 忘记写 return
}
int main() {
int result = add(3, 5);
std::cout << result << std::endl; // 输出垃圾值
return 0;
}
💡 提示: C++ 编译器可能不会警告你忘记写 return,但程序的行为是未定义的(可能输出垃圾值,可能崩溃)。
❓ 常见问题
return;(不带值)可以提前结束 void 函数。 > > void printIfPositive(int x) { > if (x <= 0) { > return; // 提前结束 > } > std::cout << x << " 是正数" << std::endl; > } >▶ 示例 3:函数返回值(难度⭐)
#include <iostream>
int max(int a, int b) {
return (a > b) ? a : b;
}
int main() {
int x = 10, y = 20;
std::cout << "较大值:" << max(x, y) << std::endl;
return 0;
}
输出:
较大值:20
return 返回值。三元运算符 ? : 可以简化简单的条件判断。
📖 小节
- 函数是完成特定任务的代码块,可以复用
- 函数定义的语法:
ReturnType functionName(parameterList) { functionBody } - 函数原型告诉编译器函数的存在,以分号结尾
return用来返回结果,并结束函数void函数不返回值- 函数可以先声明(原型),后定义
📝 作业
-
基础题 (Difficulty ⭐): 写一个函数
int multiply(int a, int b),返回两个整数的积。在main函数里调用它。 -
进阶题 (Difficulty ⭐⭐): 写一个函数
bool isPrime(int n),判断一个整数是否是素数。 -
素数:只能被 1 和自身整除的数(如 2、3、5、7、11)
-
在
main函数里让用户输入一个整数,调用isPrime并输出结果 -
挑战题 (Difficulty ⭐⭐⭐): 写一个程序,包含以下函数:
-
int fibonacci(int n):返回斐波那契数列的第 n 项 -
void printFibonacci(int n):输出斐波那契数列前 n 项
在 main 函数里让用户输入 n,先输出前 n 项,再输出第 n 项的值。
- 函数是一段可复用的代码块,减少重复
- 函数四要素:返回类型、函数名、参数列表、函数体
- 函数原型声明让编译器知道函数存在
- return 返回值并结束函数执行
- void 函数不返回值,可用 return; 提前结束
8. 🚀 下一步
学会了函数的基础,接下来我们学习 函数参数传递(第11课)—— 学习如何把参数传给函数,以及"传值"和"传引用"的区别。