day13.2
谁能横刀立马,唯我飞牛大将军!
下面是day13所学的知识点:
函数递归
迭代
1.什么是递归
程序调用自身的编程技巧称为递归( recursion)。 递归做为一种算法在程序设计语言中广泛应用。
一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。 递归的主要思考方式在于:把大事化小
2.递归的两个必要条件
<1>存在限制条件,当满足这个限制条件的时候,递归便不再继续。
<2>每次递归调用之后,越来越接近这个限制条件
先来看一道例题:编写函数不允许创建临时变量,求字符串长度。
先用创建临时变量的方法:
//这里是test.h
//预处理符,防止头文件被重复包含
#ifndef _TEST_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
MyStrlen(const char*str);
#endif
//这里是test.c
#include "test.h"
MyStrlen(const char*str)
{
int i = 0;
while (str[i] != '\0')// *(str+i) 指针访问元素有两种方式,一种是解引用,一种就是这个
{
i++;
}
return i;
//while第二种写法
/*int count = 0;
while (*str != '0')
{
count++;
str++;
}*/
}
//这里是main.c
#include "test.h"
int main()
{
const char*str = "abcd1234";
printf("%d\n",MyStrlen(str));
system("pause");
return 0;
}
再使用递归的方法:
这里的test.h和main.c的代码与上面相同
//这里是test.c
#include "test.h"
MyStrlen(const char*str)
{
if (*str == '\0')
{
return 0;
}
return 1 + MyStrlen(str + 1);
}
过程图解:

再看一道例题:接受一个整型值(无符号),按照顺序打印它的每一位,例如,输入1234,打印出1 2 3 4
方法一:循环 数组
思路:x % 10可以计算出最后一位(1234中的4),再利用x/10取出123,再转回来求出3,依次循环。全部取出后利用数组储存起来,利用另一个循环将4 3 2 1倒叙输出。
//这里是test.h
#ifndef _TSET_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
void ShowInt();
#endif
//这里是test.c
void ShowInt(int x)
{
int arr[64] = { 0 };
int i = 0;
while (x > 0)
{
arr[i] = x % 10;
x = x / 10;
i++;
}
while (i > 0)
{
i--;
printf("%d ", arr[i]);
}
}
//这里是main.c
#include "test.h"
int main()
{
int a = 0;
printf("请输入数字:");
scanf("%d",&a);
ShowInt(a);
printf("\n");
system("pause");
return 0;
}
方法二:递归一
思路:先判断输入的值是否为 <10的数字,如果不是,进入x/10的递归,直到x<10,输出1,这时候递归函数的调用开始返回,利用x%10打印2 3 4
//这里是test.h
#ifndef _TSET_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
void ShowInt();
#endif
//这里是test.c
void ShowInt(int x)
{
if (x < 10)
{
printf("%d ",x);
return;
}
ShowInt(x / 10);
printf("%d ",x % 10);
}
//这里是main.c
#include "test.h"
int main()
{
int a = 0;
printf("请输入数字:");
scanf("%d",&a);
ShowInt(a);
printf("\n");
system("pause");
return 0;
}
方法三:递归二
思路:判断输入的数是否>9,如果是,直接进行递归,直到x<9,直接取余,这里因为1的取余还是1,所以1和后面12,123,1234,是一种类型的。
test.c中执行printf("%d ",x % 10);,有两种情况,一种是if条件不满足,另一种是if条件满足了,但是内部函数调用返回了。
//这里是test.h
#ifndef _TSET_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
void ShowInt();
#endif
//这里是test.c
void ShowInt(int x)
{
if (x > 9)
{
ShowInt(x / 10);
}
printf("%d ",x % 10);
}
//这里是main.c
#include "test.h"
int main()
{
int a = 0;
printf("请输入数字:");
scanf("%d",&a);
ShowInt(a);
printf("\n");
system("pause");
return 0;
}

再看一个例子:用递归求一个数的阶乘
//test.h
#ifndef _TSET_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
int ShowInt();
#endif
//test.c 第一种写法
int ShowInt(int x)
{
if (x > 1)
{
return x * ShowInt(x - 1);
}
return 1;
}
//test.c第二种写法
int ShowInt(int x)
{
if (1 == x)
{
return 1;
}
return x*ShowInt(x - 1);
//main.c
#include "test.h"
int main()
{
int a = 0;
printf("请输入数字:");
scanf("%d",&a);
printf("%d ", ShowInt(a));
printf("\n");
system("pause");
return 0;
}
再看一个例子:用递归求斐波那契数
//test.h
#ifndef _TSET_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#pragma warning (disable:4996)
int ShowInt();
#endif
//test.c
int ShowInt(int x)
{
if (1 == x||2 == x)
{
return 1;
}
return ShowInt(x-1)+ShowInt(x-2);
}
//main.c
#include "test.h"
int main()
{
int a = 0;
printf("请输入数字:");
scanf("%d",&a);
printf("%d ", ShowInt(a));
printf("\n");
system("pause");
return 0;
}
由此看出,递归效率低,因为多次计算,多次开辟栈帧,耗时耗内存,如果次数过多,程序会崩,也就是栈溢出问题。
此时用迭代,效率更高:
int first = 1;
int second = 1;
int third = 1;
while(n > 2)
{
third = first + second;
first = second;
second = third;
n--;
}
return third;
本文深入探讨了递归与迭代两种编程技巧,通过具体实例解释了递归的基本概念、必要条件及其应用,如求字符串长度、打印整数位数、计算阶乘及斐波那契数列,并对比了递归与迭代的效率。

被折叠的 条评论
为什么被折叠?



