什么是函数?¶
在编程中,函数就像一个“代码小工具”,它把一段特定功能的代码封装起来,让我们可以重复使用。比如数学中的函数f(x)=2x,输入x就能得到对应的结果;C++中的函数也是如此,输入一些数据(参数),就能得到一个结果(返回值),或者完成某些操作。
为什么要用函数?最直接的好处是代码复用和结构清晰。比如我们要多次计算两个数的和,直接写一个函数就能避免重复写加法代码,修改也只需要改函数里的逻辑,不用到处找重复的代码。
函数的定义¶
定义一个函数需要包含几个部分:返回值类型、函数名、参数列表和函数体。
基本格式:¶
返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ...) {
// 函数体:具体要执行的代码
return 返回值; // 如果返回值类型是void,return可以省略或只写return;
}
举个例子:计算两数之和¶
// 定义一个函数,接收两个int类型的参数,返回它们的和
int add(int a, int b) { // a和b是形参(形式参数),表示接收的数据
int sum = a + b; // 函数体:计算a和b的和
return sum; // 返回计算结果(必须和返回值类型一致)
}
- 返回值类型:
int表示这个函数会返回一个整数。如果函数不需要返回值,用void(比如打印信息的函数)。 - 函数名:
add,要见名知意(比如计算和用add,交换用swap)。 - 参数列表:
(int a, int b),括号里是函数接收的参数,每个参数需要指定类型和名称。 - 函数体:大括号
{}里的代码,是函数要执行的具体操作。
函数的调用¶
定义好函数后,需要在其他地方“调用”它才能执行。调用函数时,我们需要提供实参(实际传入的参数),实参会被复制给形参。
调用格式:¶
函数名(实参1, 实参2, ...); // 无返回值时直接调用
返回值类型 变量 = 函数名(实参1, 实参2, ...); // 有返回值时接收结果
例子:在主函数中调用add函数¶
#include <iostream>
using namespace std;
// 定义add函数(前面的例子)
int add(int a, int b) {
return a + b;
}
int main() {
int x = 5, y = 3;
// 调用add函数,传入x和y作为实参
int result = add(x, y); // 接收返回值
cout << "5 + 3 = " << result << endl; // 输出:5 + 3 = 8
return 0;
}
关键点:调用时实参的类型和数量必须和函数定义的形参匹配(比如add需要两个int,就不能传一个字符串进去)。
参数传递的几种方式¶
参数传递是函数的核心概念,主要有两种方式:值传递和引用传递(初学者先掌握值传递,引用传递简单了解即可)。
1. 值传递(最常用)¶
值传递是默认的参数传递方式,它会把实参的值复制一份传给形参。此时,形参的修改不会影响实参。
例子:值传递的特点¶
#include <iostream>
using namespace std;
// 值传递:修改形参a不影响实参x
void changeValue(int a) {
a = 100; // 只修改形参a
}
int main() {
int x = 10;
changeValue(x); // 调用函数,传入x
cout << "x的值:" << x << endl; // 输出:x的值:10(实参未被修改)
return 0;
}
为什么? 因为值传递是“复制实参的值给形参”,相当于函数里的a是x的一个“副本”,修改a和x无关。
2. 引用传递(&符号)¶
如果希望函数能修改实参的值(比如交换两个变量),可以用引用传递。引用传递用&表示,形参和实参是同一个变量,修改形参会直接影响实参。
例子:引用传递实现交换功能¶
#include <iostream>
using namespace std;
// 引用传递:形参是实参的“别名”,修改会影响实参
void swap(int &a, int &b) { // a和b是引用,指向实参x和y
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 5, y = 10;
swap(x, y); // 调用时传入x和y的引用
cout << "x = " << x << ", y = " << y << endl; // 输出:x = 10, y = 5
return 0;
}
关键点:引用传递必须用&符号,且调用时实参必须是变量(不能传常量或表达式)。
3. 默认参数(可选参数)¶
在定义函数时,可以给参数设置默认值,调用时如果不传入该参数,就会使用默认值。这能简化调用逻辑。
例子:默认参数¶
#include <iostream>
using namespace std;
// 给第二个参数设置默认值为2
int power(int base, int exponent = 2) {
int result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
int main() {
cout << "3的平方:" << power(3) << endl; // 只传一个参数,使用默认值2,结果=9
cout << "3的4次方:" << power(3, 4) << endl; // 传两个参数,结果=81
return 0;
}
注意:默认参数必须从右往左设置(比如exponent=2必须在base后面),否则编译器会报错。
函数声明与定义顺序¶
如果函数定义在调用它的代码(比如main)之后,需要先声明函数。函数声明告诉编译器“这个函数存在,返回值类型和参数列表是什么”。
例子:函数声明¶
#include <iostream>
using namespace std;
// 函数声明:先告诉编译器有这个函数
int multiply(int a, int b); // 分号结尾,不需要函数体
int main() {
int result = multiply(4, 5);
cout << "4 * 5 = " << result << endl; // 输出:20
return 0;
}
// 函数定义:实现函数逻辑
int multiply(int a, int b) {
return a * b;
}
总结¶
- 函数定义:返回值类型+函数名+参数列表+函数体,要明确功能。
- 函数调用:用函数名+实参调用,接收返回值(无返回值用
void)。 - 参数传递:
- 值传递:形参是实参的副本,修改不影响实参。
- 引用传递:用
&,形参即实参,修改影响实参。 - 默认参数:简化调用,注意从右往左设置。
练习:试着写一个包含add(两数相加)、swap(交换两数)和power(计算多次幂)的小程序,熟悉函数的定义和调用!