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

定义一个函数,就是把四个部件写齐:返回类型 + 函数名 + 参数表 + 函数体。前三样合称函数头(也叫函数签名),描述"这台机器叫什么、吃什么料、吐什么货";花括号里的函数体才是真正干活的语句。

📝 本节和前面几节的关系

6.1 讲了"函数是什么、为什么要有",这一节落地"怎么写出来"。写定义用的零件全是前面学过的旧朋友:返回类型是第二章的类型(int/double/void)、函数名要守 2.3.1 的标识符规则、参数就是 2.3.2 的变量声明、花括号是 2.1.5 讲过的"作用域边界"。学完这一节,你就能自己造机器了;下一节 6.1.2 解决"机器还没造好就想用"的问题。

一、定义的完整格式

返回类型 函数名(参数表) {
    函数体;             // 干活
    return 返回值;      // 交结果(返回类型是 void 时可省)
}

读完这一行要能自动翻译成大白话:int add(int a, int b) = "我叫 add,你递给我两个整数,我还你一个整数"。

二、四个部件逐个拆

部件 位置 作用 例子
返回类型 最前面 出口的规格:交回什么类型;不交结果写 void int、double、void
函数名 返回类型后面 以后喊它用的名字 add、printTable
参数表 圆括号里 入口:收几样料、各是什么类型 (int a, int b)、()
函数体 花括号里 真正干活的语句序列 { return a + b; }

职责分工一句话:函数头告诉编译器怎么用,函数体告诉计算机怎么干。函数头写错,调用处就编不过;函数体写错,编译能过但结果不对。

三、三个最小例子(覆盖三种形态)

void sayHello() {                    // ① 不收料、不交结果:纯干活
    cout << "Hello" << endl;
}

int add(int a, int b) {              // ② 收两样料、交一个结果
    return a + b;
}

void printStars(int n) {             // ③ 收料、但不交结果
    for (int i = 1; i <= n; i++) cout << "*";
    cout << endl;
}

三种形态对应现实里的三类机器:喇叭(只出声)、计算器(有进有出)、打印机(给纸才干活)。

四、动手 Demo:自己写第一个函数

#include <iostream>
using namespace std;

double circleArea(double r) {          // 返回类型 double,一个参数
    const double PI = 3.14159;         // 2.2.5 的 const 常量
    return PI * r * r;
}

void printLine() {                     // 无参数、无返回
    cout << "--------------------" << endl;
}

int main() {
    printLine();
    cout << "半径 1 的面积 = " << circleArea(1.0) << endl;
    cout << "半径 2 的面积 = " << circleArea(2.0) << endl;
    printLine();
    return 0;
}

看到什么算成功:

--------------------
半径 1 的面积 = 3.14159
半径 2 的面积 = 12.5664
--------------------

两个函数各司其职:printLine 管"装饰"、circleArea 管"计算"。main 里读起来就是一句话一句话的指令,没有一个细节碍眼——这就是 6.1 说的"可读性"。

30 秒实验:把 circleArea 的返回类型 double 改成 int,重新编译运行——面积变成 3 和 12,小数被砍掉(不是四舍五入,回看 3.1.1 整数除法是"砍")。这就是"返回类型就是出口规格":写 int 就等于承诺只交整数。

五、常见误区

  1. "函数名后面的圆括号可以不写"——不行。int add { } 不是函数,缺了括号编译器根本不认。
  2. "声明了 int 返回类型但函数体里没 return"——多数编译器只给警告不报错,交回的是一份垃圾值(和 2.3.2 未初始化的坑同源)。有返回类型就必须保证每条路径都有 return。
  3. "参数表里只写类型、不写名字"——形参名可以省(int add(int, int) 合法),但函数体里就用不到那个参数了,等于白收。
  4. "定义写在 main 后面,直接在 main 里调用"——会报"未定义的标识符"。这不是定义写错了,是顺序问题,下一节 6.1.2 的声明专治它。
自测三问(点开对答案) 1. 函数定义的四个部件?——返回类型、函数名、参数表、函数体(前三合称函数头)。 2. 不交结果的函数返回类型写什么?——`void`。 3. 把 `double` 返回类型改成 `int`,`return 3.9;` 会怎样?——小数被砍成 `3`(不是四舍五入),而且编译器可能只给警告。

相关笔记