C++函数知识点详解
编程小白的全方位指南 – 通俗易懂的大白话解释
函数是C++编程的基础构建块,理解函数是掌握编程的关键一步
函数的基本概念
什么是函数?
函数就像一台小型机器:给它一些材料(输入),它会执行特定的任务,然后给你一个结果(输出)。
为什么要用函数?
- 代码复用:一次编写,多次使用
- 模块化:把大问题拆解成小问题
- 易于维护:修改一处,影响全局
- 提高可读性:通过名字知道功能
函数的组成
- 返回类型(函数产出什么)
- 函数名(机器的名称)
- 参数列表(需要什么材料)
- 函数体(如何加工材料)
int sum(int a, int b) { // 函数头
int result = a + b; // 加工材料
return result; // 产出结果
} // 函数结束
int result = a + b; // 加工材料
return result; // 产出结果
} // 函数结束
函数声明与定义
函数声明(原型)
就像商品的广告:告诉编译器这个函数的存在,但不说明具体怎么做。
// 告诉编译器:我有一个叫multiply的函数
// 它需要两个double参数,返回一个double结果
double multiply(double x, double y);
// 它需要两个double参数,返回一个double结果
double multiply(double x, double y);
函数定义
这是函数的完整实现,说明函数具体如何工作。
double multiply(double x, double y) {
return x * y; // 实际工作内容
}
return x * y; // 实际工作内容
}
重要区别:声明是”我会做这件事”,定义是”我是这样做的”。
声明通常放在头文件(.h)中,定义放在源文件(.cpp)中。
参数与返回值
参数传递
- 值传递:给函数一个副本,原数据不受影响
- 引用传递:给函数原始数据的访问权限,可以修改原数据
- 常量引用:给函数查看数据的权限,但不能修改
void valueExample(int a) { a = 10; } // 不影响外部
void refExample(int &b) { b = 20; } // 修改外部变量
void constRefExample(const int &c) {
// c = 30; // 错误!不能修改常量引用
}
void refExample(int &b) { b = 20; } // 修改外部变量
void constRefExample(const int &c) {
// c = 30; // 错误!不能修改常量引用
}
返回值
函数完成任务后给出的结果:
- 可以返回基本类型(int, double等)
- 可以返回自定义类型(结构体、类)
- 可以返回指针或引用(但要小心生命周期)
- void表示不返回任何值
函数重载
同一个函数名,不同的参数列表,实现不同的功能。
// 两个整数的加法
int add(int a, int b) {
return a + b;
}
// 三个整数的加法
int add(int a, int b, int c) {
return a + b + c;
}
// 两个浮点数的加法
double add(double x, double y) {
return x + y;
}
int add(int a, int b) {
return a + b;
}
// 三个整数的加法
int add(int a, int b, int c) {
return a + b + c;
}
// 两个浮点数的加法
double add(double x, double y) {
return x + y;
}
注意:函数重载不能仅通过返回类型不同来区分,参数列表必须不同。
内联函数
对于非常小的函数,使用inline关键字可以建议编译器将函数体直接插入调用处,避免函数调用的开销。
inline int max(int a, int b) {
return (a > b) ? a : b;
}
return (a > b) ? a : b;
}
使用场景
- 函数体非常小(1-5行)
- 被频繁调用
- 需要避免函数调用开销
注意:inline只是给编译器的建议,编译器可能会忽略。过度使用内联函数可能导致代码膨胀。
默认参数
给参数设置默认值,调用时可以不传递这些参数。
void greet(string name, string prefix = “Hello”, string suffix = “!”) {
cout << prefix << ", " << name << suffix << endl;
}
greet(“Alice”); // 输出: Hello, Alice!
greet(“Bob”, “Hi”); // 输出: Hi, Bob!
greet(“Charlie”, “Hey”, “!!!”); // 输出: Hey, Charlie!!!
cout << prefix << ", " << name << suffix << endl;
}
greet(“Alice”); // 输出: Hello, Alice!
greet(“Bob”, “Hi”); // 输出: Hi, Bob!
greet(“Charlie”, “Hey”, “!!!”); // 输出: Hey, Charlie!!!
规则
- 默认参数必须从右向左设置
- 不能在声明和定义中同时指定默认值(通常在声明中指定)
- 默认值可以是常量、全局变量或函数
函数调用过程可视化
1. 程序执行到函数调用处
2. 保存当前执行状态
3. 传递参数
4. 执行函数体
5. 返回结果
6. 恢复之前状态继续执行
#include <iostream>
using namespace std;
// 函数声明
int square(int num);
int main() {
int number = 5;
cout << square(number) << endl; // 函数调用
return 0;
}
// 函数定义
int square(int num) {
return num * num;
}
using namespace std;
// 函数声明
int square(int num);
int main() {
int number = 5;
cout << square(number) << endl; // 函数调用
return 0;
}
// 函数定义
int square(int num) {
return num * num;
}
递归函数
函数自己调用自己,用于解决可以分解为相似子问题的问题。
int factorial(int n) {
if (n == 0 || n == 1) { // 基本情况
return 1;
}
return n * factorial(n – 1); // 递归调用
}
if (n == 0 || n == 1) { // 基本情况
return 1;
}
return n * factorial(n – 1); // 递归调用
}
递归要点
- 必须有终止条件(避免无限递归)
- 每次递归应向基本情况靠近
- 递归层次不宜过深(可能栈溢出)
函数指针
指向函数的指针,可以将函数作为参数传递。
// 声明一个函数指针类型
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int calculate(int x, int y, Operation op) {
return op(x, y); // 通过函数指针调用函数
}
int main() {
cout << calculate(3, 4, &add) << endl; // 输出 7
cout << calculate(3, 4, &multiply) << endl; // 输出 12
return 0;
}
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int calculate(int x, int y, Operation op) {
return op(x, y); // 通过函数指针调用函数
}
int main() {
cout << calculate(3, 4, &add) << endl; // 输出 7
cout << calculate(3, 4, &multiply) << endl; // 输出 12
return 0;
}
Lambda表达式
C++11引入的匿名函数,用于创建临时的、一次性的函数对象。
// 基本形式
[](int a, int b) -> int {
return a + b;
};
// 使用示例
auto sum = [](int a, int b) { return a + b; };
cout << sum(3, 4) << endl; // 输出 7
// 捕获外部变量
int factor = 2;
auto multiplier = [factor](int x) { return x * factor; };
cout << multiplier(5) << endl; // 输出 10
[](int a, int b) -> int {
return a + b;
};
// 使用示例
auto sum = [](int a, int b) { return a + b; };
cout << sum(3, 4) << endl; // 输出 7
// 捕获外部变量
int factor = 2;
auto multiplier = [factor](int x) { return x * factor; };
cout << multiplier(5) << endl; // 输出 10