函数指针:
一个运行的程序在内存中的布局,分为四个区域。Data Area 、Heap Area和Stack Area——数据区域;Code Area称为代码区域。指向数据区域的指针称为数据指针。指向代码区域的指针称为指向函数的指针(简称函数指针)。
区别:函数指针——Function Pointer ; 返回指针类型的函数是指针函数Pointer Function。
函数是以参数个数、参数类型、参数顺序甚至返回类型的不同来区分不同类型。
函数指针的类型必须接受编译器的检查。
函数指针的定义形式看起来比较复杂,通常采用typedef来简化。
typedef int (*Fun)(int a,int b);
任何函数内不能嵌套定义其他函数,也即不村子子函数的概念。数据环境的操作统一由栈机制来实施。
递归函数在运行中,其调用与被调用函数的指令代码是同一个函数副本,只不过各个不同运行中的调用点,作为状态的一部分,在栈中被分别保护起来。
C++的函数机制决定了递归操作的可能性与形式。
递归条件:
1、递归函数是有条件地调用自身,该条件就是递归的停止条件;
2、递归函数中必须有完成终极任务的语句序列,以使函数有意义;
3、递归函数有递归调用语句。
递归函数在时空开销上的不利局面势必影响性能。非递归函数虽然效率高,但有时候却比较难编程,而且相对来说可读性差。
低级编程强调性能,抽象编程(相对较高层次)强调可读。
函数重载:
重载的目的是通过自然描述函数名称来简化编程和增强程序的可读性。
只要参数个数不同,参数类型不同,参数顺序不同,参数就可以重载。然而,返回类型不同则不允许函数重载。
C++按步骤找到匹配并调用函数:
1.寻找一个严格匹配,如果找到了,就用那个函数;
2.通过相容性类型的隐式转换寻求一个匹配,如果找到了,就用那个函数;
3.通过用户定义的转换寻求一个匹配,若能查出有唯一的一组转换,就用那个函数。
C++允许int型到long型,int型到double型的隐式转换。但若必须在两者之间抉择时,则会引起错误。
C++用名称压轧(name mangling)技术来改变函数名,区分参数不同的同名参数。
函数参数默认值只能从后往前设置:
void func(jint a=1, int b, int c=3, int d=4);错b和a的位置违规
void func(int a, int b=2, int c=3, int d=4);OK
无名参数(Nameless Parameters)
函数的声明和定义中,都可以省略形参名,例如:void point(int a, int);如果在函数定义中也省略形参名,则函数体中就不能使用这个形参了。
若开始用了一个函数形参,后来发现不续约用它,就可以将它无名化,而且不需要改动那些调用该函数以前版本的代码。
总结:函数是程序的基本组成。本质上基于过程程序设计就是以函数作为基本过程单位的。
函数的灵活多样性反映在其副作用上,副作用又是反映在函数的指针和引用传递上。人们利用指针和引用的参数传递,大大地提高了数据传递的效率。但任何有意无意的越权数据和代码访问都是指针造成的。数据和代码的越权访问是程序缺陷所在。
C++中函数机制是靠栈结构来支撑的,不同的编译器处理函数的手法大同小异,栈机制使得函数的执行代码与函数的数据区域相分离,使得函数传递调用成为可能。然而,递归调用全套复制了函数的局部数据,因而对于深度的递归可能在时间和空间上陷入困境。
main函数是操作系统调用的函数,因而它是唯一不能由其他函数调用的函数,它的返回类型一定是int型,否则就不是标准的。但是main函数中得返回语句可以网开一面地免去——特权。main函数所带的参数规定了操作系统对它数据传递的形式,借此参数,程序可以处理运行命令中得附加信息。重定向是操作系统启动命令的功能之一。