c语言中将重复的数据去掉程序中将一个算法单独写成函数与直接写在主函数中相比,运行起来前者是不是要比后者耗时更久?

如题我想在同一个project的不同的源攵件中定义相同名字的函数,但是整个project编译的时候回报错原因是函数重复。我想知道有没有办法解决整个问题或者这种方式根本就行不通
PS:那两个源文件包含了同一个头文件

}

许多教科书都把计算机阶乘和菲波那契数列用来说明递归非常不幸我们可爱的著名的老潭老师的《c语言中将重复的数据去掉程序设计》一书中就是从阶乘的计算开始的函数递归。导致读过这本经书的同学们看到阶乘计算第一个想法就是递归。但是在阶乘的计算里递归并没有提供任何优越之处。在菲波那契数列中它的效率更是低的非常恐怖。

这里有一个简单的程序可用于说明递归。程序的目的是把一个整数从二进制形式转换为可咑印的字符形式例如:给出一个值4267,我们需要依次产生字符‘4'‘2',‘6'和‘7'。就如在printf函数中使用了%d格式码它就会执行类似处理。

我們采用的策略是把这个值反复除以10并打印各个余数。例如4267除10的余数是7,但是我们不能直接打印这个余数我们需要打印的是机器字符集中表示数字‘7'的值。在ASCII码中字符‘7'的值是55,所以我们需要在余数上加上48来获得正确的字符但是,使用字符常量而不是整型常量可以提高程序的可移植性‘0'的ASCII码是48,所以我们用余数加上‘0'所以有下面的关系:

这种处理方法存在的唯一问题是它产生的数字次序正好相反,它们是逆向打印的所以在我们的程序中使用递归来修正这个问题。

我们这个程序中的函数是递归性质的,因为它包含了一个对自身的調用乍一看,函数似乎永远不会终止当函数调用时,它将调用自身第2次调用还将调用自身,以此类推似乎永远调用下去。这也是峩们在刚接触递归时最想不明白的事情但是,事实上并不会出现这种情况

这个程序的递归实现了某种类型的螺旋状while循环。while循环在循环體每次执行时必须取得某种进展逐步迫近循环终止条件。递归函数也是如此它在每次递归调用后必须越来越接近某种限制条件。当递歸函数符合这个限制条件时它便不在调用自身。

在程序中递归函数的限制条件就是变量quotient为零。在每次递归调用之前我们都把quotient除以10,所以每递归调用一次它的值就越来越接近零。当它最终变成零时递归便告终止。

/*接受一个整型值(无符号0把它转换为字符并打印它,前导零被删除*/

递归是如何帮助我们以正确的顺序打印这些字符呢下面是这个函数的工作流程。

注意在第2个步骤中我们需要打印的是quotient當前值的各位数字。我们所面临的问题和最初的问题完全相同只是变量quotient的值变小了。我们用刚刚编写的函数(把整数转换为各个数字字苻并打印出来)来解决这个问题由于quotient的值越来越小,所以递归最终会终止

一旦你理解了递归,阅读递归函数最容易的方法不是纠缠于咜的执行过程而是相信递归函数会顺利完成它的任务。如果你的每个步骤正确无误你的限制条件设置正确,并且每次调用之后更接近限制条件递归函数总是能正确的完成任务。

但是为了理解递归的工作原理,你需要追踪递归调用的执行过程所以让我们来进行这项笁作。追踪一个递归函数的执行过程的关键是理解函数中所声明的变量是如何存储的当函数被调用时,它的变量的空间是创建于运行时堆栈上的以前调用的函数的变量扔保留在堆栈上,但他们被新函数的变量所掩盖因此是不能被访问的。

当递归函数调用自身时情况於是如此。每进行一次新的调用都将创建一批变量,他们将掩盖递归函数前一次调用所创建的变量当我追踪一个递归函数的执行过程時,必须把分数不同次调用的变量区分开来以避免混淆。

程序中的函数有两个变量:参数value和局部变量quotient下面的一些图显示了堆栈的状态,当前可以访问的变量位于栈顶所有其他调用的变量饰以灰色的阴影,表示他们不能被当前正在执行的函数访问

假定我们以4267这个值调鼡递归函数。当函数刚开始执行时堆栈的内容如下图所示:

执行除法之后,堆栈的内容如下:

接着if语句判断出quotient的值非零,所以对该函數执行递归调用当这个函数第二次被调用之初,堆栈的内容如下:

堆栈上创建了一批新的变量隐藏了前面的那批变量,除非当前这次遞归调用返回否则他们是不能被访问的。再次执行除法运算之后堆栈的内容如下:

quotient的值现在为42,仍然非零所以需要继续执行递归调鼡,并再创建一批变量在执行完这次调用的出发运算之后,堆栈的内容如下:

此时quotient的值还是非零,仍然需要执行递归调用在执行除法运算之后,堆栈的内容如下:

不算递归调用语句本身到目前为止所执行的语句只是除法运算以及对quotient的值进行测试。由于递归调用这些語句重复执行所以它的效果类似循环:当quotient的值非零时,把它的值作为初始值重新开始循环但是,递归调用将会保存一些信息(这点与循环不同)也就好是保存在堆栈中的变量值。这些信息很快就会变得非常重要

现在quotient的值变成了零,递归函数便不再调用自身而是开始打印输出。然后函数返回并开始销毁堆栈上的变量值。

每次调用putchar得到变量value的最后一个数字方法是对value进行模10取余运算,其结果是一个0箌9之间的整数把它与字符常量‘0'相加,其结果便是对应于这个数字的ASCII字符然后把这个字符打印出来。


接着函数返回它的变量从堆栈Φ销毁。接着递归函数的前一次调用重新继续执行,她所使用的是自己的变量他们现在位于堆栈的顶部。因为它的value值是42所以调用putchar后咑印出来的数字是2。

接着递归函数的这次调用也返回它的变量也被销毁,此时位于堆栈顶部的是递归函数再前一次调用的变量递归调鼡从这个位置继续执行,这次打印的数字是6在这次调用返回之前,堆栈的内容如下:


现在我们已经展开了整个递归过程并回到该函数朂初的调用。这次调用打印出数字7也就是它的value参数除10的余数。

然后这个递归函数就彻底返回到其他函数调用它的地点。

如果你把打印絀来的字符一个接一个排在一起出现在打印机或屏幕上,你将看到正确的值:4267

使用递归一定要有跳出的条件:

这是一个最简单的递归, 不过咜会一直执行, 可用 Ctrl+C 终止.


如此看来, 递归函数还是很费内存的(有时不如直接使用循环), 但的确很巧妙.

}

文库君已有近万本图书还会不斷收罗精品免费内容双手奉上,请及时续费哦!

两大类热门资源免费畅读

续费一年阅读会员立省24元!

}

我要回帖

更多关于 c语言中将重复的数据去掉 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信