函数的作用是
拆分任务和方便复用
函数高内聚,低耦合(独立)
在函数使用时一定要让其和主函数分步骤,分工明确
ex,main函数里头是负责打印
自定义函数负责判断
函数:
函数包括:函数名,函数参数,函数返回类型,三要素
用函数三要素+排除法可以让我们更好的认识奇怪函数的部分:
ex : 分析 void (*singnl ( int , void (*)(int) ))(int)
显然 :( int , void (*)(int) )是参数,后者是函数指针类型(返回viod)
剩下的:void (*singnl )(int) , singnl是函数名
剩下的:void (*)(int) ,只剩下函数返回类型这一种可能了,这个就是singnl函数的返回类型
void函数
void的函数表示不反回类型到main函数中,或没有定义形式参数
ex: void game(void) ;
1.若不写前面的void 函数默认返回整形
2.若不写后面的void 后果图
若没有要接收的形式参数,要老老实实加 void
3.后面什么都没有的跟的return;语句搭配void使用
(即return空气)
自定义函数:
自定义的的函数是 为了方便执行子任务
格式: { 类型 , 函数名(形式参数) }
{ 函数内容(库函数的内容已经在头文件里) }
有关于实参和形参请看书
(地址,内存)
若要传地址,则要用指针变量接收(图)
特别的:在传递字符的时候字符会自动对应其的ASCII码值
重量级:传值调用和传址调用
传值调用时:形参是实参的一分拷贝,它们的地址不同,改变形参不会影响实参
传址调用时:形参和实参的地址是一样的,改变形参就是该变实参(这就是数组传参 的原理,一般会传一个数组名进去)
二维数组传参表示行和列是不用傻乎乎的直接写一个数字
{
sizeof ( arr ) / sizeof ( arr [0] ) 表示行数
sizeof ( arr[0] ) / sizeof ( arr [0][0] ) 表示列数
}
嵌套调用和链式访问:(不好写笔记所以到书上去看)
注意;在其过程中函数的返回值
函数的定义和声明,企业的分模块应用(不好写笔记所以到书上去看)
1.在,只简单声明函数时语句末尾时是要加;号的
2.在写入函数的主体时不要加;号
函数递归(函数自己调用自己参数不一样而已)
作用:把大型复杂的问题转化为一个与原问题相似,规模小的子问题来解决
思想:以大化小,递推,回归
条件(递归首先就要考虑这些)
1:不满足限制条件时,递归不再继续
2:随着递归的进行会越来越接近限制条件
不然会造成栈溢出(stack overflow)这是一个网站
递推回归进行顺序很有意思
蓝色表示:函数递推,红色表示回归
我们要知道:1:函数从哪里来的回到哪里去
2:在上图中每个函数都有对应接受的形式参数n
2.右边的图与内存的内容相互联系 每一次函数调用都要申请一块内存空间在暂时保存函数(作用后会销毁)这个就叫函数栈帧(这也是递归容易栈溢出的原因)
结语:
1.递归的优缺点明显,到底改用递归还是迭代要根据具体情况而定
2. 以大化小思路一定要清晰:书上打印数字和斐波那契数列的这种以大化小的思路非常好
回调函数(函数指针的应用):
把一个函数的地址作为参数,传给另一个函数,这个通过另一个函数而被调用的函数就是回调函数。
特点:根据判断来调用不同的函数
作用:1.在多个回调函数成分相似的时候,可以用另一个函数来一起实现回调函数的调用
这就减少了赘余
2.回调函数可以通过判断决定传哪个函数的地址(即使用哪个函数),这样子就实
现类似于if语句的分支功能
例子 calc (add) calc(sub) calc(div) calc(mul)
add sub div mul 这四个函数都是两个参数,都返回整形,所以它们的成分相似
注意:由于函数的地址作为实参,所以另一个函数的形参是函数指针类型。(形参要接受什么类型就要什么类型的变量)
这个以calc举例: calc ( int (*p)(int , int) ){p是形参的名字}