⚙️ C++ 函数基础 - L22 进阶概念

掌握函数定义、参数传递、返回值和作用域

📚 什么是函数?

函数的概念

函数(Function)是一段具有特定功能的、可重用的代码块。它将复杂的任务分解为小的、可管理的部分。

  • 📦 代码复用:一次编写,多次调用
  • 🎯 模块化:将大问题分解为小问题
  • 🔧 易于维护:修改一处,全局生效
  • 📖 提高可读性:函数名说明功能
  • 🧪 便于测试:独立测试每个函数
💡 生活中的类比:
• 函数就像厨房里的搅拌机:输入食材,输出果汁
• 函数就像洗衣机:输入脏衣服,输出干净衣服
• 函数就像自动售货机:投入硬币,获得商品
• 你不需要知道内部如何工作,只需知道如何使用

函数的组成部分

// 函数定义的四个部分 返回类型 函数名(参数列表) { // 函数体:执行的具体操作 return 返回值; // 可选 } // 示例:计算两个数的和 int add(int a, int b) { int sum = a + b; return sum; }

四个关键部分:

  • 返回类型:函数执行后返回的数据类型(void表示无返回值)
  • 函数名:函数的标识符,遵循命名规则
  • 参数列表:传递给函数的数据(可以为空)
  • 函数体:包含具体的执行语句

为什么需要函数?

// ❌ 没有函数:代码重复 int main() { // 第一次计算矩形面积 int length1 = 5, width1 = 3; int area1 = length1 * width1; cout << "面积1:" << area1 << endl; // 第二次计算矩形面积 int length2 = 10, width2 = 7; int area2 = length2 * width2; cout << "面积2:" << area2 << endl; // 第三次计算矩形面积 int length3 = 8, width3 = 4; int area3 = length3 * width3; cout << "面积3:" << area3 << endl; return 0; } // ✅ 使用函数:代码简洁 int calculateArea(int length, int width) { return length * width; } int main() { cout << "面积1:" << calculateArea(5, 3) << endl; cout << "面积2:" << calculateArea(10, 7) << endl; cout << "面积3:" << calculateArea(8, 4) << endl; return 0; }

⚙️ 函数的定义和调用

无参数无返回值的函数

#include <iostream> using namespace std; // 函数定义:打印问候语 void sayHello() { cout << "你好,欢迎学习C++!" << endl; cout << "祝你学习愉快!" << endl; } int main() { // 函数调用 sayHello(); // 第一次调用 sayHello(); // 第二次调用 sayHello(); // 第三次调用 return 0; }
💡 要点:
void 表示没有返回值
• 空括号 () 表示没有参数
• 通过函数名加括号调用:sayHello()

有参数无返回值的函数

#include <iostream> using namespace std; // 函数定义:打印个人信息 void printInfo(string name, int age) { cout << "姓名:" << name << endl; cout << "年龄:" << age << "岁" << endl; cout << "------------------" << endl; } int main() { // 调用函数,传入不同的参数 printInfo("张三", 18); printInfo("李四", 20); printInfo("王五", 19); return 0; }

有参数有返回值的函数

#include <iostream> using namespace std; // 函数定义:计算两个数的最大值 int getMax(int a, int b) { if (a > b) { return a; } else { return b; } } // 函数定义:计算阶乘 long long factorial(int n) { long long result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } int main() { // 使用返回值 int maxVal = getMax(10, 20); cout << "最大值:" << maxVal << endl; // 20 // 直接在表达式中使用 cout << "5的阶乘:" << factorial(5) << endl; // 120 cout << "10的阶乘:" << factorial(10) << endl; // 3628800 return 0; }
🎮 互动实验:函数调用演示

选择不同的函数,查看执行过程和结果

选择函数查看演示...

🛠️ 参数传递方式

值传递(默认方式)

值传递会复制参数的值,函数内部修改不会影响原变量。

#include <iostream> using namespace std; // 值传递:不会修改原变量 void modifyValue(int x) { cout << "函数内:x = " << x << endl; x = 100; cout << "修改后:x = " << x << endl; } int main() { int num = 10; cout << "调用前:num = " << num << endl; modifyValue(num); cout << "调用后:num = " << num << endl; // 仍然是10 return 0; }
💡 值传递特点:
• 安全:不会意外修改原变量
• 效率较低:大数据量时需要复制
• 适合小数据和不需要修改的场景

引用传递

引用传递直接操作原变量,函数内部修改会影响原变量。

