首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >《C++ 程序设计》第 3 章 函数:从基础到深度探索

《C++ 程序设计》第 3 章 函数:从基础到深度探索

作者头像
啊阿狸不会拉杆
发布2026-01-21 12:32:57
发布2026-01-21 12:32:57
760
举报
       大家好!今天我们来深入学习 C++ 中的核心概念 —— 函数。函数是 C++ 程序的基本构建块,掌握函数的使用是编写高效、可维护代码的基础。本文将按照《C++ 程序设计》第 3 章的结构,从函数的定义与使用到深度原理,结合完整可运行的代码示例,带大家全面掌握函数知识。

思维导图(整体知识框架)

3.1 函数的定义与使用

        函数是完成特定功能的代码块,它能让程序结构更清晰、代码更易复用。想象函数就像一个 "工具",我们定义它能做什么,然后在需要时调用它。

3.1.1 函数的定义

函数定义的基本格式:

代码语言:javascript
复制
返回类型 函数名(参数列表) {
    // 函数体:实现功能的代码
    return 返回值; // 若返回类型为void则无此句
}

代码示例:基本函数定义

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 函数定义:计算两个整数的和
int add(int a, int b) { // 返回类型int,函数名add,参数列表(int a, int b)
    int result = a + b; // 函数体:计算和
    return result; // 返回计算结果
}

// 函数定义:打印欢迎信息(无返回值)
void printWelcome() { // 返回类型void表示无返回值
    cout << "欢迎学习C++函数!" << endl;
    // 无return语句(或return;)
}

int main() {
    printWelcome(); // 调用无返回值函数
    int sum = add(3, 5); // 调用有返回值函数
    cout << "3 + 5 = " << sum << endl;
    return 0;
}
3.1.2 函数的调用

函数调用的基本流程:声明函数 → 调用函数 → 执行函数体 → 返回结果。

函数声明的作用:告诉编译器函数的返回类型、函数名和参数列表,确保调用时类型匹配。

代码示例:函数声明与调用

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 函数声明(原型)
int max(int a, int b); // 只需要参数类型,参数名可省略:int max(int, int);

int main() {
    int x = 10, y = 20;
    // 函数调用:使用函数名+参数列表
    int larger = max(x, y); 
    cout << "较大的数是:" << larger << endl;
    return 0;
}

// 函数定义(实现)
int max(int a, int b) {
    return (a > b) ? a : b; // 三目运算符返回较大值
}

运行结果

3.1.3 函数的参数传递

C++ 中参数传递主要有两种方式:值传递引用传递

1. 值传递
  • 特点:将实参的值复制一份给形参,函数内部修改形参不影响实参。
  • 适用场景:不需要修改实参的值,传递简单数据类型。
2. 引用传递
  • 特点:形参是实参的别名,函数内部修改形参会直接影响实参。
  • 语法:形参前加&符号。
  • 适用场景:需要修改实参的值,或传递大型数据(避免复制开销)。

代码示例:参数传递方式对比

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 1. 值传递:修改形参不影响实参
void valuePass(int num) {
    num = 100; // 只修改形参
    cout << "函数内(值传递):num = " << num << endl;
}

// 2. 引用传递:修改形参影响实参
void referencePass(int &num) {
    num = 200; // 修改实参(因为形参是实参的别名)
    cout << "函数内(引用传递):num = " << num << endl;
}

int main() {
    int a = 10, b = 20;
    
    // 测试值传递
    cout << "值传递测试:" << endl;
    cout << "调用前:a = " << a << endl;
    valuePass(a);
    cout << "调用后:a = " << a << endl; // a的值未改变
    
    // 测试引用传递
    cout << "\n引用传递测试:" << endl;
    cout << "调用前:b = " << b << endl;
    referencePass(b);
    cout << "调用后:b = " << b << endl; // b的值已改变
    
    return 0;
}

运行结果

综合案例:学生成绩管理
代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

// 结构体存储学生信息
struct Student {
    string name;
    int score;
};

// 引用传递:修改学生成绩
void updateScore(Student &stu, int newScore) {
    stu.score = newScore;
}

// 值传递:打印学生信息(不需要修改原数据)
void printStudent(Student stu) {
    cout << "姓名:" << stu.name << ",成绩:" << stu.score << endl;
}

