The C Programming language3

3-4 在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-(2的(字长-1)次方)。请解释原因,修改函数,使它在任何机器上运行时都能打印出正确的值。

答:最大的负数是指8-bit表示中的-128,用补码表示是10000000。当然,1000 0000是原码时候表示-0,但是00000000也可以表示0,所以把10000000设定为-128的原码,即8-bit表示补码时的范围是-128~127,正好256个数。在书本中p52的itoa(),当n是负数时,n=-n,直接限定n不能等于-128;那么为何n=-n?因为后面的循环条件是while((n/=10)>10)。为了不用n=-n,我们改为while(n/10)这样无论n是正负数,当n为个位后,n/10都是0,不满足循环条件。

以上思路均来自答案。但是我用递归调用实现itoa(),即整数转换为字符串。递归有一个好处是不用reverse()函数。

#include <stdio.h>
#include <stdlib.h>
#include<limits.h>
#include <string.h>
#define MAX 15

int itoa(int,int,char*);
int main(void)
{
	int i,location=0;
	char s[MAX];
	printf("INT_MIN=%d\n", INT_MIN);
	location = itoa(INT_MIN, location, s);
	s[location] = '\0';
	puts(s);

	getchar();
	return 0;
}
int itoa(int N,int location,char* s)
{
	if (N == 0)
	{
		return location;
	}
	location = itoa(N / 10, location,s);
	if (N<0&&location==0)
	{
		s[location++] = '-';
	}
	s[location++] = abs(N % 10) + '0';
	if (location == MAX - 1)
	{
		printf("The num has exceed the maximum of string!\n");
		getchar();
		exit(0);
	}
	return location;
}

3-5就是把上面的功能实现为任意进制。主要在于什么时候用数字字符,什么时候用字母字符,以及字母字符的转换。

#include <stdio.h>
#include <stdlib.h>
#include<limits.h>
#include <string.h>
#define MAX 15
#define STEP 16

int itoa(int,int,char*,int );
int main(void)
{
	int i,location=0;
	char s[MAX];
	printf("INT_MIN=%d\n", INT_MIN);
	location = itoa(-5000, location, s,STEP);
	s[location] = '\0';
	puts(s);

	getchar();
	return 0;
}
int itoa(int N,int location,char* s,int step)
{
	int a;
	if (N == 0)
	{
		return location;
	}
	location = itoa(N / step, location, s, step);
	if (N<0&&location==0)
	{
		s[location++] = '-';
	}
	if ((a=N%step)<10)
		s[location++] = abs(N % step) + '0';
	else
		s[location++] = abs(N % step) + 'a' - 10;
	
	if (location == MAX - 1)
	{
		printf("The num has exceed the maximum of string!\n");
		getchar();
		exit(0);
	}
	return location;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值