C++ 函数(保姆级教程)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在编程的世界中,函数如同乐高积木一般,是构建复杂程序的基础模块。对于初学者和中级开发者而言,掌握 C++ 函数 的设计与使用,不仅能提升代码的复用性,还能让逻辑结构更加清晰。本文将从函数的定义、参数传递、作用域到高级特性,逐步展开讲解,并通过实例帮助读者理解如何高效地运用这一核心工具。


一、函数的基本概念:程序的“积木块”

1.1 函数的定义与调用

函数是执行特定任务的代码块,通过 定义调用 两个步骤完成功能封装。例如,计算两个数之和的函数可以这样定义:

// 函数定义:返回类型、函数名、参数列表、函数体  
int add(int a, int b) {  
    return a + b;  
}  

在需要时调用该函数:

int result = add(3, 5); // 调用 add 函数,参数为 3 和 5  

比喻:函数就像厨房里的“料理机”,你只需将食材(参数)放入,按下开关(调用函数),就能得到成品(返回结果)。

1.2 函数的组成部分

  • 返回类型:函数执行后返回的数据类型(如 int, double),若无返回值则用 void
  • 函数名:需遵循标识符命名规则,建议使用有意义的名称(如 calculate_area)。
  • 参数列表:输入数据的容器,可为空(如 void)。
  • 函数体:具体操作的代码块,用花括号 {} 包裹。

示例代码

// 无返回值的函数示例  
void print_message() {  
    std::cout << "Hello, C++ Functions!";  
}  

二、参数传递:函数间的“对话方式”

函数通过参数与外部交互,参数传递的方式决定了数据如何在函数内外流动。

2.1 值传递(Pass by Value)

默认的传递方式:函数接收参数的副本,修改副本不会影响原变量。

void modify(int x) {  
    x = 10; // 仅修改副本  
}  
int main() {  
    int num = 5;  
    modify(num);  
    std::cout << num; // 输出仍为 5  
    return 0;  
}  

2.2 引用传递(Pass by Reference)

通过 & 符号传递变量的地址,函数直接操作原变量。

void modify(int &x) { // 使用引用传递  
    x = 10; // 修改原变量  
}  
int main() {  
    int num = 5;  
    modify(num);  
    std::cout << num; // 输出 10  
    return 0;  
}  

比喻:值传递像传递物品的复制品,而引用传递则像直接传递钥匙,让对方能操作原物。

2.3 指针传递

通过指针间接修改变量,需手动解引用操作。

void modify(int *x) {  
    *x = 10; // 通过指针修改原值  
}  
int main() {  
    int num = 5;  
    modify(&num); // 传递地址  
    std::cout << num; // 输出 10  
    return 0;  
}  

三、作用域与生命周期:函数的“可见范围”

3.1 局部变量与全局变量

  • 局部变量:定义在函数内部,仅在函数执行期间存在。
  • 全局变量:定义在所有函数之外,程序全程可用,但需谨慎使用以避免副作用。

示例代码

int global_var = 100; // 全局变量  

void func() {  
    int local_var = 200; // 局部变量  
    std::cout << global_var << " " << local_var; // 输出 100 200  
}  

3.2 函数嵌套的作用域

C++ 允许函数嵌套定义,但内部函数仅在外部函数内部可见。

void outer() {  
    void inner() {  
        // 内部函数,只能在 outer 内调用  
    }  
    inner(); // 合法  
}  

四、函数重载:让函数名“一词多义”

通过参数类型或数量的不同,可为同一函数名赋予多种行为,称为函数重载

示例代码

// 重载 add 函数:整数相加  
int add(int a, int b) { return a + b; }  

// 重载 add 函数:字符串拼接  
std::string add(const std::string &s1, const std::string &s2) {  
    return s1 + s2;  
}  

int main() {  
    std::cout << add(3, 5) << " " << add("Hello", " World"); // 输出 8 Hello World  
    return 0;  
}  

五、递归函数:自我调用的艺术

递归是函数直接或间接调用自身的行为,常用于解决分治问题(如阶乘、斐波那契数列)。

5.1 递归三要素

  1. 基准条件(Base Case):终止递归的条件。
  2. 递归步骤(Recursive Step):缩小问题规模后调用自身。
  3. 调用逻辑:确保每次递归向基准条件靠近。

示例:计算阶乘

int factorial(int n) {  
    if (n == 0) return 1; // 基准条件  
    return n * factorial(n - 1); // 递归步骤  
}  

比喻:递归如同俄罗斯套娃,每个大娃娃里都有更小的娃娃,直到最小的娃娃无法再分。


六、Lambda 表达式:匿名函数的“轻量级”实现

C++11 引入的 Lambda 表达式,允许在代码块内定义无名函数,常用于算法或回调场景。

语法格式

[捕获列表](参数列表) -> 返回类型 { 函数体 }  

示例代码

int main() {  
    auto add = [](int a, int b) { return a + b; }; // 定义 Lambda  
    std::cout << add(2, 3); // 输出 5  
    return 0;  
}  

七、实际案例:计算器程序

结合上述知识点,构建一个简易计算器:

#include <iostream>  

// 函数声明  
double add(double a, double b);  
double subtract(double a, double b);  
double multiply(double a, double b);  
double divide(double a, double b);  

int main() {  
    double num1, num2;  
    char op;  
    std::cout << "Enter operation (e.g., 5 + 3): ";  
    std::cin >> num1 >> op >> num2;  

    switch(op) {  
        case '+': std::cout << add(num1, num2); break;  
        case '-': std::cout << subtract(num1, num2); break;  
        case '*': std::cout << multiply(num1, num2); break;  
        case '/': std::cout << divide(num1, num2); break;  
        default: std::cout << "Invalid operator";  
    }  
    return 0;  
}  

// 函数定义  
double add(double a, double b) { return a + b; }  
double subtract(double a, double b) { return a - b; }  
double multiply(double a, double b) { return a * b; }  
double divide(double a, double b) { return b != 0 ? a / b : 0; }  

八、结论

通过本文的学习,读者应能理解 C++ 函数 的核心概念与高级用法,包括参数传递、作用域、重载、递归及 Lambda 表达式。掌握这些内容不仅能提升代码的可维护性,还能为后续学习模板、STL 等高级主题打下基础。建议读者通过实践项目(如计算器、排序算法)深化理解,并逐步探索函数指针、异常处理等进阶技巧。编程之路永无止境,愿函数成为你构建复杂程序的得力工具!

最新发布