C语言知识点:函数,递归和迭代

本文介绍了C语言中的函数概念,区分了库函数和自定义函数,并详细阐述了递归的原理、限制条件以及迭代作为解决递归问题的方法。通过实例演示了如何通过递归和迭代求解阶乘,强调了递归可能带来的栈溢出问题及迭代的替代作用。
摘要由CSDN通过智能技术生成

1. 函数

最早我们在数学中接触到函数,比如一次函数,一元二次函数等等。C语言中以及其他语言,比如python中也有函数的概念(Function),可以翻译为:子程序。

一个大的计算任务可以分解成若干个较C语言的程序其实是由无数个小的函数组合而成的,也可以说:小的函数(对应较小的任务)完成。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复用的,提升了开发软件的效率。

在C语言中一般有两种函数:库函数 和 自定义函数。


1.1 库函数

库函数通常来讲就是语言中自带的一些函数,比如我们经常使用的 printf(), scanf() 等。每个语言也都有自己对应的库函数。

一些库函数也要引用对应的头文件 (.h)

举一个例子:我们求 2 的 3 次方,就要用到 pow() 函数,要想使用这个函数,我们必须引入头文件 <math.h> 。如下图:

因为 pow() 函数中必须是 double 类型,所以我们也要定义 a, b 为 double 类型。但我们输出的时候不想有小数怎么办,在 % 后加一个 . 就可以了,如果想要两位小数就加 .2 

以上就是关于库函数的简单解释。

1.2 自定义函数

自定义函数,顾名思义就是我们自己定义的函数,函数的功能也是自己定义的。

自定义函数是有一定的语法形式的:

一个自定义函数需要有:

type (函数类型) : int 有返回值;void 无返回值

function_name (函数的名字,一般是纯英文加下划线)

形式参数 (和主函数(main)需要传入的参数建立联系,用完即销毁)

{ } 花括号内的就是函数的内容。

举例:写一个相加的函数 Add() ,计算两个数的和

如图所示,我定义了一个 int 类型的函数,函数名是 Add ,从主函数传入了两个值 x,y(形式参数)(可以和主函数名字相同),然后返回 x+y 的值。所以,当我运行后,主函数中需要输入 a,b(实际参数)两个值,我输入完这两个值就传入 Add 函数中,然后直接返回两数的和。

一个简单的相加函数就完成了。

另外,形式参数相当于实际参数的一份临时拷贝,用完即弃。

2. 函数的递归

前面讲了函数的基本内容,现在终于到了本章的重头戏,函数的递归。

那么函数的递归究竟是什么呢,有一个比较形象的描述,就是函数自己调用自己。

2.1 递归的思想

递归其实就是大事化小,小事化了,把一个很大的问题,慢慢细分,最后分到不能再分就结束了。

我们来写一个最简单的递归代码

在这个代码中,我们在 main() 函数中再次调用了 main() 函数,那么结果会是什么呢?

结果就是不断的调用自己,就像套娃一样,没有尽头的套圈。所以,递归是要有限制条件的。

2.2 递归的限制条件

递归必须有限制条件,否则就会像上面一样,无限递归,导致栈溢出。

1. 递归必须有结束条件。

2. 每次递归都要更接近这个条件。

2.3 例子

一个简单的例子来解释递归的这两个条件,那就是求 n 的阶乘(n!)

我们都知道,n! = n*(n-1)*(n-1)*...*1;比如5的阶乘就是,5*4*3*2*1 = 120

那么,我们怎么写一个函数,具有实现递归来求 n 的阶乘呢?

数学中规定 0的阶乘等于1,0! = 1。那么 1 的阶乘也等于 1,1! = 1。

所以,我们可以分类,将 n <= 1的情况归为一类,n > 1的情况分为一类。当 n <= 1时,返回1;当n > 1 时,返回 n * fun(n-1) 。我们先来看代码,可能会有人疑惑,为什么当n > 1 时,返回      n * fun(n-1) 呢。

当我们输入 n = 5,传入函数中,进入判断,n = 5 不满足 n<=1,所以进入 else , 然后返回 5*fun(5-1),因为调用了自己,所以进入 fun(5-1);在 fun(4) 中,进入判断,然后进入 else,返回 4*fun(4-1);在fun(3) 中,进入判断,然后 else,返回 3*fun(2);

直到 n = 1,fun(1) 进入判断,满足 n <= 1,返回 1。然后回到 fun(2),2*1 = 2;再回到 fun(3),3*2 = 6;再回到 fun(4),4*6 = 24;再回到 fun(5),5*24 = 120.

 

所以,递归的本质,就是先递,再归。

我们可以用一张图来表示:

总结来说,递归可以将一个大的问题,逐渐分成小问题,然后再总结到一起。

3. 函数的迭代

看完了函数的递归,大家可能会感觉非常好用,今后的每一个函数都想用递归试试,但是,递归虽然结构简单,也有着比较致命的缺点,那就是递归次数比较多的时候,容易造成,栈溢出。

比如:当我输入 40 的时候,由于递归的数量和计算量太大,直接就不计算了。

用什么方法能避免这种问题呢,当我们需要计算量大的时候,迭代可以弥补递归容易导致栈溢出的问题。那么迭代又是什么呢?

通俗来讲,迭代就是循环,之前讲过。

我们来写一个求 n 的阶乘的迭代

用我们比较熟知的 for 循环来求 n 的阶乘,这样就不会因为重复计算而导致栈溢出的情况。

4. 小结:

这一章,我们讲了函数,函数的递归和迭代。内容不多,挑了一些简单易懂的例子来说明递归的思想,下一章就递归问题再分析几个例子,顺序打印一个数的每一位,斐波那契数列(青蛙跳台阶)和 汉诺塔问题。

本人小白一个,如有错误请指出,也欢迎讨论。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值