📄 加减乘运算器3.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 intlength,floatlength; /*整数位、小数位长度*/
}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;
}//initlist
/***********************************************************************************/
void end_insert(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;
}// end_insert
/**********************************************************************************/
void head_insert(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;
}//head_insert
/************************************************************************************/
void add_zero(list *L1,list *L2) /*加零函数,补零使两个数据的整数位和小数位的长度相同,以便加减时使小数点对齐*/
{
while(L1->floatlength>L2->floatlength) /*当表1中的数的小数位长度大于表2的数的小数位长度时,给表2的小数部分从后补零*/
{
end_insert(L2,'0');
L2->floatlength++; /*表2的小数位长度增加*/
}
while(L2->floatlength>L1->floatlength) /*当表1中数的小数位长度小于表2的数的小数位长度时,给表1的小数部分从后补零*/
{
end_insert(L1,'0');
L1->floatlength++; /*表1的小数位长度增加*/
}
while(L2->intlength<L1->intlength) /*当表2的整数位长度小于表1的整数位长度时,给表2的整数部分从前补零*/
{
head_insert(L2,'0');
L2->intlength++; /*表2的整数位长度增加*/
}
while(L2->intlength>L1->intlength) /*当表2的整数位长度大于表1的整数位长度时,给表1的整数部分从前补零*/
{
head_insert(L1,'0');
L1->intlength++; /*表1的整数位长度增加*/
}
}//add_zero
/*************************************************************************************/
void add_point(list *L,int n) /*加小数点的函数,使运算结果根据两个运算数据的小数位长度添加小数点*/
{
lnode *p,*q;
int i;
p=L->end;
for(i=1;i<=n;i++) /*从表尾开始向前,直到保证小数点后有n位小数*/
{
p=p->prior;
}
q=(lnode *) malloc(sizeof(lnode));
q->data='.';
q->prior=p->prior; /*将'.'插入链表的操作*/
q->next=p;
p->prior=q;
q->prior->next=q;
}//add_point
/*************************************************************************************/
int compare(list *L1,list *L2) /*比较两个数据大小的函数*/
{
lnode *p,*q;
int temp;
p=L1->head->next;
q=L2->head->next;
if(L1->intlength>L2->intlength) /*当前一个数的整数位长度大于后一个数的整数位长度时*/
temp=1;
else
{
if(L2->intlength>L1->intlength) /*当前一个数的整数位长度小于后一个数的整数位长度时*/
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);
}
}//compare
/***************************************************************************************/
void storelist(list *L1,list *L2) /*保存数据函数,使L2中得到的数据保存在L1中*/
{
lnode *q;
char a;
for(q=L2->head->next;q!=L2->end;q=q->next)
{
a=q->data;
end_insert(L1,a);
}
}//storelist
/***************************************************************************************/
void clean(list *L) /*清空链表函数,将L清空*/
{
L->head->next=L->end;
L->end->prior=L->head;
}//clean
/*****************************************************************************************************************************/
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;
}
head_insert(L3,a); /*将运算的结果插入链表*/
}
if(b) /*运算L1,L2最高位,如有进位*/
{
head_insert(L3,'1');
L3->intlength++;
}
}//add
/*****************************************************************************************************************************/
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;
}
head_insert(L3,a); /*将结果插入链表*/
}
}
else
{
sub(L2,L1,L3); /*如果L1数值大于L2,交换顺序*/
}
}//sub
/******************************************************************************************************************************/
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->floatlength=0;
for(q=L2->end->prior;q!=L2->head;q=q->prior) /*L2每一位分别与L1相乘*/
{
temp1->intlength=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;
head_insert(temp1,a); /*将结果插入链表*/
temp1->intlength++;
}
if(b!=0) /*最高位有进位情况*/
{
a=b+48;
head_insert(temp1,a);
temp1->intlength++;
b=0;
}
if(L2->end->prior==L2->head->next) /*如果L2仅有一位的情况*/
{
storelist((*L3),temp1);
break;
}
else
{
if(m) /*L2已经超过两位与L1相乘,需要相加*/
{
storelist(temp2,*L3); /*将已有的结果保存在temp2中*/
clean(*L3); /*清空表3*/
temp2->floatlength++;
temp2->intlength--; /*将temp2小数点左移,相当于与L1错开一位*/
temp1->floatlength=0;
add_zero(temp1,temp2); /*补零使两个数据的整数位和小数位长度相同*/
add(&temp1,&temp2,*L3); /*L2两位分别与L1相乘的结果相加,将最终结果放入表3中*/
clean(temp2);
clean(temp1);
}
else /*L2当前仅有一位与L1相乘时*/
{
storelist(*L3,temp1);
temp2->intlength=temp1->intlength;
clean(temp1);
}
}
m=1;
}
}//mult
/*******************************************************************************************************************************/
void cut_zero(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=='.') /*小数部分全部为零的情况*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -