CC++ & Algorithm

函数的定义与调用

中等4
语言版本:C++
概述:学习如何把一段代码打包成“函数”,就像做菜的食谱一样,可以随时调用。

把代码打包成“函数”——像做菜食谱一样调用

你平时买零食的时候,是不是常常心里默默算账?比如你有一张10元纸币,又向同学借了5元,最后总共多少钱?这种“把两个数加起来”的操作,如果你在C++里每次都要重新写一遍加法逻辑,代码会变得又长又乱。这时候,函数就派上用场了——它就像一本做菜的食谱:把某段功能完整的代码打包起来,取一个名字,以后只要喊这个名字,程序就会立刻执行里面的步骤。这样你就能反复使用,代码也更容易读懂。

函数到底是什么?——先看一个生活的例子

想象你在班里负责“收作业本”。你需要记录每个小组交上来的本子数量:第一组30本,第二组25本,第三组28本……每次你都得“加一遍”。如果你写了一个小工具叫 add,只要说“add(30, 25)”,它就能立刻算出和,那该多方便!C++里的函数就干这件事:它把一段代码“封装”起来,可以带进去一些“原料”(参数),然后给你一个“结果”(返回值)。

定义函数:告诉C++你的“食谱”长什么样

定义一个函数,需要告诉C++三件事:

  1. 返回值类型:这个函数会端出什么菜?是整数(int)、小数(double)、还是什么都不返回(void)?
  2. 函数名字:你给这个食谱起的名字,比如 addmyScorecountApples
  3. 参数列表:做菜需要什么材料?需要几个整数?需要几个字符?参数用圆括号包起来,多个参数用逗号隔开。

然后,用花括号 { } 把函数的“步骤”包起来,最后用 return 把结果送出来。

下面这个函数计算两个整数的和,就像你算“零花钱+零花钱”:

#include <iostream>
using namespace std;

// 函数定义:计算两个整数的和
int add(int a, int b) {
    int result = a + b;   // 把a和b加起来,存到result里
    return result;        // 返回结果
}

int main() {
    int myMoney = 10;      // 我的零花钱10元
    int borrowed = 5;      // 找同学借了5元
    int total = add(myMoney, borrowed);   // 调用函数求总和
    cout << "我一共有" << total << "元" << endl;
    return 0;
}

解释上面的代码:

  • int add(int a, int b)
    • 第一个 int 表示这个函数会返回一个整数(就像厨师端出一盘菜,这盘菜是整数)。
    • add 是函数名,你可以取任何合法的名字,比如 sumplus
    • (int a, int b) 是参数表,告诉函数:你需要两个整数作为原材料,我们给它们分别起名叫 ab
  • 花括号里的 int result = a + b; 是“步骤1:把原料加在一起”。
  • return result; 是“步骤2:把做好的菜端出来”。注意:return 后面的值必须和函数开头声明的返回类型一致(这里是 int)。
  • main 里调用 add(myMoney, borrowed) 时,函数会收到 a=10, b=5,然后执行加法,送回 15

调用函数:就像喊厨师的名字

main 函数或者其他函数中,写上 函数名(实际参数) 就是在说:“请执行 add 食谱,材料用 myMoneyborrowed”。程序会立刻跳到 add 函数里面,把实参的值传给形参(a和b),然后执行步骤,最后带着结果返回,赋值给等号左边的变量。

注意:调用前,函数必须先定义(或者至少在前面声明,后面再定义),否则编译器会不认识它。

参数与返回值:带多少材料,端出什么菜

有参数,有返回值(最常用)

比如上面的 add

有参数,无返回值(只干活,不端菜)

如果函数只需要打印一些信息,不需要返回结果,那么返回值类型写 void。例如:

#include <iostream>
using namespace std;

// 函数:打印问候语,需要你告诉它名字
void sayHello(string name) {
    cout << "你好," << name << "!欢迎学习C++!" << endl;
    // 注意:这里没有 return 语句
}

int main() {
    sayHello("小华");   // 输出:你好,小华!欢迎学习C++!
    return 0;
}

无参数,有返回值(不需要材料,但能给你东西)

比如一个随机数生成器,不需要输入,每次返回一个整数。

#include <iostream>
#include <cstdlib>   // 为了使用 rand()
#include <ctime>     // 为了使用 time()
using namespace std;

// 函数:返回一个1-10之间的随机数,不需要参数
int getRandom() {
    int num = rand() % 10 + 1;   // 生成1~10
    return num;
}

