函数 - GESP C++ 四级
引入
在数学中,我们有函数的概念,例如就是一个函数。在编程中,同样有函数的概念。函数是一个程序段的总称。通过函数,我们可以略去大量重复但有细微差别的代码。例如下面这段代码:
#include <iostream>
using namespace std;
int x, y;
int main() {
cin >> x >> y;
x += (x + 1) / 2 + (y + 3);
y += (y + 1) / 2 + (x + 3);
cout << x << y;
return 0;
}如果我们x += (x + 1) / 2 + (y + 3) 这步操作封装成一个函数f(x, y),那么我们就只需要分别调用f(x, y) 和f(y, x) 就可以实现上述的计算效果。
上面的例子可能不太明显。当处理大段代码,或者需要递归执行操作时,才是函数大显神威的时候。
函数的定义与调用
在 C++ 中,可以通过下面的格式来定义一个函数:
返回值类型 函数名(参数类型 参数名, ...) {
// 函数内容
}和数学类似,参数是调用函数时传给函数的一个变量或值,相当于给他起了个别名。而返回值是函数执行完成后返回的值,可以赋值给变量等,在函数内部使用 return来返回值,格式return 返回值。return 执行后函数后面的代码都会停止执行。如果函数是一个无返回值的函数,但是在函数中想要停止函数执行,可以使return; ,即return 后不填返回值。
如果没有返回值,返回值类型需void ;如果没有参数,小括号里为空。
在定义函数后,可以使函数名(参数, ...)来调用函数。例如,下面代码对上面代码进行了一个优化:
#include <iostream>
using namespace std;
int x, y;
int f(int a, int b) {
return (a + 1) / 2 + (b + 3);
}
int main() {
cin >> x >> y;
x += f(x, y);
y += f(y, x);
cout << x << y;
return 0;
}在学习引用传值后,我们还能进一步优化这段代码。
形参与实参、作用域
在上面的这段代码中,我们f 函数内定义了两个参数a 和b 。这两个参数是没有实际的值的,只是形式上的参数,我们称为形式参数,简称形参。而在调用f函数时,我们传入了两个参数a 和b ,这两个参数是有实际的值,我们称为实际参数,简称实参。
在 C++ 中,我们在函数内部定义的变量是一种临时的变量,不能被函数外部所访问。但是全局变量却可以被任何函数访问,这就牵扯到了作用域的问题。可以简单的这样理解:除了全局作用域外,每对大括号内部是一个作用域,作用域内还可以套作用域。我们称外层的作用域级别高,内层的作用域级别低。一个作用域中的代码只能访问当前作用域中的变量,或者包含当前作用域的作用域(也就是级别比当前作用域高的作用域)的变量。任何地方都可以访问全局作用域中的变量。
函数参数传递的概念
在阅读本节前,默认你已经了解了指针类型的概念和使用。
在 C++ 中,函数参数有三种传递方式:值传递、引用传递和指针传递。
值传递是指只传入一个值,格式为参数类型 参数名。也就是说,函数内部使用的形参是实参的一个备份,修改形参不会影响到实参。
引用传递是指传入变量的引用,格式为参数类型 &参数名。也就是说,函数内部使用的形参是实参的一个别名,对形参的修改会同步给对应的实参。
指针传递传入的是一个指针类型的变量,格式为参数类型 *参数名 ,这里的参数类型是指针指向的变量的类型,参数名是函数内这个指针形参的名称。在函数内部需要使* 对指针进行解引用来获取值,和引用传递类似,解引用形参后对变量值的修改会同步给实参对应的变量的值。
下面给出一个例子,以帮助你更好地理解三种传递方式。同样,这段代码是在上面那段代码的基础上修改的:
#include <iostream>
using namespace std;
int x, y;
void f1(int a, int b) {
a = (a + 1) / 2 + (b + 3);
}
void f2(int &a, int &b) {
a = (a + 1) / 2 + (b + 3);
}
void f3(int *a, int *b) {
*a = (*a + 1) / 2 + (*b + 3); // 因为传的是指针,所以要解引用
}
int main() {
cin >> x >> y;
f1(x, y); // 不会改变x和y的值
f2(x, y); // 会改变x和y的值
f3(&y, &x); // 传的是指针,会改变x和y的值
cout << x << y;
return 0;
}总结
函数是编程中的一个重要概念,可以帮助我们便捷地复用整段代码。学习函数,有利于我们更好、更快、更便捷地进行编程。函数在一些算法中也有应用。作为基础语法的一部分,我们必须熟练地掌握函数。