本节将带领各位深入了解函数方面的知识点,其中包括函数的定义、嵌套、使用、、、、、、在函数讲解中力争让各位可以在函数方面做到基本掌握,同时我们对金典方法递归进行讲解
目录
1、函数的背景
2、函数的分类
3、函数的参数
4、函数的调用
5、函数的嵌套
6、链式访问
7、递归(含两个经典算法)
1、函数的背景
函数是为了完成某一个任务所写的部分代码——这就是函数。函数的编写尽量独立性越高越好,这样在使用者调用该函数时有更多的使用范围,而不是因为函数内容过于复杂多了许多无用的内容而大大减少了使用范围。
2、函数的分类
在C语言中函数主要分为两个部分,1、库函数 2、自定义函数。
1、库函数
是我们在编程过程中程序自带的函数,主要对象是完成一些较为基本的内容例如输入、打印、、、、这些基础功能由系统自带的函数完成,使用时引用头文件直接调用即可,方便程序员进行软件开发
2、自定义函数
自定义函数是程序员在进行软件开发时,为了实现项目中的某种特殊要求,进行编写的函数,在使用的使用的时候引用相应头文件即可
自定义函数和库文件一样,要有函数名,返回值类型和函数参数。不一样的是库函数是系统提供的不够灵活,而自定义函数是由程序员自己开发,对于程序员有很大的发挥空间,灵活性也相对的十分的好
3、函数的参数
函数的参数分为实际参数和形式参数
1、实际参数
实参故名思意就是真实传给函数的参数,实参包括常量、变量、函数、表达式等等,在进行函数调用的时候它们都有准确的值,然后将这些值传送到函数中的形参中去
2、形式参数
形式参数呢是对那些函数名后面括号中的变量的称呼,这些变量只有在函数的调用过程中才能够分配内存单元即进行实例化,当函数调用完成之后形式参数则进行自动销毁,因此形式参数只有在函数中才有用
#include <stdio.h>
int get_max(int x, int y)
{
return (x>y)?(x):(y);
}
int main()
{
int num1 = 10;
int num2 = 20;
int max = get_max(num1, num2);
printf("max = %d\n", max);
return 0;
}
例如在这个函数中,num1、num2则是传过去的变量即实际参数,而x,y是在函数括号里面的变量即是形式参数
4、函数的调用
1、传值调用
传值调用即是在调用时候,实参和形参在电脑内存中分别占有内存块,在对形参的改变过程中不会对实参产生改变
2、传址调用
传址是在调用过程中,将实参的地址传送过去,换句话说在函数中改变形式参数的过程中直接对实际参数进行了改变
5、函数的嵌套调用
函数的嵌套则是像小环和大环一样,小环就是大环的一部分,即是在函数调用过程中调用另一个函数
例如:
#include <stdio.h>
void new_line()
{
printf("hehe\n");
}
void three_line()
{
int i = 0;
for(i=0; i<3; i++)
{
new_line();
}
}
int main()
{
three_line();
return 0;
}
6、链式访问
链式访问则是把各个函数像在一条链子上一样,即一个函数的返回值则是另一个函数的参数进行,各个函数像连接在一起一样
例如:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = "hello";
int ret = strlen(strcat(arr,"bit"));
printf("%d\n", ret);
return 0;
}
7、函数经典算法介绍——递归
递归是一种在程序设计语言中广泛应用的一种算法
简单来说就是在函数在使用过程中直接或者间接的调用自身函数的一种算法
它在思考过程中即是将一个复杂的大问题可以通过类似的算法逐步将问题拆解成一个个类似的小问题,从而在解决过程中不断的调用相同的算法重复计算进而解决复杂的大问题,大大的减少了程序的代码量
在使用过程中两个必要条件
1、一定要存在限制条件,当满足这个限制条件时候,递归过程将不再继续进行下去
2、递归每次进行一层的话将越来越接近这个限制条件才可以
下面几个递归供参考
比如下面这个代码打印98765这个数字
#include <stdio.h>
void print(int n)
{
if(n>9)
{
print(n/10);
}
printf("%d ", n%10);
}
int main()
{
int num = 98765;
print(num);
return 0;
}
2、递归方法实现n的阶乘
int recursion(unsigned int m)
{
int ret = 1;
if (m > 1)
{
ret = m * recursion(m - 1);
}
else
ret = 1;
return ret;
}
int main()
{
int i = 0;
scanf("%d", &i);
int ret=recursion(i);
printf("%d", ret);
return 0;
}
下面呢则是两个递归的经典题目
1、汉诺塔问题
void move(char from , char to)
{
printf("将%c柱子最上面的圆盘->放到%c柱子上面\n", from, to);
}
void hanoi(char A,char B,char C,int n) //函数目的将n个圆盘按照汉诺塔规则从A柱子移动到C柱子上面(函数默认最开始都在A上最后移动到B上面)
{
if (n == 1)
{
move(A, C);
}
else
{
hanoi(A,C,B,n - 1);
move(A, C);
hanoi(B, A, C, n - 1);
}
}
int main()
{
char A = 'A';
char B = 'B';
char C = 'C'; //ABC分别表示三个柱子
int n = 0;
printf("请输入汉诺塔的圆盘个数:\n");
scanf("%d", &n); //n为有几个圆盘
hanoi(A,B,C,n); //调用汉诺塔函数函数给出步骤
}
2、青蛙跳台阶问题
1、递归的方法求斐波那契数列
int fib(m)
{
int a = 1;
int b = 1;
if (m > 2)
return fib(m - 1) + fib(m - 2);
else
return 1;
}
int main()
{
int m = 0;
scanf("%d", &m);
int ret=fib(m);
printf("%d", ret);
return 0;
}
具体分析在我的另一篇博客中有,有兴趣的可以去学习了解一下
https://blog.csdn.net/watermelonw/article/details/119718323?spm=1001.2014.3001.5501