C++函数
本期我们讨论的是 C++ 中的函数。
函数到底是什么呢,函数就是我们写的代码块,被设计用来执行特定的任务,以后我们学习 class 类的时候,这些块会被称为方法,但是当我说到函数时,我们讲的可不是 C++ 类里面的方法。
01 函数能干什么
对我们来说,使用函数是很常见的,避免代码重复。我们不想重复写相同的代码,当然,如果我们也可以复制和粘贴很多代码,但会导致巨大的混乱,这也意味着如果我们决定改变一些代码,我们必须在所有这些地方改变它,我们粘贴的地方,那维护这些代码简直就是灾难,所以我们把我们要做的事情写成一个函数,然后可以多次调用它。
如果需要的话,你可以认为函数有一个输入,一个输出,尽管他们可能并不需要这么做。我们可以为函数提供一定的参数,函数可以为我们返回值。
02 定义函数
假设我们想把两个数相乘,我们想写出这样的一个函数。
#include <iostream>
using namespace std;
int multiplyNumber(int num1,int num2)
{
return num1*num2;
}
int main()
{
int data = multiplyNumber(4,5);
cout<<"data 积为:" <<data<<endl;
return 0;
}
我们对上面的代码做一些详细的解释。
首先写的是所谓的返回值 int
,也就是说,这就是这个函数的返回类型,因为是两个整数相乘,这当然会得到一个整数 ;然后给出函数名 multiplyNumber
,它有两个参数 a
和 b
,这些就是我们要乘的数,它们的类型都是 int
。然后给出函数体,它会返回 a*b 。
这样你就得到一个函数,它有两个都是整数的参数,该函数的功能是返回两者的乘积。
我们不一定非要提供参数,例如,我可以不提供任何参数,直接返回 5*8 ,这仍然是一个返回整数的函数,但它没任何参数。
我们也可以让函数不返回任何东西,我们通过写 void 作为返回类型来实现,void 意思是啥也没有,所以我们可以这样做。
03 调用函数
如何调用这个函数呢?调用一个函数非常简单,我们直接看下面的例子。
对上面的代码我们做一些解释。
首先我们定义了一个变量 data,来装这个结果,然后直接写函数的名字加括号就可以完成调用函数,括号里面的数字就是函数需要的两个参数,返回值 data保存 a*b 的结果,最后我们将结果输出到终端。
04 为什么要用函数
所以,为什么要用函数呢?看起来代码还更多了一些。
让我们把情况说的更详细些,假设我要做一堆的乘法,我想把它们都记录到控制台,在没有函数的情况下,下面的情况这样看起来会很乱。
如果你运行了这些代码,你会发现我犯了一些错误,我想说的是,其实这种情况经常发生。人们复制和粘贴代码块, 然后忘记改变一个小细节,比如变量名没改过来,在某些情况下程序如果正常运行的话,你就有可能注意不到,直到它在某个地方出错了,你才会知道。
上面的多段代码大部分内容基本差不多,基本的区别就是参与乘法的数字不同。这就很难受了。
让我们为这个重复的过程创建一个函数。
函数定义好后,我们要做的就是调用这个函数。
如果启动这个程序, 你可以看到,在这里可以获得正确的值,这是一个很简单的例子,我们获得了一个非常干净、易于阅读的程序。
通过以上给分析过程,我们有效地证明了函数是真的非常重要的。你的目标应该是将你的代码分开成很多函数。
然而, 有一件事我想强调,也不要把你的代码每一行都拆成函数,对任何人都没有好处的代码,这很难维护,您的代码将看起来凌乱不堪,它会让你的程序变慢。
原因是每次我们调用函数时,编译器生成一个call 指令,这基本上意味着,在一个运行的程序中,我们需要创建一个堆栈结构,这意味着我们必须把像参数这样的东西推进堆栈,我们还需要将一个叫做返回地址的东西,然后我们要做的是跳到二进制执行文件的不同部分,以便开始执行我们的函数指令。为了将 push 进去的结果返回,我们得回去到最初调用函数之前。就像在内存中跳跃来执行函数,跳跃和执行这些都需要时间,这些会减慢我们的程序。当然前提是保持我们当前的函数是作为一个实际的函数,而不是做内联inline
的工作(我们会在未来深入讨论内联)。
05函数的目的
我说这些都是因为不想让你们对于每一行代码都去创建函数,不要做那么搞笑的事情,编码多了你才能明白哪里你会需要一个函数,但基本上如果你看到自己在多次做一项共同的任务,那么基本可以为此创建一个函数,函数的主要目的是防止代码重复,我们不希望复制粘贴代码。