#include <iostream> using namespace std; // 引用传递:会修改原变量 void swapValues(int &a, int &b) { int temp = a; a = b; b = temp; } // 使用引用来避免复制大对象 void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { cout << arr[i] << " "; } cout << endl; } int main() { int x = 10, y = 20; cout << "交换前:x = " << x << ", y = " << y << endl; swapValues(x, y); cout << "交换后:x = " << x << ", y = " << y << endl; // x=20, y=10 return 0; }
💡 引用传递特点:
• 高效:不需要复制数据
• 可以修改原变量
• 使用 & 符号声明引用参数
• 适合大数据和需要修改的场景

默认参数

可以为参数设置默认值,调用时可以省略这些参数。

#include <iostream> using namespace std; // 带有默认参数的函数 void greet(string name = "朋友", string greeting = "你好") { cout << greeting << ", " << name << "!" << endl; } // 计算幂运算,指数默认为2 double power(double base, int exponent = 2) { double result = 1; for (int i = 0; i < exponent; i++) { result *= base; } return result; } int main() { // 使用默认参数 greet(); // 你好, 朋友! greet("张三"); // 你好, 张三! greet("李四", "早上好"); // 早上好, 李四! cout << endl; // 默认指数为2 cout << "5的平方:" << power(5) << endl; // 25 cout << "2的立方:" << power(2, 3) << endl; // 8 cout << "3的4次方:" << power(3, 4) << endl; // 81 return 0; }
🎯 参数传递实验

体验值传递和引用传递的区别

输入数字后点击"测试交换"...

🚀 作用域和递归

变量的作用域

作用域决定了变量在程序中可见的范围。

#include <iostream> using namespace std; int globalVar = 100; // 全局变量:整个程序都可访问 void testScope() { int localVar = 50; // 局部变量:只在函数内有效 cout << "函数内 - 局部变量:" << localVar << endl; cout << "函数内 - 全局变量:" << globalVar << endl; } int main() { cout << "主函数 - 全局变量:" << globalVar << endl; testScope(); // cout << localVar << endl; // 错误!localVar在此不可见 // 同名变量:局部变量优先 int globalVar = 200; // 遮蔽全局变量 cout << "主函数 - 局部globalVar:" << globalVar << endl; // 200 return 0; }
💡 作用域规则:
全局变量:在所有函数外定义,整个程序可访问
局部变量:在函数内定义,只在函数内有效
参数变量:也是局部变量
• 同名时,局部变量优先(遮蔽全局变量)
• 尽量避免使用全局变量,容易导致bug

函数重载

同一个函数名可以有多个版本,只要参数列表不同。

#include <iostream> using namespace std; // 重载函数:计算面积 double area(double radius) { return 3.14159 * radius * radius; // 圆面积 } double area(double length, double width) { return length * width; // 矩形面积 } double area(double base, double height, char type) { if (type == 't' || type == 'T') { return 0.5 * base * height; // 三角形面积 } return 0; } int main() { cout << "圆面积(半径5):" << area(5.0) << endl; cout << "矩形面积(长10宽5):" << area(10.0, 5.0) << endl; cout << "三角形面积(底10高5):" << area(10.0, 5.0, 't') << endl; return 0; }

递归函数简介

递归是函数调用自身的编程技巧。

#include <iostream> using namespace std; // 递归计算阶乘 long long factorial_recursive(int n) { // 基准情况(终止条件) if (n <= 1) { return 1; } // 递归调用 return n * factorial_recursive(n - 1); } // 递归计算斐波那契数列 long long fibonacci(int n) { if (n <= 0) return 0; if (n == 1) return 1; return fibonacci(n - 1) + fibonacci(n - 2); } int main() { cout << "5! = " << factorial_recursive(5) << endl; // 120 cout << "10! = " << factorial_recursive(10) << endl; // 3628800 cout << endl; cout << "斐波那契数列前10项:"; for (int i = 0; i < 10; i++) { cout << fibonacci(i) << " "; } cout << endl; return 0; }
💡 递归三要素:
1. 基准情况:什么时候停止递归
2. 递归调用:函数调用自身
3. 问题缩小:每次调用问题规模减小

⚠️ 注意:递归深度过大会导致栈溢出

📝 实战练习

📝 理解测试

以下代码的输出是什么?

#include <iostream> using namespace std; void modify(int &x) { x = x * 2; } int main() { int num = 5; modify(num); cout << num << endl; return 0; }
选择答案查看解析...
💻 综合挑战

题目:编写一个函数库,包含以下功能:
1. 判断质数
2. 计算最大公约数
3. 计算最小公倍数
4. 反转字符串

点击"生成代码框架"查看提示...