C++ 函数:模块化编程核心

一、引言:从 "写代码" 到 "设计程序"

在前面三篇文章中,我们已经掌握了 C++ 的基础语法、数据类型、变量、表达式以及最核心的分支与循环。我们已经能够写出具备逻辑判断、循环执行、数据计算能力的程序,比如判断成绩、计算累加、打印图形等。

但随着程序功能越来越多,代码会迅速膨胀:

  • 所有逻辑都堆在 main 函数里;
  • 相同功能的代码反复复制粘贴;
  • 代码行数上千行后,阅读困难、修改困难、排查错误更困难;
  • 无法在多个项目中复用已有功能。

为了解决这些问题,编程语言提供了 ** 函数(Function)** 机制。

函数是 C++ 模块化编程的基石。 它的作用是:

  1. 封装重复代码,避免冗余;
  2. 拆分复杂逻辑,让程序结构清晰;
  3. 实现代码复用,一次编写,多处调用;
  4. 便于团队协作,每人负责不同函数模块。

可以说: 不会使用函数,就只能写 "小脚本"; 学会函数,才能真正开发结构化、可维护、可扩展的程序。

本篇文章将全面、系统、深入讲解 C++ 函数的全部核心知识点,内容包括:

  • 函数的定义、声明、调用;
  • 函数参数:形参、实参、值传递;
  • 函数返回值:return、void;
  • 函数重载(C++ 重要特性);
  • 默认参数;
  • 内联函数;
  • 递归函数;
  • 多文件编程与头文件;
  • 函数的常见错误与工程规范。

学完本篇,你将正式进入模块化程序设计的世界。


二、什么是函数

函数是完成特定功能的、可重复调用的代码块 。 一个完整的 C++ 程序由一个 main 函数 + 若干其他函数组成。

main 是程序入口,其他函数由 main 直接或间接调用。

函数的意义

  • 把大问题拆成小问题
  • 把复杂逻辑拆成简单逻辑
  • 代码可复用
  • 易读、易改、易调试
  • 适合大型项目开发

三、函数的定义与调用

(一)函数定义语法

cpp

运行

复制代码
返回值类型 函数名(参数列表)
{
    函数体;
    return 返回值;
}

五部分:

  1. 返回值类型:函数执行完后返回的数据类型(无返回值用 void)。
  2. 函数名:见名知意,命名规则同变量。
  3. 参数列表:调用时传入的数据(0 个或多个)。
  4. 函数体:具体执行代码。
  5. return:返回结果并结束函数。

(二)最简单的函数示例

cpp

运行

复制代码
// 定义:打印Hello
void sayHello()
{
    cout << "Hello, Function!" << endl;
}

(三)函数调用

函数必须被调用才会执行。 调用方式:

cpp

运行

复制代码
函数名(参数);

完整示例:

cpp

运行

复制代码
#include <iostream>
using namespace std;

void sayHello() {
    cout << "Hello, Function!" << endl;
}

int main() {
    sayHello(); // 调用函数
    return 0;
}

四、带参数的函数

函数可以接收外部传入的数据,称为参数

  • 形参(形式参数):定义函数时写的参数。
  • 实参(实际参数):调用函数时传的值。

示例:求两个整数的最大值

cpp

运行

复制代码
int max(int a, int b) {
    return a > b ? a : b;
}

int main() {
    int m = max(10, 20); // 10、20是实参
    cout << m << endl;
    return 0;
}

C++ 默认是值传递

调用函数时,实参的值被复制给形参 。 函数内部修改形参,不会影响外面的实参

示例:

cpp

运行

复制代码
void change(int x) {
    x = 100;
}

int main() {
    int a = 10;
    change(a);
    cout << a; // 仍然是10
    return 0;
}

五、带返回值的函数

返回值是函数执行后给调用者的结果。

规则:

  1. 返回类型不是 void,必须写 return;
  2. return 只能返回一个值
  3. return 执行后,函数立即结束。

示例:求立方

cpp

运行

来源:59s.zengto.cn

来源:ru9.zengto.cn

来源:ad1.zengto.cn

来源:8xi.zengto.cn

来源:5xs.zengto.cn

来源:4jy.zengto.cn

来源:m2t.zengto.cn

来源:0ol.zengto.cn

来源:2sj.zengto.cn

来源:et3.zengto.cn

复制代码
int cube(int n) {
    return n * n * n;
}

无返回值函数用 void

cpp

运行

复制代码
void print(int n) {
    cout << n << endl;
}

六、函数声明(最重要知识点之一)

C++ 编译器是从上到下编译的。 如果函数定义在 main 之后,编译器找不到函数,会报错。

解决方法:函数声明

声明格式:

cpp

运行

复制代码
返回值类型 函数名(参数列表);

示例:

cpp

运行

复制代码
#include <iostream>
using namespace std;

// 函数声明
int add(int a, int b);

int main() {
    cout << add(3, 5);
    return 0;
}

// 函数定义
int add(int a, int b) {
    return a + b;
}

声明就像 "告诉编译器:这个函数后面会出现,请先放行"。


七、函数重载(C++ 核心特性)

C++ 允许多个函数同名,但参数不同 ,这就是函数重载

重载条件:

  1. 函数名相同
  2. 参数个数、类型、顺序不同
  3. 返回值不同不能构成重载

示例:

cpp

运行

复制代码
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

int add(int a, int b, int c) {
    return a + b + c;
}

调用时,编译器会根据传入参数自动匹配正确函数。

