0
点赞
收藏
分享

微信扫一扫

结构体与共用体——共用体——C语言——day16

ZMXQQ233 2024-02-04 阅读 9

文章目录


前言

本文总结于此文章


一、函数递归

什么是递归

例如(史上最简单的递归):

#include<stdio.h>
int main()
{
	printf("Hello World\n");
	main();
}

先一直打印 Hallo World,最终程序挂掉

在这里插入图片描述

递归的两个重要条件

练习一

我们的第一想法就是:

	1234%10 = 4
	1234/10=123
	123%10=3
	123/10=12
	12%10=2
	12/10=1
	1%10=1
	1/10=0

这样我们能得到数字的每一位,然后我们把他们打印出来

#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
int main()
{
  int a ,n;
	printf("请输入一个无符号的整型:");
	scanf("%d", &a);
while(a>10)
  {
  if(a>10)
	{
  n = a % 10;
  printf("\n%d  ",n);
  a = a / 10;
  }
}
    printf("\n%d",a);
	return 0;
}

在这里插入图片描述

我们发现输出结果和题目中的不同,这个问题需要我们用递归来进行

因为递归的原理是先递推再回归,一层一层的传递下去

我们定一个print函数,它的功能是按照顺序打印num的每一位。

在写代码的过程中,我们只需要关注最后一层的递推和回归

在这里插入图片描述

我们的想法就是先把余的1打印出来,再把上一层余的2打出来,以此类推。

    printf("%d  ",n%10); 

因为这是我们上一层所调用的print函数,当这个函数执行完后,我们还要回到上一层,继续执行代码

    printf("%d  ",n%10); 

依次循环,这就是我们的递归

首先,我们先把递归函数写出来


  void print(int n)
  {
  
  if(n<10)
  {
    printf("%d  ",n);
  }
  else
  {
    print(n/10);
    printf("%d  ",n%10); 
  }
}

代码实现:

#include <stdio.h>
  void print(int n)
  {
  
  if(n<10)
  {
    printf("%d  ",n);
  }
  else
  {
     print(n/10);
    printf("%d  ",n%10); 
  }
}
  int main ()
  {  
  int a=0;
  printf("输入一个数字\n");
  scanf("%d",&a);
  print(a);
  return 0;
}

在这里插入图片描述

当然也可以更简便:

其更简便的最根本的原因是限制条件不同,使用n>9时,就不用使用else

#include<stdio.h>
void print(unsigned int n)
{
	if (n > 9)限制条件
	{
		print(n / 10);每次递归调用之后越来越接近这个限制条件
	}
	printf("%d ", n % 10);
}
int main()
{
	unsigned int num = 0;
	scanf("%u", &amp;num);
	print(num);
	return 0;
}

练习二

写一个可以求字符串长度的代码(老朋友了已经是)

我们有一个专门求字符串长度的库函数 strlen

长度等于开始到空字符之间的字符数(不包括空字符本身)\0

首先我们先创建一个字符数组

char arr[] = "abc";

再用strlen函数

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abc";
	strlen(arr);
	printf("%d", strlen(arr));
	return 0;
}

我们自己创建一个函数,模仿写一个strlen函数

这里先用非递归方式

#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
int my_strlen(char* str)
{
    int count = 0;
    while (*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}

int main(){
    char i[100];
    printf("请输入一个字符串: ");
    scanf("%s", i);
    my_strlen(i);
    printf(" %d", my_strlen(i));
    return 0;
}

count在这里只是起到一个计数器的作用

下来试一下递归

如果第一个字符不是\0,那说明字符串里至少有一个字符
这就是我们的思路

首先写递归函数:

int my_strlen(char* str)
{
    if(*str !='\0')
    {
        return 1 + my_strlen(str+1);
    }
    else
    {
        return 0;
    }
}

递归过程如下
在这里插入图片描述

代码如下

在这里插入图片描述

递归与迭代

练习三

先构思好递归(思路如下,是别的博主的图,博主文章在前言)

在这里插入图片描述

代码实现

#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
int my(int i)
{
    if(i<=1)
    {
        return 1;
    }
    else
    {
            return i *my(i -1);
    }
}

int main(){
    int i;
    printf("请输入一个数字: ");
    scanf("%d", &i);
    my(i);
    printf("%d", my(i));
    return 0;
}

在这里插入图片描述

递归函数也只是一种解决问题的技巧,它和其它技巧一样,也存在某些缺陷,具体来说就是:递归函数的时间开销和内存开销都非常大,极端情况下会导致程序崩溃。

所以这道题最好用非递归的方式来计算,比如迭代,循环是一种迭代

练习四

什么是斐波那契数列

在这里插入图片描述

流程如下:

在这里插入图片描述

写出代码:

#include<stdio.h>
#define  _CRT_SECURE_NO_WARNINGS
int Fib(int n)
{
	if(n<=2)
    {
        return 1;
    }
    else
    {
        return Fib(n-1)+Fib(n-2);
    }
}
int main()
{
	int n = 0;
	scanf("%d",&n);
	printf("%d",Fib(n));
	return 0;
}

在练习三、四中出现的问题

我们会出现这样的问题

原因是因
函数在调用过程中很多计算,其实一直在重复

在这里插入图片描述

系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出

如何解决这个问题

原文链接:https://blog.csdn.net/m0_68468727/article/details/126466506

#include<stdio.h>
int Fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;
 
	while (n>2)
	{
		c = a + b;
		a = b;
		b = c;//都向后传第一位
		n--;
	}
	return c;
}
 
int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d\n", Fib(n));
	return 0;
}

提示


如果您发现文章有错误请与我留言,感谢

举报

相关推荐

0 条评论