int main() {
    Student s = {"张三", 75};
    
    cout << "修改前:";
    printStudent(s);
    
    // 修改成绩(引用传递)
    updateScore(s, 92);
    
    cout << "修改后:";
    printStudent(s);
    
    return 0;
}

运行结果

3.2 内联函数

        内联函数(Inline Function)是一种特殊的函数,编译器会将内联函数的代码 "嵌入" 到调用它的地方,减少函数调用的开销(如压栈、跳转等操作)。

内联函数的特点
  • 使用inline关键字声明
  • 适用于代码量少、调用频繁的函数
  • 不能包含复杂控制结构(如循环、switch)
  • 是编译器的 "建议",编译器可能忽略该建议

代码示例:内联函数的使用

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 声明为内联函数:求两个数的较小值
inline int min(int a, int b) {
    return (a < b) ? a : b;
}

int main() {
    int x = 15, y = 8;
    // 调用内联函数
    int smaller = min(x, y);
    cout << x << "和" << y << "中较小的是:" << smaller << endl;
    
    return 0;
}

运行结果

3.3 constexpr 函数

  constexpr函数是 C++11 引入的特性,用于在编译期计算常量表达式,提高程序运行效率。

constexpr 函数的要求
  • 函数体必须足够简单(不能有复杂控制流)
  • 返回值必须是常量表达式
  • 参数必须是字面量类型

代码示例:constexpr 函数的使用

代码语言:javascript
复制
#include <iostream>
using namespace std;

// constexpr函数:编译期计算阶乘
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : (n * factorial(n - 1));
}

int main() {
    // 1. 编译期计算(结果在编译时就已确定)
    constexpr int fact5 = factorial(5); // 编译期计算5! = 120
    cout << "5的阶乘(编译期计算):" << fact5 << endl;
    
    // 2. 运行期计算(如果参数不是常量表达式)
    int n;
    cout << "请输入一个整数:";
    cin >> n;
    int factN = factorial(n); // 运行期计算n!
    cout << n << "的阶乘(运行期计算):" << factN << endl;
    
    return 0;
}

运行结果

3.4 带默认形参值的函数

C++ 允许为函数参数指定默认值,当调用函数时如果不提供该参数,则使用默认值。

默认参数的规则
  1. 默认参数必须从右向左设置(不能跳过前面的参数给后面的参数设默认值)
  2. 默认参数在声明或定义中设置一次即可(通常在声明中设置)
  3. 函数调用时,实参与形参按位置匹配

代码示例:带默认参数的函数

代码语言:javascript
复制
#include <iostream>
#include <string>
using namespace std;

// 带默认参数的函数声明(默认参数在声明中设置)
void printInfo(string name, int age = 18, string gender = "未知");

// 函数定义(不需要重复默认参数)
void printInfo(string name, int age, string gender) {
    cout << "姓名:" << name << ",年龄:" << age << ",性别:" << gender << endl;
}

int main() {
    // 1. 提供所有参数
    printInfo("张三", 20, "男");
    // 2. 省略最后一个参数(使用gender的默认值)
    printInfo("李四", 22);
    // 3. 省略后两个参数(使用age和gender的默认值)
    printInfo("王五");
    
    return 0;
}

运行结果

错误示例:默认参数设置不当
代码语言:javascript
复制
// 错误:不能跳过前面的参数给后面的参数设默认值
void wrongFunc(int a, int b = 5, int c) { // 编译错误!
    // ...
}

3.5 函数重载

        函数重载(Function Overloading)允许在同一作用域内定义多个函数名相同但参数列表不同的函数,提高代码可读性和复用性。

函数重载的条件
  • 函数名必须相同
  • 参数列表必须不同(参数类型、数量或顺序不同)
  • 返回类型不同不能作为重载的依据

代码示例:函数重载的实现

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <sstream>  // 为兼容性添加

using namespace std;

// 1. 两个int相加
int add(int a, int b) {
    cout << "int + int:";
    return a + b;
}

// 2. 两个double相加(参数类型不同)
double add(double a, double b) {
    cout << "double + double:";
    return a + b;
}

// 3. 三个int相加(参数数量不同)
int add(int a, int b, int c) {
    cout << "int + int + int:";
    return a + b + c;
}

