⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 加减乘运算器3.c

📁 用双向链表实现任意位数的正负整数或小数的加法、减法和乘法运算以及对文件的相关操作。 文件说明: 给定的文件a*.txt为第一个数
💻 C
📖 第 1 页 / 共 2 页
字号:

#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 + -