函数递归 声明及定义!

关于假期的第一个小结:生活很难,代码也很难,但是要坚持下去呀,别沮丧!冲冲冲!
for me & for you all


前言

耐着性子,开始专注做一件事的样子还不错吧。
递归函数及函数的声明和定义(头文件)!
关于递归 函数声明和定义 以及头文件的运用,可以达成多人协作及出售。
以下是个人的一些小结:


一、函数声明及定义

1.函数声明

先声明后使用!!!故:若放在同一个文件中 则放在主函数之前
自己写出一个新的函数,在库函数中不存在
函数声明一般放在
头文件
中!!
声明

2.函数定义

即:函数声明的函数体
定义

3.实例及注意点

1)创建外部声明函数时:同名的头文件(放声明)和源文件(放定义)
add
2)实现的代码
最终的主函数最终
头文件(声明:含有分号!!)
头
同名源文件(定义)
源文件

4.头文件中避免重复调用

1) and 2) 等价

1)#pragma once
1
2)#ifndef Add_H
#define Add_H(根据头文件名称进行改变)
函数声明; (分号!)
#endif Add_H
2

5.头文件的纠正

可加extern!!!
补充

6.好处

1)分块写:便于多人协作
2)封装和隐藏
3)例如:计算器的实现
计算

7.若要实现隐藏&售出

将头文件和同名源文件封装为一个静态库.lib :有功能但是看不到代码,可售出

隐藏
封装静态库.lib的方法:
给别人的只有头文件和静态库
新建一个项目eg.add-将自己原本写好即将出售的头文件.h和源文件.c拷贝,放到自己新建的项目内eg.add-然后在新建的项目的源文件中打开现有项-将头文件拉到头文件处-点击最上方的项目-右击鼠标-属性-配置属性-常规-配置类型-下拉应用程序的倒三角-静态库.lib-编译-Debug文件夹下有.lib文件

8.编译与链接

编译

二、什么是递归?

以我而言:简而言之的递归便是—— 函数调用自身的一种方法,主要用于实现多次重复计算。

递归

三、递归的两个必要条件及实例

1.递归的两个必要条件

1)存在限制条件,当满足此限制条件时,递归不再进行。
2)每次递归调用后越来越接近这个限制条件。

2.实例

1)接受一个整型值(无符号),按照顺序打印它的每一位。 例如: 输入:1234,输出 1 2 3 4。

注:一定要注意限制条件,可画图整理思路!
思路:
思路

代码:
按顺序打印
执行顺序:(遇到最终停止时的return便开始逆序return)
顺序1
顺序2
小结1:从最终return或printf开始返回,然后找到上一级的递归再返回,直到最开始。


2)编写函数不允许创建临时变量,求字符串的长度。

1.含有count的临时变量(不符合题目意思)
代码:
含临时变量
2.利用递归解决:
思路:
想法

代码:
递归
执行步骤:
1
2
3

3)其实可以直接调用<string.h>中的strlen()函数求字符串长度
实例


四、递归与迭代(实例)

1.求n的阶乘。(不考虑溢出)

1)非递归形式
非递归
2)递归
思路:
思路

代码:
代码
执行步骤:
步骤

2.求第n个斐波那契数。(不考虑溢出)

1)何为斐波那契数列:
第一二个数均为1,从第三个数开始的数均为前两个数之和

2)非递归
非1
循环处可进行优化:
优化
注:一定要存在可跳出循环的限制条件

3)递归
思路:
思路

代码:
递归

4)经比较,易发现:
若计算的n比较小时看不出来两者的优劣性,若计算较大的n,如50,迭代可较快完成,只涉及加法运算,但是递归将会被分成无数次递归,需要耗时较长(不考虑结果正确性),如图:
故:此时相较而言,迭代可能较好
如
小结:递归并不总是好的,要看条件选择。

3.什么时候使用递归?

递归

五、思考拓展(递归典例)

1.汉诺塔问题

1)何为汉诺塔问题:
汉诺塔
2)解决思路
思路
3)代码
有待-

2.青蛙跳台阶问题

(可以抽象为斐波那契数列问题)

1)何为青蛙跳台阶问题:
青蛙
2)解题思路
图

思路
3)代码:
代码

六、补充

1.递归会存在溢出情况

递归会因为占据空间太大出现栈溢出情况,故要根据情况选择递归或者迭代。
栈溢出
以此为例:栈帧可创建和销毁!
每一次函数的调用都要重新开辟空间,故容易造成栈溢出。
空间分为三个区(从上到下):栈区(局部变量、形参) 堆区(动态内存分布 eg.malloc calloc realloc free等) 静态区(全局变量、静态变量)
函数栈帧=运行时堆栈
栈帧的创建和销毁

2.数组定义的区别及关于’\0’

char arr[10]=“abcdef” 表示:abcdef\0 (含有\0)
char arr[]={‘a’,‘b’,‘c’,‘d’} 表示:a b c d (不含\0)
注:\0占空间 但是不算字符长度!!!

3.关于函数声明及主函数的对应写法

1)在定义的函数名前面加上最终返回类型,()内的类型对应于主函数的函数类型

2)如:声明的函数:int my_strlen(char* str){则对应于return} main()函数中int len=my_strlen(arr)用于接收,要printf() return 0;
如:声明的函数:void my_strlen(char* str){则对应于printf()} main()函数中return my_strlen(arr0即可。

4.关于指针+1

指针+1

5.递归溢出及解决方案

溢出

今天的分享到此结束,又是充实的一个早上!期待之后对其他问题的解答!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

'Dream是普通小孩耶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值