16.函数

一、前言

函数非常重要,并且我们在数学中早就接触过函数了。

比如,明明y=2x+5这样简单的函数,为什么数学书上常常会出现下面这样的写法呢?

y=f(x)
f(x)=2x+5

我相信很多人以前其实是根本没有细想过的,甚至觉得这明显就是多此一举。

但待你深入学习数学、乃至其它学科,逐渐你会发现,这样写是有其原因的。

任何领域想要长足的发展,都需要有一定的体系结构,而这些体系结构中会有大量重复、低层次的内容,如果不将其压缩,就会造成后续升级繁琐。

比如,乘法就是对加法的压缩,当你想要计算100*100时,你不会想到用100个100去相加,因为那样太繁琐。

同样的,专业领域一般都有属于自己的专有名词,比如计算机领域就有硬盘内存等,它们的作用同样是压缩信息,这样你就不用每次交流都说出一大堆描述性的词来描述这个东西。

也许例子不太恰当,但想来你应该能理解我的意思。

函数对于编程的意义很大程度上也在于此:压缩低层次、相对固定不变的内容,日后直接通过函数名使用即可。

二、深入理解

虽然不同语言中对于函数的实现方法并不相同,但大体可以将函数分为三个部分:

  1. 参数
  2. 内部执行语句
  3. 返回值

也就是说,只要有了上面这三个部分,其实就可以定义一个函数了,比如C/C++中的函数:

返回值 name(参数){
	执行语句
}

比如rust中的函数:

fn funname(参数)-> 返回值{
	执行语句
}

函数名只是函数的一个标识,是用来寻找这个函数位置的,比如很多语言中都存在匿名函数,就是只使用一次的函数,那就没必要使用函数名,因为它并不是必要的。

更进一步抽象的说,函数其实你也可以理解为一个对象,而函数名,实际上就是这个对象的名称,就和普通的变量没什么区别。

这一点在js代码中就非常常见:

let a=10;
let f=()=>{}

上面这句话就是让f变量等于一个函数,()中存放函数参数,{}中存放执行语句,至于返回值则不需要写,因为js中是在运行时推断的。

上面介绍的都是声明函数,也就是告诉程序我写了这个函数,而想要执行它,基本都是通过下面这种代码形式:

int ret=funName(参数);

也就是通过函数名+参数的形式来执行函数,然后将执行的结果交给最前面的变量。

对于函数来书,很多语言还存在函数重载,典型的代表就是C++,它可以允许你用一个函数名定义多个函数。

但事实上,这多个函数依旧是不同的函数,并且变量名也不会相同,因为C++编译器在编译的时候会根据你函数的参数来修改你的函数名。

这也是为什么C++中重载函数的参数个数、类型、顺序不能完全相同的原因。

至于类函数,其实也是一个普通的函数,只不过它指定了第一个参数为this指针,也就是当前变量的实例,且不需要我们填。

比如一个类:

class Test{
	public:
	void fun(int a){}
}

如果能拿到fun函数的地址,那么下面两种写法其实是等价的:

Test t;
t.fun(100);

pfun=&fun; //假设拿到了fun函数的地址
pfun(&t,100);//与上面写法实际上是等价的。

这在rust、go等现代化语言中就可以很好的看出来,它们不再支持类,但允许你使用结构体绑定函数。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux