C++ 函数基础
什么是函数?
函数是C++程序的基本构建块,是一段执行特定任务的代码块。函数有助于我们实现代码的模块化,提高代码的可重用性和可维护性。通过函数,我们可以将复杂的程序分解成更小、更易于管理的部分。
函数就像是一个小型的程序,它接收输入(参数),执行特定的操作,然后返回一个结果(返回值)。
- 提高代码可重用性
- 降低代码复杂度
- 使程序更易理解和维护
- 支持团队协作开发
函数的基本语法
在C++中,函数的基本语法如下:
返回类型 函数名(参数列表) {
// 函数体
// 执行的代码
return 返回值; // 如果有返回值的话
}
例如,一个简单的加法函数:
int add(int a, int b) {
int sum = a + b;
return sum; // 返回两个数的和
}
函数声明与定义
在C++中,函数需要先声明后使用。函数声明告诉编译器函数的名称、返回类型和参数类型,而函数定义则包含了函数的具体实现。
函数声明
函数声明也称为函数原型,通常放在主函数之前或头文件中:
int add(int a, int b); // 函数声明
函数定义
函数定义包含函数的完整实现:
int add(int a, int b) { // 函数定义
return a + b;
}
完整示例
#include <iostream>
using namespace std;
// 函数声明
int add(int a, int b);
int main() {
int num1 = 5;
int num2 = 3;
int result = add(num1, num2); // 函数调用
cout << "Sum: " << result << endl;
return 0;
}
// 函数定义
int add(int a, int b) {
return a + b;
}
输出:
Sum: 8
参数传递
C++提供多种向函数传递参数的方式:
值传递
当使用值传递时,函数接收参数值的副本。对参数的修改不会影响原始值。
void modifyValue(int x) {
x = x * 2; // 修改不会影响原始变量
}
int main() {
int num = 10;
cout << "Before: " << num << endl;
modifyValue(num);
cout << "After: " << num << endl; // 输出仍为10
return 0;
}
输出:
Before: 10
After: 10
引用传递
引用参数是变量的别名,对引用的修改会直接影响原始变量:
void modifyValue(int &x) {
x = x * 2; // 修改会影响原始变量
}
int main() {
int num = 10;
cout << "Before: " << num << endl;
modifyValue(num);
cout << "After: " << num << endl; // 输出为20
return 0;
}
输出:
Before: 10
After: 20
指针传递
也可以通过指针传递参数,这样函数可以修改调用者提供的变量:
void modifyValue(int *x) {
*x = *x * 2; // 修改指针指向的值
}
int main() {
int num = 10;
cout << "Before: " << num << endl;
modifyValue(&num); // 传递变量地址
cout << "After: " << num << endl; // 输出为20
return 0;
}
输出:
Before: 10
After: 20
返回值
函数可以返回一个值给调用者。返回类型在函数声明时指定:
int square(int x) {
return x * x; // 返回x的平方
}
如果函数不需要返回值,可以使用void
关键字作为返回类型:
void greet() {
cout << "Hello, World!" << endl;
// 无需返回值
}
返回多个值
C++不直接支持返回多个值,但可以通过以下方法实现:
- 使用结构体或类
- 使用引用参数
- 使用
std::tuple
或std::pair
(C++11及以上)
例如,使用std::tuple
返回多个值:
#include <tuple>
std::tuple<int, int> divideAndRemainder(int dividend, int divisor) {
int quotient = dividend / divisor;
int remainder = dividend % divisor;
return std::make_tuple(quotient, remainder);
}
int main() {
int dividend = 17;
int divisor = 5;
auto result = divideAndRemainder(dividend, divisor);
int quotient = std::get<0>(result);
int remainder = std::get<1>(result);
cout << dividend << " / " << divisor << " = ";
cout << quotient << " remainder " << remainder << endl;
return 0;
}
输出:
17 / 5 = 3 remainder 2
默认参数
C++允许为函数参数设置默认值,如果调用时没有提供这些参数,将使用默认值:
void printMessage(string message, int times = 1) {
for (int i = 0; i < times; i++) {
cout << message << endl;
}
}
int main() {
printMessage("Hello"); // 使用默认参数,打印一次
printMessage("Hi there", 3); // 打印三次
return 0;
}
输出:
Hello
Hi there
Hi there
Hi there
- 默认参数必须从右向左指定,不能跳过参数
- 函数声明和定义只能有一个地方指定默认参数,通常在声明中指定
函数重载
C++允许多个函数使用相同的名称,只要它们的参数列表不同(参数数量或类型不同)。这称为函数重载。
// 两个整数相加
int add(int a, int b) {
return a + b;
}
// 三个整数相加
int add(int a, int b, int c) {
return a + b + c;
}
// 两个浮点数相加
double add(double a, double b) {
return a + b;
}
int main() {
cout << add(5, 3) << endl; // 调用第一个函数
cout << add(5, 3, 2) << endl; // 调用第二个函数
cout << add(5.2, 3.7) << endl; // 调用第三个函数
return 0;
}
输出:
8
10
8.9
内联函数
内联函数是一种请求编译器在调用点直接展开函数代码,而不是生成函数调用的优化技术。使用inline
关键字声明:
inline int max(int a, int b) {
return (a > b) ? a : b;
}
内联是一个请求,不是命令。编译器可能会忽略这个请求,特别是当函数太大或太复杂时。
递归函数
递归函数是一个直接或间接调用自身的函数。递归是解决某些问题的强大技术。
计算阶乘的递归函数示例:
int factorial(int n) {
if (n <= 1) { // 基本情况
return 1;
} else {
return n * factorial(n - 1); // 递归调用
}
}
int main() {
cout << "5! = " << factorial(5) << endl;
return 0;
}
输出:
5! = 120
递归函数必须有一个基本情况(终止条件),否则会导致无限递归,最终导致栈溢出。
实际案例:温度转换应用
让我们创建一个小应用程序,使用函数来进行不同温度单位之间的转换:
#include <iostream>
using namespace std;
// 函数声明
double celsiusToFahrenheit(double celsius);
double fahrenheitToCelsius(double fahrenheit);
double celsiusToKelvin(double celsius);
double kelvinToCelsius(double kelvin);
void displayMenu();
void processChoice(int choice);
int main() {
int choice;
do {
displayMenu();
cout << "选择功能 (0-4): ";
cin >> choice;
if (choice >= 1 && choice <= 4) {
processChoice(choice);
} else if (choice != 0) {
cout << "无效选择,请重试。" << endl;
}
} while (choice != 0);
cout << "感谢使用温度转换程序!" << endl;
return 0;
}
// 显示菜单
void displayMenu() {
cout << "\n温度转换程序\n";
cout << "-------------------\n";
cout << "1. 摄氏度转华氏度\n";
cout << "2. 华氏度转摄氏度\n";
cout << "3. 摄氏度转开尔文\n";
cout << "4. 开尔文转摄氏度\n";
cout << "0. 退出\n";
cout << "-------------------\n";
}
// 处理用户选择
void processChoice(int choice) {
double temp, result;
cout << "输入温度值: ";
cin >> temp;
switch (choice) {
case 1:
result = celsiusToFahrenheit(temp);
cout << temp << " °C = " << result << " °F" << endl;
break;
case 2:
result = fahrenheitToCelsius(temp);
cout << temp << " °F = " << result << " °C" << endl;
break;
case 3:
result = celsiusToKelvin(temp);
cout << temp << " °C = " << result << " K" << endl;
break;
case 4:
result = kelvinToCelsius(temp);
cout << temp << " K = " << result << " °C" << endl;
break;
}
}
// 摄氏度转华氏度
double celsiusToFahrenheit(double celsius) {
return (celsius * 9.0/5.0) + 32;
}
// 华氏度转摄氏度
double fahrenheitToCelsius(double fahrenheit) {
return (fahrenheit - 32) * 5.0/9.0;
}
// 摄氏度转开尔文
double celsiusToKelvin(double celsius) {
return celsius + 273.15;
}
// 开尔文转摄氏度
double kelvinToCelsius(double kelvin) {
return kelvin - 273.15;
}
示例交互:
温度转换程序
-------------------
1. 摄氏度转华氏度
2. 华氏度转摄氏度
3. 摄氏度转开尔文
4. 开尔文转摄氏度
0. 退出
-------------------
选择功能 (0-4): 1
输入温度值: 25
25 °C = 77 °F
温度转换程序
-------------------
1. 摄氏度转华氏度
2. 华氏度转摄氏度
3. 摄氏度转开尔文
4. 开尔文转摄氏度
0. 退出
-------------------
选择功能 (0-4): 0
感谢使用温度转换程序!
总结
函数是C++程序设计中最基本也是最重要的概念之一。通过函数,我们可以:
- 将程序分解成小的、可管理的组件
- 避免代码重复
- 提高代码的可读性和可维护性
- 支持代码的重用
我们学习了函数的定义和声明、参数传递方法(值、引用和指针)、返回值、默认参数、函数重载、内联函数和递归函数等内容。
练习
- 编写一个函数计算两个整数的最大公约数。
- 编写一个函数判断一个数是否为素数。
- 创建一个简单的计算器程序,使用函数实现加、减、乘、除四则运算。
- 编写一个函数,接受一个整数数组和其大小,返回数组中的最大值和最小值(尝试使用多种方法返回多个值)。
- 实现一个递归函数计算斐波那契数列的第n项。