【乱七八糟】atoi、itoa、递归

atoi是C标准库提供的一个接口,函数原型大致为:

int atoi(const char* pch);
不考虑太多异常情况,可以这样实现:

int atoi(const char* pch)
	{
		if (NULL == pch)
		{
			return 0;
		}

		int iSymbol = 1;
		if (*pch == '-')
		{
			iSymbol = -1;
			++pch;
		}

		int num = 0;

		//遍历字符串
		while (*pch != '\0')
		{
			if (*pch>= '0' && *pch<='9')
			{
				num = 10*num + *pch++ - '0';
			}
			else
			{
				break;
			}
			
		}

		return num;
	}

我们知道,数字 + 字符0,可以得到其对应的字符,比如

1 + '0'  == '1'   对应可以得出 '1' - '0' == 0


C标准库未提供itoa这个接口,但很多编译器都有提供(比如vs就在stdlib.h中声明了),应用也比较广泛,一般声明为:

char* itoa(int _Val, char * _DstBuf,int _Radix);


不考虑太多异常情况,大致可以这样实现:

char* itoa(int _Val, char * _DstBuf,int _Radix)
	{
		//只支持2、8、10、16进制
		if(_Radix != 10 && _Radix != 16 && _Radix != 8 && _Radix != 2)
		{
			_DstBuf = '\0';
			return _DstBuf;
		}


		//每个进制每位对应的字符
		char index[]="0123456789ABCDEF";
		
		int i=0;
		int j = 0;
		int k = 0;
		unsigned unum = 0;;			  

		//10进制负数
		if(_Radix==10 && _Val<0) 
		{
			k=1; 
			unum=(unsigned)-_Val;
			_DstBuf[i++]='-';
		}
		else
		{
			unum=(unsigned)_Val;
		}
		
		do	
		{
			_DstBuf[i++] = index[unum%(unsigned)_Radix];
			unum/=_Radix;
		}
		while(unum);


		_DstBuf[i]='\0';
		
		
		//反转字符串
		char temp;
		for(j=k;j<=(i-k-1)/2;j++)
		{
			temp=_DstBuf[j];
			_DstBuf[j] = _DstBuf[i-1+k-j];
			_DstBuf[i-j-1]=temp;
		}

		return _DstBuf;
	}


这里主要使用了/、%,还有数字/字符转换,以及字符串反转,以下大致解释下:

比如我调用的时候传参:

sr::itoa(98521,arr,16);
puts(arr);

意为将98521转换为16进制

在接口中,使用了index[]定义16进制每位的表现字符,使用下标可以一一对应


按照除16 + 模16,可以得到下面这个表

98521 %16   9  
6157   %16  13  
384     %16   0
24       %16   8
1         %16   1


最后一列再对应到index数组中的所有,可以得到9D081,反转后可得到1809D


--------------------------------------------------------华丽丽的分割线---------------------------------------------

其实按照上面那个表,可以获知,itoa其实也可以通过递归实现,而且由于递归使用了栈来存储中间过程设计的变量,遵循后进先出的规则,所以也不需要反转字符串

下面也大致实现下,为了方便起见,使用string来存储:

void itoa(string &str,int in_iNum,int n)
	{
		//不支持负数
		if (in_iNum < 0)
		{
			in_iNum = -1 *in_iNum;
		}

		int tmp_iVal = in_iNum/n;

		if (tmp_iVal != 0)
		{
			itoa(str,tmp_iVal,n);
		}	

		char index[]="0123456789ABCDEF";

		str.append(1,*(index + in_iNum%n));

	}

递归很重要的一点是何时结束调用,这里当tmp_iVal不为0时,递归调用自己,意思也就是,当tmp_iVal为0时,结束调用

ps:这里使用string的一个原因是如果使用char[],还需要关注下标,有个问题是如果再接口中定义变量用作下标变量,实际每次调用,都会是同样的值

所以这里不考虑性能问题,直接传入string,代码也会稍微整洁易懂些




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值