// 4. int和string拼接(参数类型和顺序不同)
string add(int num, string str) {
    cout << "int + string:";
    // 方法1:使用to_string(需要C++11支持)
    // return to_string(num) + str;
    
    // 方法2:使用stringstream(兼容性更好)
    stringstream ss;
    ss << num;
    return ss.str() + str;
}

int main() {
    cout << add(3, 5) << endl;          // 调用int+int版本
    cout << add(2.5, 3.8) << endl;      // 调用double+double版本
    cout << add(10, 20, 30) << endl;    // 调用int+int+int版本
    cout << add(100, "分") << endl;     // 调用int+string版本
    
    return 0;
}

运行结果

综合案例:计算器的函数重载
代码语言:javascript
复制
#include <iostream>
using namespace std;

// 计算器类
class Calculator {
public:
    // 加法重载
    int calculate(int a, int b) {
        return a + b;
    }
    
    double calculate(double a, double b) {
        return a + b;
    }
    
    // 减法重载
    int calculate(int a, int b, char op) { // 参数数量不同
        if (op == '-') return a - b;
        return 0;
    }
    
    double calculate(double a, double b, char op) {
        if (op == '-') return a - b;
        return 0;
    }
};

int main() {
    Calculator calc;
    
    cout << "3 + 5 = " << calc.calculate(3, 5) << endl;
    cout << "2.5 + 4.8 = " << calc.calculate(2.5, 4.8) << endl;
    cout << "10 - 4 = " << calc.calculate(10, 4, '-') << endl;
    cout << "8.5 - 3.2 = " << calc.calculate(8.5, 3.2, '-') << endl;
    
    return 0;
}

运行结果

3.6 使用 C++ 语言系统函数

C++ 标准库提供了丰富的系统函数(如数学运算、字符串处理等),使用时需要包含对应的头文件。

常用系统函数及头文件

功能类别

头文件

常用函数

数学运算

<cmath>

sqrt()(平方根)、pow()(幂运算)、sin()(正弦)

随机数

<cstdlib>

rand()(生成随机数)、srand()(设置随机数种子)

字符串转换

<string>

to_string()(数值转字符串)

代码示例:系统函数的使用

代码语言:javascript
复制
#include <iostream>
#include <cmath>    // 数学函数
#include <cstdlib>  // 随机数函数
#include <ctime>    // 时间函数(用于设置随机数种子)
#include <string>   // 字符串转换函数
#include <sstream>  // 为兼容性添加
using namespace std;

int main() {
    // 1. 数学函数
    double num = 25.0;
    cout << num << "的平方根是:" << sqrt(num) << endl;          // 平方根
    cout << "2的3次方是:" << pow(2, 3) << endl;                // 幂运算
    
    // 修改:使用更通用的π表示方法
    const double PI = 3.14159265358979323846;
    cout << "π/2的正弦值是:" << sin(PI / 2) << endl;         // 正弦函数
    
    // 2. 随机数函数
    srand(time(0)); // 设置随机数种子(基于当前时间,确保每次运行结果不同)
    cout << "\n生成3个1-100的随机数:";
    for (int i = 0; i < 3; i++) {
        // rand() % 100 生成0-99的随机数,+1后变为1-100
        cout << (rand() % 100 + 1) << " ";
    }
    cout << endl;
    
    // 3. 字符串转换函数
    int age = 25;
    // 方法1:使用to_string(需要C++11支持)
    // string ageStr = to_string(age) + "岁";
    
    // 方法2:使用stringstream(兼容性更好)
    stringstream ss;
    ss << age;
    string ageStr = ss.str() + "岁";
    
    cout << "\n转换结果:" << ageStr << endl;
    
    return 0;
}

运行结果(随机数部分每次运行不同):

3.7 深度探索

3.7.1 运行栈与函数调用的执行

        函数调用的过程依赖于内存中的 "运行栈"(Runtime Stack),每次函数调用都会创建一个 "栈帧"(Stack Frame)存储函数的参数、返回地址和局部变量。

