第 6 课
函数
一句话答案:函数是一段有名字的代码,带输入(参数)和一个输出(返回值)。按名字调用它,而不是复制它的内容。
最小的有用函数
#include <iostream>
using namespace std;
int square(int x) {
return x * x;
}
int main() {
cout << square(3) << endl;
cout << square(7) << endl;
return 0;
}
三部分组成:返回类型(int)、名字(square)、参数表(int x)。函数体 return 出这个类型的值。
为什么要这样?因为不用重复自己
对比同一个程序的两种写法:
#include <iostream>
using namespace std;
bool isEven(int n) {
return n % 2 == 0;
}
int main() {
int count = 0;
for (int i = 1; i <= 10; i++) {
if (isEven(i)) count++;
}
cout << count << " even numbers" << endl;
return 0;
}
现在「偶数」的定义只存在于一个地方。规则要改,你改一行而不是十行。函数的全部理由就在这里。
返回值 vs 打印
返回的函数能参与运算,打印的函数不能:
#include <iostream>
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
int total = add(2, 3) * 10; // 可行:add() 给出了一个值
cout << total << endl;
return 0;
}
优先返回。在顶层(main)打印,在函数里计算。
自己调用自己:递归
阶乘是教科书案例 —— n! = n × (n−1)!:
#include <iostream>
using namespace std;
long long factorial(int n) {
if (n <= 1) return 1; // 边界 —— 少了它就无限递归
return n * factorial(n - 1);
}
int main() {
cout << factorial(5) << endl; // 120
return 0;
}
递归需要一个停下来的边界。继续读:递归专文,以及练习题全排列和汉诺塔。
三个 bug
- 某条路径没返回。声明成
int的函数如果走到末尾还没 return,会得到未定义的垃圾值。 - 传值。改参数不会改调用方的变量。(完整文章)
- 递归缺边界。程序会以栈溢出崩溃,而不是打印一个数。