您的位置:首页 > 运维架构 > Linux

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

2017-08-17 16:00 351 查看
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;
}



有关更多字符串和整数之间的相互转换的知识,希望和大家一起讨论分享。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息