🔷 第六章 函数
📄 一句话概括

函数=把一段专门干某件事的代码"打包"起来、起个名字,以后喊名字就能用。它一次解决三件事:不用抄、改一处全生效、代码看得懂。程序说到底就是一堆函数拼起来的,main 也只是其中一个(只是它是"进门那一个")。

📝 本节和前面几节的关系

前五章写的所有代码都堆在 main 里——第二章拆过 main 的四个部件,第三章在里面算数,第四章在里面判断,第五章在里面循环。当 main 长到几百行,就得拆:第六章给的就是这把拆刀。你其实早就用过函数了(main 是函数、cout 相关的东西也是别人写好的函数),本章要学的是自己造函数。

一、函数是什么:一台带按钮的机器

生活里到处都是函数:ATM 机、微波炉的"开始"键、电梯的楼层按钮。你只管按按钮,不用管里面怎么数钞票、怎么转盘子。C++ 里的函数就是同一个东西:

机器的部位 函数里的对应物 例子
投料口 参数(入口) sortScores(scores, 5) 里的 scores
内部机械 函数体(干活的代码) 花括号里那一堆语句
出货口 返回值(出口) 排好序的结果交回来

一句话:函数是"给一段代码起的名字"。起了名字,就能反复喊它。

二、为什么要用函数(三个理由)

  1. 不抄——同一段活儿只写一遍,需要的地方喊名字。抄三遍的代码,改的时候就要改三处(总会漏一处)。
  2. 好改——逻辑藏在函数里,改函数一处,所有调用点自动跟着变。这是函数最大的价值。
  3. 看得懂——printTable()、sortScores()、calcAverage() 摆在 main 里,一眼就知道程序在干什么,不用一行行读细节。给代码起名字,等于给程序加目录。

再加一条加分项:能分工——多人协作时,各写各的函数,约定好名字和参数就能拼起来(这就是"模块化"的起点)。

三、一个函数的一生:定义 → 声明 → 调用

本章按这个顺序展开:

环节 小节 一句话
写出来 6.1.1 定义 造这台机器(长什么样、干什么)
先打招呼 6.1.2 声明 告诉编译器"有这么个名字",便于先用后写
入口与出口 6.2 参数与返回值 怎么把料送进去、怎么把结果接回来
怎么用 6.3 调用 传值调用 / 嵌套调用 / 递归调用
变量的地盘 6.4 变量作用域 谁能看见谁
同名的艺术 6.5 重载函数 一个名字、多副面孔
省那点开销 6.6 内联函数 用空间换时间
活多久、住哪儿 6.7 变量的存储类别 auto / static / register / extern

四、动手 Demo:把第五章的乘法表装进函数

回忆 5.4 的九九乘法表——现在把它打包成一个函数:

#include <iostream>
using namespace std;

void printTable() {              // 造机器:名字 printTable,不吐结果(void)
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            cout << j << "*" << i << "=" << j * i << "\t";
        }
        cout << endl;
    }
}

int main() {
    printTable();                            // 喊一声,整段活儿干完
    cout << "---- 再喊一遍 ----" << endl;
    printTable();                            // 喊几次干几次,代码只写了一遍
    return 0;
}

看到什么算成功:屏幕上出现两份完整的九九表(下三角),中间夹着一行 ---- 再喊一遍 ----。

对比体会:如果不用函数,想打印两遍就得把那段双层循环完整复制一遍。而有了函数,第二次只是一行 printTable();。

30 秒实验:把函数体里 i <= 9 改成 i <= 5,编译运行——两个调用处打印的都变成 5 行。只改一处、两处生效,这就是第二节说的"好改"。

五、常见误区

  1. "函数必须返回一个值"——不是。只干活、不交结果的函数用 void(上面的 printTable 就是),6.2.1 专门讲空函数。
  2. "函数写得越长越厉害"——反过来。一个函数只干一件事,超过一屏(约 50 行)就该想怎么拆。
  3. "复制几份改成不同名字也算复用"——那只是多份副本,改起来照样得改多处,是"伪复用"。
  4. "main 是特殊函数,不用守函数的规矩"——main 特殊在"程序从这里开始",语法上它和其他函数一模一样(一样的返回类型、参数表、花括号)。
自测三问(点开对答案) 1. 函数解决哪三个问题?——不重复抄、改一处全生效、代码可读(另外还能分工协作)。 2. 函数的"入口"和"出口"分别是什么?——入口是参数,出口是返回值(`void` 表示没有出口)。 3. 为什么说"改函数一处,调用点全生效"?——因为调用点只是"喊名字",真正的逻辑只有函数体那一份。

相关笔记