*c语言学习笔记(十二)*
一、递归的含义
程序调用自身的编程技巧称为递归;递归作为一种算法在程序设计语言中广泛应用。递归的主要思考方式为:把大事化小;
先说一下函数调用问题,创建一个自定义函数可以比较两个数大小并且输出较大值;在源文件主函数中调用,创建一个自定义头文件包含自定义函数;首先创建头文件
鼠标右键点击,然后选择.h文件类型,在空白模板中输入:
#ifndef __COMP_H__
#define __COMP_H__
int comp(int x, int y);
#endif
这里就是创建了自己的一个头文件,头文件中包含了comp函数,之后新建一个comp.c文件,在这个文件中输入comp这个函数体,因为仅仅要求输出较大值,故暂时不考虑相等以及其他情况;
int comp(int x, int y)
{
if (x > y)
return x;
else
return y;
}
此时自定义函数,自定义头文件就创建成功了;在源文件main函数中进行函数调用,首先添加头文件
#include"comp.h"
注:头文件名称是自己命名的,所以用" ",系统头文件用< >来完成;
之后调用函数:
int z = comp(5, 6);
printf("%d", z);
输出结果如图,以上一系列步骤即完成了自定义函数,自定义头文件创建过程;
对于头文件中的语句
#ifndef __COMP_H__
#define __COMP_H__
int comp(int x, int y);
#endif
这样写的目的是为了避免重复定义,是标准代码方式;
#ifndef的意思为如果没有定义,则执行下面的定义。
二、递归的用法
首先给出最简单的递归代码:
printf("正在递归\n");
main();
在main函数内部调用main函数本身,程序执行结果是死循环,建议大家看看就行。后面程序会在死循环中自动终止,原因是栈溢出。
编译器给出的警告:
warning C4717: “main”: 如递归所有控件路径,
函数将导致运行时堆栈溢出
对于堆栈的问题,后面再学习中将会再详细介绍。
递归的两个必要条件:
1、存在限制条件,当条件满足时,递归便不再进行;
2、每次递归调用之后越来越接近限制条件;
三、练习:运用递归方法,接受一个整型数(无符号),按顺序打印他的每一位
代码如下:主函数内容:
unsigned int num = 0;
scanf("%d", &num);
print(num);
自定义函数内容:
void print(int n)
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n % 10);
}
最后输出结果:
关于递归的思想,此次练习确实比之前难度上升,关键的问题是要弄清楚函函数执行的顺序,每一步代码是怎样执行的;
这里简单描述一下函数执行过程:
当输入1234时,程序进入print函数,判断语句成立,由于if里面的语句为print();
故此时进行第一次递归,诸如此类往返,直至判断语句不成立,执行打印printf;
注:
1、关于递归的具体执行过程,可以从n值的变化中看出来n=1234(大于9成立)–除十–123–成立–除十–12–成立—除十----1,运行至此,程序判断语句不成立了,执行打印程序,第一个1就被打印出来了;
2.函数返回问题:当第一个1被打印出来之后,函数继续执行就要返回,这里就是第二个关键,函数返回时返回上一个执行函数的函数入口,由于是递归函数,故在这里返回,n的值再次发生变换:1–12–123–1234,由于if语句已经执行过了,所以每次执行,都只是执行了下面的打印语句:
printf("%d ", n % 10);
这里1234就被一层一层分别打印了出来;
这里可能我解释的不够透彻或者对理解有错误,希望有同学看见能指点一下更清晰的思路,谢谢!