int main() {
    srand(time(0));        // 随机种子
    int lucky = getRandom();
    cout << "你的幸运数字是:" << lucky << endl;
    return 0;
}

无参数,无返回值(纯粹执行动作)

比如播放一个提示音。

void beep() {
    cout << "\a";   // 发出蜂鸣声
}

新手最容易犯的错误

1. 忘记写返回类型,或者写错类型

函数定义时,返回类型不能省略。如果函数不打算返回任何东西,必须写 void

2. 有返回值的函数里没有 return 语句

如果声明了 intdouble 等返回类型,但函数里没有写 return,程序会得到一些莫名其妙的值,甚至崩溃。

错误示例:

// 错误:声明了返回int,却没有return
int badAdd(int a, int b) {
    int sum = a + b;
    // 忘记return sum;
}

3. 调用时写错了参数类型或个数

比如函数要两个整数,你却传了一个整数和一个字符串,或者只传了一个整数。这时编译器会报错。

4. 函数名和变量名重复

比如你有一个变量叫 add,又定义了一个函数也叫 add,会冲突。建议函数名用“动词”或“动作”,变量名用“名词”。

5. 在函数内部定义了和参数同名的变量(但不一定错,但容易混淆)

比如:

int add(int a, int b) {
    int a = 10;   // 错误!a已经是参数,不能再重新定义
    return a + b;
}

这样编译器会报错“重定义”。

完整可运行的示例:计算考试平均分

下面这个例子,你扮演老师,输入三个学生的分数,用函数计算平均分并打印等级。

#include <iostream>
using namespace std;

// 函数:计算三个整数的平均值,并返回(小数用double)
double average(int score1, int score2, int score3) {
    double sum = score1 + score2 + score3;   // 总分
    double avg = sum / 3.0;                  // 平均分,要除以3.0,不然整数除法会丢失小数
    return avg;
}

// 函数:根据平均分输出等级(无返回值,直接打印)
void showGrade(double avg) {
    if (avg >= 90) {
        cout << "优秀!" << endl;
    } else if (avg >= 75) {
        cout << "良好!" << endl;
    } else if (avg >= 60) {
        cout << "及格!" << endl;
    } else {
        cout << "需要加油!" << endl;
    }
}

int main() {
    int chinese, math, english;   // 定义三门课成绩

    cout << "请输入语文、数学、英语成绩(空格隔开):";
    cin >> chinese >> math >> english;

    double avgScore = average(chinese, math, english);   // 调用 average 函数
    cout << "平均分是:" << avgScore << endl;

    showGrade(avgScore);   // 调用 showGrade 函数,打印等级

    return 0;
}

运行结果示例:

请输入语文、数学、英语成绩(空格隔开):85 92 78
平均分是:85
良好!

相关指引

  • 如果你想把函数定义放在 main 后面,就需要在 main 前面先声明函数(也叫函数原型),比如 int add(int a, int b);
  • 函数还可以嵌套调用,比如在 average 函数里面再调用其他函数。
  • 变量作用域:函数内部定义的变量只能在那个函数里用,外面看不见。这叫“局部变量”。
  • 如果你想深入学习,可以了解“形参和实参的区别”、“值传递和引用传递”、“递归函数”(函数调用自己)。

现在,自己动手试试吧!写一个函数 multiply(4, 6) 计算乘法,再试试写一个函数来判断一个数是偶数还是奇数,打印出来。掌握函数之后,你的代码会像搭积木一样清晰。

例题精讲

1单选题

下列选项中,哪个是C++中正确的函数定义?

Avoid func() {}
Bvoid func();
Cfunc() {}
Dvoid func()
2单选题

若函数定义如下:int add(int a, int b) { return a + b; },则调用add(3, 4)的返回值是?

A3
B4
C7
D12
3判断题

在C++中,函数的定义可以放在函数调用之后,只要在调用之前有函数声明即可。

4填空题
补全代码,实现调用函数计算两个整数的和:
#include <iostream>
using namespace std;
int sum(int x, int y) {
    return x + y;
}
int main() {
    int a = 5, b = 10;
    int result = ___(a, b);
    cout << result;
    return 0;
}
5填空题
补全函数定义,使其返回三个整数中的最大值:
int max3(int a, int b, int c) {
    int m = a;
    if (b > m) ___(1)___;
    if (c > m) ___(2)___;
    return m;
}