📄 运算器.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct node //定义节点
{
char data;
struct node *next,*prior;
}lnode;
typedef struct //定义链表,包含头尾指针及链表
{ //整数位,小数位长度
lnode *head,*end;
int before,after;
}list;
int b=0;
void initlist(list **L)
{
(*L)=(list *) malloc(sizeof(list));
(*L)->head=(lnode *) malloc(sizeof(lnode));
(*L)->end=(lnode *) malloc(sizeof(lnode));
(*L)->head->next=(*L)->end;
(*L)->head->prior=NULL;
(*L)->end->prior=(*L)->head;
(*L)->end->next=NULL;
}
void after_increase(list *L,char c) //完成从表尾插入字符c的操作
{
lnode *p;
p=(lnode*) malloc(sizeof(lnode));
p->data=c;
p->prior=L->end->prior;
L->end->prior=p;
p->prior->next=p;
p->next=L->end;
}
void before_increase(list *L,char c) //完成从表头插入字符c的操作
{
lnode *p;
p=(lnode *) malloc(sizeof(lnode));
p->data=c;
p->next=L->head->next;
L->head->next=p;
p->next->prior=p;
p->prior=L->head;
}
void add_zero(list *L1,list *L2) //加零函数,补零使两个数据的整数位和小数位的
{ //长度相同,以便加减时使小数点对齐
while(L1->after>L2->after)
{
after_increase(L2,'0');
L2->after++;
}
while(L2->after>L1->after)
{
after_increase(L1,'0');
L1->after++;
}
while(L2->before<L1->before)
{
before_increase(L2,'0');
L2->before++;
}
while(L2->before>L1->before)
{
before_increase(L1,'0');
L1->before++;
}
}
void sign(list *L,int n) //加小数点的函数,使运算结果根据两个
{ //运算数据的小数位长度添加小数点
lnode *p,*q;
int i;
p=L->end;
for(i=1;i<=n;i++)
{
p=p->prior;
}
q=(lnode *) malloc(sizeof(lnode));
q->data='.';
q->prior=p->prior;
q->next=p;
p->prior=q;
q->prior->next=q;
}
int compare(list *L1,list *L2) //比较两个数据大小的函数
{
lnode *p,*q;
int temp;
p=L1->head->next;
q=L2->head->next;
if(L1->before>L2->before) //整数位不同
temp=1;
else
{
if(L2->before>L1->before)
temp=-1;
else
{
temp=p->data-q->data; //整数位相同
while(temp==0)
{
p=p->next;
q=q->next;
temp=p->data-q->data;
}
}
}
if(temp>0)
return(1);
else
{
if(temp==0)
return(2);
else
return(3);
}
}
void copylist(list *L1,list *L2) //保存数据函数,使L1中得到的数据保存在L2中
{
lnode *q;
char a;
for(q=L2->head->next;q!=L2->end;q=q->next)
{
a=q->data;
after_increase(L1,a);
}
}
void clean(list *L) //清空链表函数,将L清空
{
L->head->next=L->end;
L->end->prior=L->head;
}
void add(list **L1,list **L2,list *L3) //加法运算
{
lnode *p,*q;
char a;
int b=0;
for(p=(*L1)->end->prior,q=(*L2)->end->prior;p!=(*L1)->head;p=p->prior,q=q->prior)
{
a=p->data+q->data-48+b; //字符与整型差48
b=0; //b为进位
if(a>'9') //大于9需要进位
{
a=a-10;
b=1;
}
before_increase(L3,a); //将运算的结果插入链表
}
if(b) //运算L1,L2最高位,如有进位
{
before_increase(L3,'1');
L3->before++;
}
}
void sub(list *L1,list *L2,list *L3) //减法运算
{
lnode *p,*q;
char a;
int b=0;
if(compare(L1,L2)==1) //比较大小,保证是大数减小数
{
for(p=L1->end->prior,q=L2->end->prior;p!=L1->head;p=p->prior,q=q->prior)
{
a=p->data-q->data+48-b;
b=0; //b是借位标志
if(a<'0') //需要借位
{
a=a+10;
b=1;
}
before_increase(L3,a); //将结果插入链表
}
}
else
{
sub(L2,L1,L3); //如果L1数值大于L2,交换顺序
}
}
void mult(list *L1,list *L2,list **L3) //乘法运算
{
lnode *p,*q;
char a;
int k;
int m=0; //m为一个开关
list *temp1,*temp2;
initlist(&temp1); //temp1用来保存当前一位相乘的结果
initlist(&temp2); //temp2用来保存L2以前每位相乘后的结果的和
temp2->after=0;
for(q=L2->end->prior;q!=L2->head;q=q->prior)//L2每一位分别与L1相乘
{
temp1->before=0;
for(p=L1->end->prior;p!=L1->head;p=p->prior)//L1每一位与L2当前位相乘
{
k=(p->data-48)*(q->data-48)+b;
b=0; //b是进位
if(k>9) //需要进位
{
b=k/10;
a=k%10+48;
}
else
a=k+48;
before_increase(temp1,a); //将结果插入链表
temp1->before++;
}
if(b!=0) //最高位有进位情况
{
a=b+48;
before_increase(temp1,a);
temp1->before++;
b=0;
}
if(L2->end->prior==L2->head->next) //如果L2仅有一位的情况
{
copylist((*L3),temp1);
break;
}
else
{
if(m) //L2已经超过两位与L1相乘,需要相加
{
copylist(temp2,*L3); //将已有的结果保存在temp2中
clean(*L3);
temp2->after++; //将temp2小数点左移,相当与
temp2->before--; //与L1错开一位
temp1->after=0;
add_zero(temp1,temp2);
add(&temp1,&temp2,*L3); //L2两位分别与L1相乘的结果相加
clean(temp2);
clean(temp1);
}
else //L2当前仅有一位与L1相乘
{
copylist(*L3,temp1);
temp2->before=temp1->before;
clean(temp1);
}
}
m=1;
}
}
void cut(list *L) //去掉运算多余的零函数
{
lnode *p,*q;
p=L->head->next;
q=L->end->prior;
while(p->data=='0') //去掉整数部分的零
{
if(p->next->data=='.')
break;
else
{
L->head->next=p->next;
p->next->prior=L->head;
p=p->next;
}
}
while(1) //去掉小数部分的零
{
if(q->data=='.') //小数部分全部为零的情况
{
q->prior->next=q->next;
q->next->prior=q->prior;
free(q);
break;
}
if(q->data=='0')
{
L->end->prior=q->prior;
q->prior->next=L->end;
q=q->prior;
}
else
break;
}
}
int judge(list *L) //判断L的数据是否是零的函数
{
lnode *p;
int a=0;
for(p=L->head->next;p!=L->end;p=p->next)
{
if(p->data!='0')
{
a=1;
break;
}
}
if(a)
return(1);
else
return(0);
}
void readnum(char filename[],list *L) //从文件读取数据函数,并记录整数位,小数位个数
{
FILE *fp;
char c;
int n=0;
int m=1;
L->before=0;
L->after=0;
fp=fopen(filename,"r");
while(!feof(fp))
{
c=fgetc(fp);
if(c>='0'&&c<='9'||c=='.'||c=='-') //读完最后一位还要相下读取一位,故要舍去
{
if(c=='.') //小数点不读取
{
m=0;
continue;
}
if(c=='-') //负号不读取
{
before_increase(L,c);
continue;
}
if(m)
{
after_increase(L,c);
L->before++;
}
if(!m)
{
after_increase(L,c);
L->after++;
}
}
else
break;
}
fclose(fp);
}
int freesign(list *L) //取数的绝对值函数
{
lnode *p;
p=L->head->next;
if(p->data=='-')
{
p=L->head->next;
L->head->next=p->next;
p->next->prior=L->head;
p->next=p;
p->prior=p;
free(p);
return(1);
}
else
return(0);
}
void writenum(char filename[],list *L) //将结果写入文件函数
{
FILE *fp;
char c;
lnode *p;
fp=fopen(filename,"w");
for(p=L->head->next;p!=L->end;p=p->next)
{
c=p->data;
fputc(c,fp);
}
fclose(fp);
}
void main()
{
list *L1,*L2,*L3;
int sign1=0,sign2=0;
int com;
char filename1[10],filename2[10];
char filename3[]="add.txt";
char filename4[]="sub.txt";
char filename5[]="mult.txt";
initlist(&L1); //第一个数据
initlist(&L2); //第二个数据
initlist(&L3); //运算结果
printf("input the first file's name");
gets(filename1);
printf("input the second file's name");
gets(filename2);
readnum(filename1,L1); //将第一个数据保存在L1中
readnum(filename2,L2); //将第二个数据保存在L2中
sign1=freesign(L1); //取L1的绝对值,并判断正负
sign2=freesign(L2); //取L2的绝对值,并判断正负
com=compare(L1,L2); //比较L1,L2绝对值大小
if(sign1==0&&sign2==0) //L1,L2都是正数情况
{
if(judge(L1)&&judge(L2))
{
mult(L1,L2,&L3);
sign(L3,(L1->after+L2->after));
cut(L3);
}
else
before_increase(L3,'0');
writenum(filename5,L3);
clean(L3);
add_zero(L1,L2);
add(&L1,&L2,L3);
sign(L3,L1->after);
cut(L3);
writenum(filename3,L3);
clean(L3);
if(com!=2)
{
sub(L1,L2,L3);
if(com==3)
before_increase(L3,'-');
sign(L3,L1->after);
cut(L3);
}
else
before_increase(L3,'0');
writenum(filename4,L3);
clean(L3);
}
if(sign1==1&&sign2==1) //L1,L2都是负数情况
{
if(judge(L1)&&judge(L2))
{
mult(L1,L2,&L3);
sign(L3,(L1->after+L2->after));
cut(L3);
}
else
before_increase(L3,'0');
writenum(filename5,L3);
clean(L3);
add_zero(L1,L2);
add(&L1,&L2,L3);
sign(L3,L1->after);
cut(L3);
before_increase(L3,'-');
writenum(filename3,L3);
clean(L3);
if(com!=2)
{
sub(L1,L2,L3);
sign(L3,(L1->after,L2->after));
cut(L3);
if(com==1)
before_increase(L3,'-');
}
else
before_increase(L3,'0');
writenum(filename4,L3);
clean(L3);
}
if(sign1==0&&sign2==1) //L1为正,L2为负情况
{
if(judge(L1)&&judge(L2))
{
mult(L1,L2,&L3);
sign(L3,(L1->after+L2->after));
cut(L3);
before_increase(L3,'-');
}
else
before_increase(L3,'0');
writenum(filename5,L3);
clean(L3);
add_zero(L1,L2);
if(com!=2)
{
sub(L1,L2,L3);
sign(L3,L1->after);
cut(L3);
if(com==3)
before_increase(L3,'-');
}
else
before_increase(L3,'0');
writenum(filename3,L3);
clean(L3);
add(&L1,&L2,L3);
sign(L3,L1->after);
cut(L3);
writenum(filename4,L3);
clean(L3);
}
if(sign1==1&&sign2==0) //L1为负,L2为正情况
{
if(judge(L1)&&judge(L2))
{
mult(L1,L2,&L3);
sign(L3,(L1->after+L2->after));
cut(L3);
before_increase(L3,'-');
}
else
before_increase(L3,'0');
writenum(filename5,L3);
clean(L3);
add_zero(L1,L2);
if(com!=2)
{
sub(L1,L2,L3);
sign(L3,L1->after);
cut(L3);
if(com==1)
before_increase(L3,'-');
}
else
before_increase(L3,'0');
writenum(filename3,L3);
clean(L3);
add(&L1,&L2,L3);
sign(L3,L1->after);
cut(L3);
before_increase(L3,'-');
writenum(filename4,L3);
clean(L3);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -