浅谈尾递归和goto循环

本文探讨了尾递归的概念,强调其在节省栈空间方面的优势,但指出Python、Java和C++不支持尾递归优化。虽然可以借助异常处理模拟优化,但这并非理想解决方案。同时,文章提及了goto语句,一种高级但潜在危险的控制流工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习python递归的时候接触到尾递归,尾递归的要求是,函数的最后一个运算是递归调用,而不是其他的运算。

举阶乘为例子

// tail_recursion.cpp
int fact(int num ){
	if(num <= 0 )
		return 0 ;
	else if(num == 1 )
		return 1 ;
	else if (num > 1 )
	{
		return num * fact(num - 1 ) ;
	}
}

int fact_tail(int num , int ans){
	if(num == 1 ){
		return ans ;
	}
	else if(num <= 0 ){
		return 0 ;
	}
	else if(num > 1 ){
		return fact_tail(num - 1 , ans * num ) ;
	}
}

第一个函数是我们熟知的递归函数,它的优点是简介易懂。缺点也十分经典,就是大量耗费栈空间,每次调用递归时都要把上一次的数据压栈。第二个函数是我们的尾递归函数。比较两个函数,在递归调用部分,递归函数的最后一个运算是乘法,而尾递归函数里的递归调用是最后一个运算。当最后一个运算是乘法这一类的运算时,我们的就一定要压栈保留原来的数据,用于后来的运算。但是尾递归就不用了,对于尾递归来说,上一次函数的任务已经完成了。它的数据已经通过参数传递了,是完全没有保留意义的,我们是完全可以不用压栈的。

由此,其实在部分语言中,会有我们所称的尾递归优化。编译器会为尾递归提供编译级别的优化,比如至始至终递归函数都只是用一个栈,不会出现栈溢出的情况。但是,可惜的是,我们的python、java还有c++其实是没有尾递归优化的。当然,如果真的在这些语言中需要尾递归优化,其实是可以通过异常处理的修改来实现的。这里提供一个网址:http://www.cnblogs.com/Alexander-Lee/archive/2010/09/16/1827587.html

当然,上述的方法其实是牵强而为之。


今天还了解到一个叫goto 的语句,十分高级,但是也十分危险。

// goto.cpp
int main (){
	goto mark ;
        int x = 1 ;
	mark : printf("*") ;
	return 0 ;
}

在程序中,mark是printf语句的标识符,使用goto语句可以使程序直接执行到mark行,起到一个无条件跳转的功能。但是因为是无脑跳转,所以在跳转完以后可能会出现变元没申明的语法错误。如上面的程序,x的声明就被跳过,在后期使用x时就会出现错误。goto语句一直是被认为是有反编程设计思想的。但是,尽管很难把握,goto语句在跳出循环方面还是有很大的作用,尤其是多重嵌套。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值