引言
之前的博客中有讲述printf(),scanf()函数,还有常见的数学库函数,这些都是C语言内置的函数,很难满足我们日常的开发需求,我们需要有自己的自定义函数,在这些函数内,我们可以更好地去自定义我们想完成的功能,同时也减轻了main()函数内大量代码的出现。
函数的定义
指的是函数的具体实现,交代函数的功能实现。
C语言也规定,每个函数必须单独定义,不允许嵌套定义,但可以嵌套调用。
自定义函数我们平时分为有参函数和无参函数,其定义形式如下:
返回类型 函数名(函数参数)
{
函数体;
}
返回类型可以是:int,float,char;也可以没有返回类型,写成void。
函数参数我们分为形参和实参,没有参数时我们可以不写或者写成void。
参数可以是:常量,变量,表达式,函数等,要有确定的值
形参
函数名后括号中的变量,当函数调用完成后就自动销毁了,所以只在函数中有效。
实参
真实传递给函数的参数。
形参实例化之后其实相当于实参的一份临时拷贝。
这样说的话会有些笼统,我们在main()函数外定义了自定义函数,在main()函数内我们调用函数时,我们需要传递参数让自定义函数实现它本身的功能,如果我们需要改变传递的参数本身的数值,我们就传递实参,不需要改变,就传递形参。
实参通常采用取地址符号“&”,另外自定义函数接收时用指针的形式接收,之后会系统讲解指针的知识。
形参的传递就不需要用&符号了。
函数的声明和调用
函数如果放在main()函数后定义,则需要在main()函数前声明,在main()函数中调用。
因为程序是从上往下跑,碰到main()函数直接进入,在main()函数中碰到了这个函数,但是程序又没见过,就会报错。
举例:
#include<stdio.h>
void max();
int main()
{
max();
return 0;
}
void max()
{
}
如果写在main()函数之前则不需要声明。
#include<stdio.h>
void max()
{
}
int main()
{
max();
return 0;
}
函数的调用
传值调用:函数的形参和实参分别占用不同内存块,对形参的修改不会影响实参。
传址调用:让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外边的变量。
使用场景:比较大小不改变数值用传值即可。
函数的递归
递归就是一个函数自己调用自己。
一般内存划分为几个区域:栈区,堆区,静态区。
栈区包含:局部变量,函数形参。
堆区包含:动态内存开辟(malloc,calloc)。
静态区包含:全局变量,static修饰的变量。
递归常见的错误:栈溢出(即函数打印一直向栈区申请空间)
举例:
#include<stdio.h>
int main()
{
printf("hehe");
main();
return 0;
}