简单LinuxC程序关于任意长整数相加(字符串实现)

本文介绍如何在Linux环境下使用C语言通过字符串实现大整数相加的方法,包括输入处理、数字验证、字符串对齐及进位处理等关键步骤。

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

Linux环境下,C语言中整数类型最长的是long long类型,占8个字节,即使如此,其能表示的数仍是有限的。如果想要实现更大的整数相加或其他运算,就不能只用long long类型或者普通整型。我们可以使用字符串来表示整数,可以由我们规定位数,这样就可以实现更大的(某种意义上的任意长)整数相加减。在这里,我使用字符串实现的是两个任意长整数相加。由于是使用的字符串,需要考虑的情况很多。下面我罗列几个需要注意的点:

1、输入的问题:

使用的输入方法不同,需要注意的点也不同。若是使用scanf("%s",str),需要考虑字符数组的大小,但使用这个函数有个缺点,如果无意输入了空格,由于该函数不读空格,检测不出这个错误。我使用的是fgets(str,SIZE,stdin)函数,需要注意的是,若是输入的字符串长度(不包括回车)小于SIZE-1,则会将回车符读入,需要去掉回车符;若是输入的字符串长度(不包括回车)等于或大于SIZE-1,多余的字符(包括回车)不会读入,但是会留在缓冲区,输入下一个字符串时,会直接将这些字符读入,所以要先清空缓冲区(再用fgets读一下)。

2、是否是数字:

在字符串读取后,需要判断每一个字符是否是数字字符或者'\0',不是的话就要报错。

3、对齐的问题:

我们进行整数加法是最低位对齐的,从最低位开始计算,但是我们输入字符数字后,字符串是从最高位对齐的。所以解决的办法可以将两个字符串逆序,计算后将结果逆序回来。

4、进位的问题:

进行正常的整数加法不需要我们考虑进位问题,计算机会给我们解决。但是使用字符串计算就需要考虑这个问题了,当两个数相加后(这里还要考虑一个问题就是不能直接字符相加,需要减掉一个字符0),大于字符9,就要进位,下一位计算时要考虑前一位是否进位过来。(当两个字符串不等长时,不等长的部分相加不需要减字符0)最后还要考虑最高位的问题,如果有进位,长度会加1,要处理一下以保证正常输出。

其他的一下细节大家细心一点就行,下面是我实现的具体代码:

#include <stdio.h>
#include <string.h>
#define SIZE 1024  //输入的数最长为SIZE-1

//字符串数字相加
int add(char *str1,char *str2,char *str3,int len)
{
	if(str1 == NULL || str2 == NULL || str3 == NULL)
	{
		printf("参数错误\n");
		return -1;
	}
	int i;
	for (i = 0;i < len ;i++)
	{
		if(str1[i] == 0 || str2[i] == 0)  //如果某个字符串对应位为'\0',结果为另一个字符串对应位的值
		{
			str3[i] += (str1[i] + str2[i]);
		}
		else  //如果两个字符串对应位都不为'\0',结果为两个字符ASCII码值相加并减去字符0的ASCII码值。
		{
			str3[i] += str1[i] + str2[i] - '0';
		}
		if(str3[i] > '9')  //如果相加后的结果大于字符9的ASCII码值,则需要进位(更高位加1),原本位ASCII码值减10
		{
			str3[i+1] += 1;
			str3[i] -= 10;
		}
	}
	if(str3[i] > 0)  //最高位若是向更高为有进位,将数字1转换为字符1
	{
		str3[i] += '0';
	}
	return 0;
}

//字符串逆序
int Reverse(char *str,int len)
{
	if (str == NULL)
	{
		printf("参数错误\n");
		return -1;
	}
	int i;
	char tmp;
	for(i = 0;i < len/2;i++)
	{
		tmp = str[i];
		str[i] = str[len-i-1];
		str[len-i-1] = tmp;
	}
	return 0;
}

//检查字符串中有没有非数字字符并去掉回车符
int check(char *str,int *len)
{
	if (str == NULL || len == NULL)
	{
		printf("参数错误\n");
		return -1;
	}
	if(str[(*len)-1] == '\n')  //去掉回车符
	{
		str[(*len)-1] = 0;
		(*len)--;
	}
	int i;
	for(i = 0;i < *len;i++)
	{
		if(str[i] != 0 && (str[i] < '0' || str[i] > '9'))
		{
			printf("输入的数字中有非数字以外的字符!\n");
			return -1;
		}
	}
	return 0;
}

int main()
{
	//初始化三个字符串
	char str1[SIZE] = {0};
	char str2[SIZE] = {0};
	char str3[SIZE+1] = {0};
	
	//输入字符串
	printf("input a number        : ");
	fgets(str1,SIZE,stdin);
	int len1 = strlen(str1);
	int lentmp = len1;
	if(check(str1,&len1))  //检查字符串中有没有非数字字符并去掉回车符
		return -1;
	if(len1 == lentmp)  //如果有字符没有被读取,则先读掉
	{
		fgets(str2,SIZE,stdin);
	}
	
	printf("input another number  : ");
	fgets(str2,SIZE,stdin);
	int len2 = strlen(str2);
	if(check(str2,&len2))
		return -1;
	
	//逆序两个字符串,使得表示的数字最低位对齐
	if(Reverse(str1,len1))
		return -1;
	if(Reverse(str2,len2))
		return -1;
	
	//判断两个字符串长短,取更长的字符串的长度作为参数给add函数
	int len;
	len1 > len2 ? (len = len1) : (len = len2);
	if(add(str1,str2,str3,len))
		return -1;
	
	//将结果逆序回来
	int len3 = strlen(str3);
	if(Reverse(str3,len3))
		return -1;
	
	printf ("The sum of two numbers: %s\n",str3);
	
	return 0;
}





有关更多字符串和整数之间的相互转换的知识,希望和大家一起讨论分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值