📄 大整数加减运算源程序.c
字号:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define LEN sizeof(struct lnode)
#define NULL 0
struct lnode /*定义结构体类型*/
{
int data; /*数据域*/
struct lnode *next; /*指针域*/
};
struct lnode *creat(int *len) /*创建链表存放大整数,len用于求所输入的大整数的位数*/
{
struct lnode *h,*p,*q;
char x;
q=h=(struct lnode *)malloc(LEN); /*生成头结点*/
x=getchar(); /*输入大整数的符号,并存放在头结点中*/
h->data=x;
while((x=getchar())!='\n') /*输入大整数并存放在链表中,以回车键结束*/
{
(*len)++; /*统计大整数的位数*/
p=(struct lnode *)malloc(LEN); /*开辟新的结点存放数据*/
p->data=x-'0'; /*把输入的数存放在新开辟的结点中*/
q->next=p;
q=p;
}
q->next=NULL;
return(h);
}
void print(struct lnode *h) /*打印大整数以及计算结果*/
{
struct lnode *p,*t; /*定义指针变量*/
p=h; /*把指针变量指向头结点*/
printf("%c",p->data); /*打印大整数的符号*/
p=p->next;
if(p->next==NULL&&p->data==0) /*如果计算结果为0,则输出0*/
printf("\n\t%d.\n",p->data);
else
{
while(p&&p->data==0) /*去掉开头的0,保证在开头第一个结点中的数是以实际输出,不带补充的0*/
{
t=p;
p=p->next;
free(t);
}
while(p!=NULL)
{
printf("%d",p->data);
p=p->next;
}
printf("\n");
}
}
struct lnode *nizhuan(struct lnode *h) /*逆转大整数*/
{
struct lnode *p,*q;
if(h->next&&h->next->next) /*当大整数的位数有三位以上时,进行逆转*/
{
p=h->next; /*指针p指向大整数的第一位*/
q=p->next; /*指针q指向大整数的第二位*/
p->next=NULL; /*在大整数的第一位与第二位之间断开,原来的链表变为两个*/
while(q) /*每次将指针q指向第二个链表的第一个结点,插入到头结点的下一位*/
{
p=q;
q=q->next;
p->next=h->next;
h->next=p;
}
}
return(h);
}
struct lnode *add(struct lnode *h1,struct lnode *h2) /*大整数加法运算*/
{
int f=0; /*进位标志,初始化为0*/
struct lnode *h3;
struct lnode *p,*q,*s;
h1=nizhuan(h1); /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
h2=nizhuan(h2);
p=h1; /*把定义的两个指针变量p,q分别指向两个链表的头结点*/
q=h2;
s=h3=(struct lnode *)malloc(LEN); /*创建第三个链表存放计算结果*/
s->data=p->data; /*计算结果的符号为其中一个大整数的符号*/
p=p->next;
q=q->next;
while(p!=NULL&&q!=NULL) /*当两个大整数的位数相同时*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
s->data=p->data+q->data+f;
if(s->data>=10) /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
{
s->data=s->data-10;
f=1;
}
else
f=0;
p=p->next;
q=q->next;
}
while(p!=NULL) /*当第一个大整数的位数大于第二个大整数时,将第一个大整数的非空结点copy到计算结果*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
s->data=p->data+f;
if(s->data>=10) /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
{
s->data=s->data-10;
f=1;
}
else
f=0;
p=p->next;
}
while(q!=NULL) /*当第二个大整数的位数大于第一个大整数时,将第二个大整数的非空结点加上f后copy到计算结果*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
s->data=q->data+f;
if(s->data>=10) /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
{
s->data=s->data-10;
f=1;
}
else
f=0;
q=q->next;
}
if(p==NULL&&q==NULL&&f==1) /*当最高位计算完毕后出现进位的时候,开辟一个新的结点存储进位*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
s->data=f;
}
s->next=NULL;
return(h3); /*返回计算结果的头指针*/
}
struct lnode *sub(struct lnode *h1,struct lnode *h2) /*位数不同的大整数减法运算*/
{
struct lnode *h3;
struct lnode *p,*q,*s;
int f=0; /*初始化借位标志*/
h1=nizhuan(h1); /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
h2=nizhuan(h2);
p=h1; /*把定义的指针变量p,q分别指向两个存放大整数的链表的头结点*/
q=h2;
s=h3=(struct lnode *)malloc(LEN); /*创建第三个链表存放计算结果*/
s->data=p->data; /*计算结果的符号为位数多的大整数的符号*/
p=p->next;
q=q->next;
while(q!=NULL)
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
if((p->data)>=(q->data))
{
s->data=p->data-q->data+f;
f=0;
}
if((p->data)<(q->data)) /*当需要借位时把借位标志设为-1*/
{
s->data=(p->data)+10-(q->data)+f;
f=-1;
}
if(s->data<0) /*当s的值小于0时,把所得的值加10,并把借位标志设为-1*/
{
s->data=s->data+10;
f=-1;
}
p=p->next;
q=q->next;
}
while(p!=NULL)
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
if(p->data==0) /*当需要借位时把借位标志设为-1*/
{
s->data=p->data+10+f;
f=-1;
}
else
{
s->data=p->data+f; /*否则把位数多的大整数的非空结点加上f后copy到计算结果中*/
f=0;
}
p=p->next;
}
s->next=NULL;
return(h3); /*返回计算结果的头指针*/
}
struct lnode *sub1(struct lnode *h1,struct lnode *h2) /*位数相同的大整数减法运算*/
{
struct lnode *h3;
struct lnode *p,*q,*s;
int flag=0,f=0; /*若第一个数大于第二个数,flag则设为1,f为借位标志*/
p=h1->next;
q=h2->next;
s=h3=(struct lnode *)malloc(LEN);
while(p!=NULL&&q!=NULL) /*比较两个大整数的大小*/
{
if(p->data>q->data)
{
h3->data=h1->data; /*若第一个数大于第二个数,计算结果的符号为第一个数的符号*/
flag=1;
break;
}
else if(p->data<q->data)
{
h3->data=h2->data; /*若第一个数小于第二个数,计算结果的符号为第二个数的符号*/
break;
}
p=p->next;
q=q->next;
}
h1=nizhuan(h1); /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
h2=nizhuan(h2);
p=h1->next;
q=h2->next;
while(p!=NULL&&q!=NULL)
{
if(flag==1) /*当第一个数大于第二个数,用第一个数的对应位减去第二个数的对应位*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
if((p->data)>=(q->data))
{
s->data=p->data-q->data+f;
f=0;
}
if((p->data)<(q->data))
{
s->data=(p->data)+10-(q->data)+f; /*当需要借位时把借位标志设为-1*/
f=-1;
}
}
else /*当第二个数大于第一个数,用第二个数的对应位减去第一个数的对应位*/
{
s->next=(struct lnode *)malloc(LEN);
s=s->next;
if((q->data)>=(p->data))
{
s->data=q->data-p->data+f;
f=0;
}
if((q->data)<(p->data))
{
s->data=(q->data)+10-(p->data)+f; /*当需要借位时把借位标志设为-1*/
f=-1;
}
}
p=p->next;
q=q->next;
}
s->next=NULL;
return(h3); /*返回计算结果的头指针*/
}
menu() /*显示该程序的相关功能*/
{printf("\t\t ***欢迎使用!***\n");
printf("\t\t **************************************************\n");
printf("\t\t| 1.输入并输出数据 |\n");
printf("\t\t| 2.加法运算 |\n");
printf("\t\t| 3.减法运算 |\n");
printf("\t\t| 4.退出系统 |\n");
printf("\t\t **************************************************\n");
}
main() /*主函数*/
{
struct lnode *h1,*h2,*h3;
char ch;
char c;
int i;
int *len1,*len2;
int x=0,y=0;
len1=&x; /*初始化符号*/
len2=&y;
menu();
start:printf("\ninput your opt:\n");
scanf("%d",&i);
switch(i)
{
case 1:
if((c=getchar())=='\n') /*产生两个大整数*/
{
printf("请以输入一个数:\n");
h1=creat(len1);
printf("请以输入另一个数:\n");
h2=creat(len2);
printf("一个数是:");
print(h1);
printf("另一个数是:");
print(h2);
goto start;
}
case 2:
{
if(h1->data==h2->data) /*如果两个大整数的符号相同,则调用加法函数*/
{
h3=add(h1,h2);
printf("进行加法运算所得结果是:");
h3=nizhuan(h3); /*逆转计算结果,使计算结果以正常顺序输出*/
print(h3); /*打印结果*/
h1=nizhuan(h1); /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
h2=nizhuan(h2);
}
if(h1->data!=h2->data) /*若两个大整数的符号不同时,相加转化为相减*/
{
if((*len1)>(*len2))
h3=sub(h1,h2);
if((*len1)<(*len2))
h3=sub(h2,h1);
if((*len1)==(*len2))
h3=sub1(h1,h2);
printf("进行加法运算所得结果是:");
h3=nizhuan(h3); /*逆转计算结果,使计算结果以正常顺序输出*/
print(h3); /*打印结果*/
h1=nizhuan(h1); /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
h2=nizhuan(h2);
}
goto start;
}
case 3:
{
if(h1->data==43&&h2->data==43) /*当两个大整数为负数时减法运算*/
{
h2->data=45;
if((*len1)>(*len2))
h3=sub(h1,h2);
if((*len1)<(*len2))
h3=sub(h2,h1);
if((*len1)==(*len2))
h3=sub1(h1,h2);
printf("进行减法运算所得结果是:");
h3=nizhuan(h3); /*逆转计算结果,使计算结果以正常顺序输出*/
print(h3); /*打印结果*/
h2->data=43;
h1=nizhuan(h1); /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
h2=nizhuan(h2);
}
if(h1->data==45&&h2->data==45) /*当两个大整数为正数时的减法运算*/
{
h2->data=43;
if((*len1)>(*len2))
h3=sub(h1,h2);
if((*len1)<(*len2))
h3=sub(h2,h1);
if((*len1)==(*len2))
h3=sub1(h1,h2);
printf("进行减法运算所得结果是:");
h3=nizhuan(h3); /*逆转计算结果,使计算结果以正常顺序输出*/
print(h3); /*打印结果*/
h2->data=45;
h1=nizhuan(h1); /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
h2=nizhuan(h2);
}
if(h1->data!=h2->data) /*两个符号不同的大整数相减,可看成是两个符号相同的大整数相加*/
{
h3=add(h1,h2);
printf("进行减法运算所得结果是:");
h3=nizhuan(h3); /*逆转计算结果,使计算结果以正常顺序输出*/
print(h3);
h1=nizhuan(h1); /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
h2=nizhuan(h2);
}
goto start;
}
case 4:
{
printf("是否退出系统?(y/n)\n"); /*判断是否推出系统*/
getchar();
ch=getchar();
getchar();
if(ch=='y'||ch=='Y')
exit(0);
else
goto start;
}
default:printf("Sorry!\nError!\nPlease input again.\n");
goto start;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -