函数分类分为库函数和自定义函数。
一. 库函数
库函数分类:
- IO函数(scanf,printf... ...)
- 字符串操作函数(strlen...)
- 字符操作函数(islower... ...)
- 内存操作函数
- 时间/日期函数(time...)
- 数学函数(sqrt...pow...)
- 其他库函数
库函数查询工具:
二. 自定义函数
定义
由三部分组成(函数名,返回值类型,函数参数)
参数
函数的参数分为形参和实参。
实参:函数调用时传入的参数(常量,变量,表达式,函数......必须要有确定的值)
形参:函数名括号内的变量
- 形式参数只有在函数被调用的过程中才能实例化(分配内存单元)
- 形式参数当函数调用完就自动销毁了,因此形参只在函数中有效
- 形参实例化之后相当于对实参的临时拷贝
调用
传值调用:修改形参不影响实参
传址调用:通过形参的指针访问函数外部变量并进行操作
传值调用的例子:
//交换两个数 //定义一个函数,进行两个数的调换 void Swap(int x, int y) { int tmp = x; x = y; y = tmp; } //编写代码,调用函数 int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:%d %d\n", a, b); //调用函数 Swap(a, b); printf("交换后:%d %d\n", a, b); return 0; }
传址调用的例子:
//交换两个数 //定义一个函数,进行两个数的调换 //*pa就是a //*pb就是b void Swap(int *pa, int *pb) { int tmp = *pa; *pa = *pb; //a = b *pb = tmp;//b =tmp } //编写代码,调用函数 int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:%d %d\n", a, b); //调用函数,采用指针,取地址进行交换 Swap(&a, &b); printf("交换后:%d %d\n", a, b); return 0; }
观察上述两段代码,我们可以发现,在函数定义时,传值是void Swap(int x, int y),传址是void Swap(int *pa, int *pb)。调用函数时,传值是Swap(a, b);传址是Swap(&a, &b)。
二者的运行结果也不同。
传值操作:
传址操作:
嵌套调用和链式访问
嵌套调用:(可以嵌套调用,不能嵌套定义)
//函数的嵌套 void line1() { printf("hehe\n"); } void line2() { line1(); printf("hehe\n"); } int main() { line2(); return 0; }
上面是一个嵌套调用的例子,我们可以看到,在line2()的自定义函数中,嵌套了line1(),在main函数里面,嵌套了line2。
最终的运行结果如下:
我们可以看到,结果中打印了两个hehe,这是由于line2()函数打印了一次,line1()函数也打印了一次。
链式访问:把一个函数的返回值作为另一个函数的参数
//函数的链式访问 int main() { printf("%d", printf("%d", printf("%d", 43))); return 0; }
在这段代码中,我们把printf()函数的返回值当作了printf()函数的参数。
运行结果如下:
在这段代码中,最内层的printf("%d", 43)的返回值是43,然后printf("%d", printf("%d", 43))的返回值是2(因为有2个字符),最后printf("%d", printf("%d", printf("%d", 43)));的返回值是1,他只有2这一个字符。
函数的声明与定义
声明:
- 告诉编译器存在一个函数,叫什么名字,有什么参数,返回类型是什么
- 具体是否存在无法确定,只是告诉编译器存在
- 先声明后使用
- 声明一般放在头文件中
定义:交代函数具体功能,具体如何实现
定义是一种特殊的声明。
以下为具体举例:
//函数声明 int Add(int x, int y); int main() { int a = 0; int b = 0; //输入 scanf("%d %d", &a, &b); //调用函数 //进行加法计算 int c = Add(a, b); //打印结果 printf("%d\n", c); return 0; } //函数定义 int Add(int x, int y) { return x + y; }
函数递归
递--递推
归--回归
简单来讲,就是函数自己调用了自己
两个必要条件:
- 存在限制条件。满足限制条件,递归便不再继续
- 每次调用递归后,越来越靠近限制条件
举例:依次打印输入数字的千十百(1234的结果为1 2 3 4)
#include <stdio.h> void print(int n) { if(n>9) { print(n/10); } printf("%d ", n%10); } int main() { int num = 1234; print(num); return 0; }