重载的意义:统一功能命名,方便使用。 例如:

  • printInt(int)
  • printDouble (double) 可以统一写成 print,由编译器自动区分。

八、默认参数

C++ 允许给参数指定默认值。 调用时如果不传该参数,自动使用默认值。

示例:

cpp

运行

复制代码
void show(string msg = "Hello") {
    cout << msg << endl;
}

int main() {
    show();        // 输出 Hello
    show("Hi");    // 输出 Hi
    return 0;
}

规则:

  1. 默认参数必须靠右;
  2. 声明时写默认值,定义时不要重复写。

九、内联函数(inline)

用 inline 声明的函数叫内联函数 。 作用:在编译时将函数代码直接展开到调用位置,减少函数调用开销

适合:函数体很短、被频繁调用的函数。

cpp

运行

复制代码
inline int square(int x) {
    return x * x;
}

注意:

  • 递归函数不能内联;
  • 函数体太长不适合内联。

十、递归函数

函数调用自己,称为递归。

递归必须满足两个条件:

  1. 基线条件(退出条件):不再递归;
  2. 递归条件:把问题规模缩小。

示例:求阶乘 n!

cpp

运行

复制代码
int fact(int n) {
    if (n == 1) return 1;   // 基线条件
    return n * fact(n - 1); // 递归
}

执行过程: fact (5) → 5fact(4) → 5 4fact(3) → ... → 5 432*1

经典递归案例:

  • 斐波那契数列
  • 汉诺塔
  • 二叉树遍历
  • 快速排序

十一、函数的典型应用案例

案例 1:判断素数函数

cpp

运行

复制代码
bool isPrime(int n) {
    if (n < 2) return false;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

案例 2:求数组最大值

cpp

运行

复制代码
int maxArray(int arr[], int len) {
    int m = arr[0];
    for (int i = 1; i < len; i++) {
        if (arr[i] > m) m = arr[i];
    }
    return m;
}

案例 3:递归求斐波那契

cpp

运行

复制代码
int fib(int n) {
    if (n == 1 || n == 2) return 1;
    return fib(n - 1) + fib(n - 2);
}

十二、多文件编程(模块化工程)

真正的 C++ 项目不会把所有代码写在一个文件里。

标准结构:

  • .h 头文件:函数声明、结构体、类声明
  • .cpp 源文件:函数实现

示例: math.h

cpp

运行

来源:x5g.zengto.cn

来源:r02.x5g.zengto.cn

来源:7zd.x5g.zengto.cn

来源:5kh.x5g.zengto.cn

来源:7ng.x5g.zengto.cn

来源:me3.x5g.zengto.cn

来源:xn8.x5g.zengto.cn

来源:f0j.x5g.zengto.cn

来源:vh1.x5g.zengto.cn

来源:9hq.x5g.zengto.cn

复制代码
#pragma once
int add(int a, int b);

math.cpp

cpp

运行

复制代码
#include "math.h"
int add(int a, int b) {
    return a + b;
}

main.cpp

cpp

运行

复制代码
#include "math.h"
int main() {
    add(3,5);
    return 0;
}

优点:

  • 代码结构清晰
  • 多人协作不冲突
  • 便于维护和升级
  • 可复用模块

十三、函数常见错误(新手必看)

1. 函数调用时写错名字

cpp

运行

复制代码
add(2,3); →写成 ad(2,3);

2. 函数定义在 main 后面,又没有声明

报错:标识符未找到

3. 有返回值函数忘记 return

cpp

运行

复制代码
int add(int a,int b) {
    int c = a + b;
    // 没return
}

4. 形参和实参类型不匹配

cpp

运行

复制代码
int f(int a);
调用:f(3.14);

5. 递归没有退出条件 → 栈溢出、程序崩溃

cpp

运行

复制代码
void f() { f(); }

6. 重载只靠返回值不同 → 编译失败

cpp

运行

复制代码
int f();
void f();
错误!

7. 默认参数放在左边

cpp

运行

复制代码
void f(int a=10, int b); 错误!

十四、函数编程规范(工程级)

  1. 一个函数只做一件事
  2. 函数名见名知意:getMax、isPrime、calculate;
  3. 函数长度不宜过长(最好不超过 50 行);
  4. 参数不超过 4 个;
  5. 先声明,后调用;
  6. 多文件项目必须分 .h 和 .cpp;
  7. 避免过度递归;
  8. 注释说明函数功能、参数、返回值。

十五、本章总结

本篇文章系统、完整、深入讲解了 C++函数全部核心内容,是模块化编程的基石:

  1. 函数定义、调用、声明
  2. 参数传递:形参、实参、值传递;
  3. 返回值:return、void;
  4. 函数重载(C++ 重要特性);
  5. 默认参数、内联函数
  6. 递归函数
  7. 多文件编程
  8. 常见错误与工程规范

掌握函数,意味着你已经从 "写代码的人" 升级为 "设计程序的人"。 你可以:

  • 拆分复杂项目
  • 封装工具函数
  • 实现代码复用
  • 参与多人协作开发
  • 写出结构清晰、可维护的高质量 C++ 代码

函数是 C++ 从基础走向进阶的分水岭。 学好函数,后面的数组、指针、结构体、类、STL 都会变得非常容易。


下一篇预告

第 5 篇《C++ 指针与引用:底层内存访问核心》(4000 字以上) 指针是 C++ 最强大、最核心、最难的部分,也是区分普通程序员和高级程序员的关键。