100 Days of Code-day21

本文探讨如何使用递归设计思路编写itoa函数,从高位到低位将整数转换成字符串,避免反转操作。在递归过程中,系统通过堆栈保存局部变量,确保信息不丢失。对比初始版本和改进版本,改进版更高效,减少了不必要的条件判断。
摘要由CSDN通过智能技术生成

运用递归的设计思想编写一个递归版本的itoa函数。即通过递归调用把整数转换为字符串。

在采用递归方法时,我们可以直接按照整数最高位到最低位的顺序,将整数的每一位放入字符串数组中。也就是说不需要再通过反转字符串来得到最终结果。
如下图所示,为了先获得最高位,这里通过不断对数字进行取整操作直到结果为0。
在这里插入图片描述
那么在这个过程中就会出现一个问题,在不断对函数进行递归调用的过程中,我们会不会丢失了局部变量(比如形参)。
计算机告诉我们:不会!!!
原因:递归调用会使用系统提供的堆栈空间。遇到递归语句时就开始递归调用自身,如下面程序段所示。

	if (n / 10)
		itoa(n / 10, num);//递归语句

如图1所示,当第一次调用时,为了防止丢失掉相关信息(局部变量以及程序被暂时终止(或者说是被打断)的位置),系统先将它们压入堆栈,起到保存这些信息的作用。
随后便将参数123传入第二次调用。以此类推,不断地将每次函数中变量的信息压入到堆栈中。直到n/10=0时不在继续进行入栈操作。此时程序可以正常进行。也就是下面所示的程序块。

	else
	{
		i = 0;
		if (n < 0)
		{
			num[i++] = '-';
		}
	}
	num[i++] = abs(n) % 10 + '0';
	num[i] = '\0';

这段程序执行结束后,得到了字符串数组num=“1”。接着程序自动返回到上一层函数的执行被打断的位置,继续执行后续程序。以此类推,不断进行出栈操作,直到堆栈为空。
在这里插入图片描述图1
初始版本相对于改进版本的不足时,下面这段程序

int	sign =0;

	if (n < 0)
	{
		sign = -1;
		n = -n;
	}
	if (sign < 0)
		num[i++] = '-';

在初始版本中,每次进行入栈操作的时候都需要判断n和sign是否小于0。而后者只需要在最高位要被放入字符串数组之前判断n是否小于0即可。

初始版本:

#define MaxSize 100
void itoa(int n,char num[])
{
	static int i = 0;
	int	sign =0;

	if (n < 0)
	{
		sign = -1;
		n = -n;
	}
	if (sign < 0)
		num[i++] = '-';
	if(n/10)
		itoa(n/10,num);
	num[i++] = n % 10 + '0';
	num[i] = '\0';
}

int main()
{
	int number = 1234;
	int i = 0;
	char num[MaxSize];
	
	itoa(number, num);
	printf("%s", num);
	return 0;
}

改进版本:

#define MaxSize 100
void itoa(int n,char num[])
{
	static int i ;
	
	if (n / 10)
		itoa(n / 10, num);
	else
	{
		i = 0;
		if (n < 0)
		{
			num[i++] = '-';
		}
	}
	num[i++] = abs(n) % 10 + '0';
	num[i] = '\0';
}

int main()
{
	int number = 1234;
	int i = 0;
	char num[MaxSize];
	
	itoa(number, num);
	printf("%s", num);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值