一、代码写成函数的好处
1.提高代码的复用性,可以直接调用函数
2.提高代码的维护性,函数应具有独立的功能,避免在函数内调用其他的函数
3.迭代开发
二、函数的三要素:函数名,形参,返回值
1、函数名
函数名也是一个指针常量,保存的是函数的地址
函数名应当具有自注释性,即函数名应当体现出函数的功能,这样可以提高代码的可读性
但是,用“_”连接的单词个数不能超过5个
2.形参
函数的调用要经过以下几个步骤:
①通过函数名找到函数的入口地址
②给形参分配空间
③传值:把实参变量对应空间的值传给形参
修改实参:读实参变量对应内存空间的值时,传实参变量名
不修改实参:写实参变量对应内存空间的值时,传实参变量地址
④执行函数体里的语句
⑤函数返回并释放空间
命令行参数:即主函数的形参,main(int argc, char *argv[])
argc:表示传进的参数的个数
*argv[]:是一个指针数组,所有传进来的参数都保存在这个数组中
由于其会将命令行的执行命令也算作一个参数,所以真正的参数从argv[1]开始
3.返回值
①返回值的注意事项
在函数中,不能返回局部变量的值,原因是,函数执行完毕后,局部变量会被释放掉,所以返回局部变量的值十分危险
②一个函数如何返回多个返回值?
这里引出传入参数和传出参数的概念
传入参数:本来有值,传进函数里使用这个值
传出参数:本来没有值,从函数内部带出来的值
所以上面那个问题的答案就是使用传出参数就可以返回多个值
③return VS exit
return:表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定,例如return 0
exit( )函数的作用:结束整个程序,头文件为#include <stdio.h>,通常做异常处理使用
exit( )中间的变量是用来返回给用户的值,可以用echo(相当于printf) $? 来查看当前程序的返回值,最常用的是exit(1)
④return 0的作用
提高函数的执行效率,告诉main函数程序结束了
三、函数指针
函数指针是在传参的时候使用
1.定义
int (*p_func)(int,int) //定义一个指向两个形参为int型,返回值为int型的函数
2.初始化
①p_func = add //将函数的入口地址赋给p_func
②p_func = &add //将整个函数的地址赋给p_func
3.回调函数
回调函数是通过函数指针引出的一个概念,通过函数指针作为形参调用的函数称为回调函数。也就是说,如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。
回调函数体现了面向对象中多态的机制
下面通过一个例子来体会一下函数指针和回调函数
首先写了三个函数和一个调用函数指针的函数
其次在主函数中调用,并打印结果
打印结果如下:
四、函数指针数组
在这里我们同样用一个例子来理解
首先写好三个函数,分别具有两数相加,两数相减和两数相乘的功能
接着在主函数中定义函数指针数组,并将三个函数的入口地址以此赋给数组中的值
打印出的结果如下
五、编写函数时的编码规范
在函数编写中如何提高代码的复用性,扩展性,维护性
下面列出比较重要的几点:
1.对所调用函数的错误返回码要仔细、全面地处理
2.防止将函数的参数作为工作变量。这是因为将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
3.函数的规模尽量限制在200行以内。
4.一个函数仅完成一件功能。
5.为简单功能编写函数。虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。
6.不要设计多用途面面俱到的函数。
7.尽量不要编写依赖于其他函数内部实现的函数。例如在网上下载一个库,然后使用其中的函数,这样做的缺点是一旦代码出现了错误,就查不出来错误之处,因为你看不见源代码
8.避免设计多参数函数,不使用的参数从接口中去掉。
9.检查函数所有参数输入的有效性,即入口参数检查,例:
if(dest == NULL || src == NULL)
{
return NULL;
}