栈帧结构示意图
代码语言:javascript
复制
高地址
+-------------------+
|      ...          |
+-------------------+
|   func()的局部变量  |
+-------------------+
|    返回地址        |  ← 栈帧信息
+-------------------+
|    参数b的值       |
+-------------------+
|    参数a的值       |
+-------------------+
|   main()的局部变量  |
|      ...          |
+-------------------+
低地址

代码示例:观察函数调用的栈行为

代码语言:javascript
复制
#include <iostream>
using namespace std;

// 展示栈帧中局部变量的特性(函数调用结束后局部变量被释放)
int stackDemo(int x) {
    int y = x * 2; // 局部变量y
    cout << "stackDemo中:x=" << x << ", y=" << y << endl;
    return y;
}

int main() {
    int a = 10; // main函数的局部变量
    cout << "main中调用前:a=" << a << endl;
    
    int result = stackDemo(a); // 调用函数,创建新栈帧
    
    cout << "main中调用后:result=" << result << endl;
    // cout << y << endl; // 错误:y是stackDemo的局部变量,此处不可访问
    
    return 0;
}

运行结果

3.7.2 函数声明与类型安全

        函数声明确保编译器在函数调用时进行类型检查,避免类型不匹配的错误,提高代码安全性。

类型不安全的示例(无函数声明)
代码语言:javascript
复制
#include <iostream>
using namespace std;

int main() {
    // 错误:调用未声明的函数(编译器可能警告或报错)
    int result = unsafeFunc(3.14); // 实参是double,函数期望int
    cout << "结果:" << result << endl;
    return 0;
}

// 函数定义在调用之后且未声明
int unsafeFunc(int num) {
    return num * 2;
}
类型安全的示例(有函数声明)
代码语言:javascript
复制
#include <iostream>
using namespace std;

// 函数声明:明确参数类型和返回类型
int safeFunc(int num); // 声明必须在调用之前

int main() {
    // 编译器会检查类型匹配
    // int result = safeFunc(3.14); // 编译错误:实参类型不匹配(double不能隐式转换为int)
    int result = safeFunc(static_cast<int>(3.14)); // 显式类型转换后调用
    cout << "结果:" << result << endl;
    return 0;
}

// 函数定义
int safeFunc(int num) {
    return num * 2;
}

运行结果

代码语言:javascript
复制
结果:6

3.8 小结

本章我们系统学习了 C++ 函数的核心知识,包括:

  1. 函数基础:函数的定义(返回类型、参数列表、函数体)、调用流程和参数传递方式(值传递 vs 引用传递)。
  2. 特殊函数类型
    • 内联函数:用inline关键字减少调用开销,适用于短小函数。
    • constexpr函数:在编译期计算常量表达式,提高运行效率。
    • 带默认参数的函数:从右向左设置默认值,简化函数调用。
  3. 函数重载:通过参数列表的不同实现同名函数的多态性,提高代码可读性。
  4. 系统函数:善用标准库函数(如数学函数、随机数函数)提高开发效率。
  5. 深度原理:理解运行栈与函数调用的执行机制,重视函数声明的类型安全保障。

      函数是 C++ 程序的基本组成单元,掌握函数的各种特性和使用技巧,是编写高效、可维护代码的基础。建议多动手实践本章的代码示例,深入理解函数在内存中的执行机制。

如果有任何问题或建议,欢迎在评论区留言交流!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 思维导图(整体知识框架)
  • 3.1 函数的定义与使用
    • 3.1.1 函数的定义
    • 3.1.2 函数的调用
    • 3.1.3 函数的参数传递
      • 1. 值传递
      • 2. 引用传递
      • 综合案例:学生成绩管理
  • 3.2 内联函数
    • 内联函数的特点
  • 3.3 constexpr 函数
    • constexpr 函数的要求
  • 3.4 带默认形参值的函数
    • 默认参数的规则
    • 错误示例:默认参数设置不当
  • 3.5 函数重载
    • 函数重载的条件
    • 综合案例:计算器的函数重载
  • 3.6 使用 C++ 语言系统函数
    • 常用系统函数及头文件
  • 3.7 深度探索
    • 3.7.1 运行栈与函数调用的执行
      • 栈帧结构示意图
    • 3.7.2 函数声明与类型安全
      • 类型不安全的示例(无函数声明)
      • 类型安全的示例(有函数声明)
  • 3.8 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档