设计一个实现任意长的整数进行加减法运算的演示程序。

    基本要求:利用双向循环链表实现长整数的存储,每个结点含一个整形变量。任何整形变量的范围是 -(2^15 - 1)~(2^15 - 1)。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。    

测试数据:

(1)0;0;应输出“0”。

(2)-2345,6789;-7654,3211;应输出“-1,0000,0000”。

(3)-9999,9999;1,0000,0000,0000;应输出“9999,0000,0001”。

(4)1,0001,0001;-1,0001,0001;应输出“0”。

(5)1,0001,0001;-1,0001,0000;应输出“1”。

(6)-9999,9999,9999;-9999,9999,9999;应输出“1,9999,9999,9998”。

(7)1,0000,9999,9999;1;应输出“1,0001,0000,0000”。
程序如下:
#define NULL 0
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct Qnode{    
    int num;            /*数字*/
    struct Qnode *low1;    /*指向低一位结点*/
    struct Qnode *high1;    /*指向高一位结点*/
}Qnode,* longnode;
typedef struct {        
    longnode High;        /*指向最高节点*/
    longnode Low;        /*指向最低节点*/
    int digit4;        /*每个结点整数的总位数(不包括高位的0)/4 */
}xlong;
void  init(xlong *a,int digit4){        /*初始化循环链表a*/
    int i;
    longnode j,k=0;
    a=(xlong*)malloc(sizeof(xlong));    /* 为a的头结点申请空间,并赋初始值 */
    a->High=NULL;
    a->Low=NULL;
    a->digit4=0;
    for(i=0;i<digit4;i++){                /* 申请digit4个结点,初始化 */
        j=(longnode)malloc(sizeof(Qnode));
        j->num=0;
        j->high1=NULL;
        j->low1=a->High;        
        if(a->High)
            a->High->high1=j;
        else
            a->Low=j;
        a->High=j;
        a->digit4++;
    }
    
}
int pass(xlong *a,xlong *b,xlong *c){        /* 两个数字的相加 */
    int cf=0;
    longnode a1=a->Low,b1=b->Low,c1=c->Low;
    while(a1){
        c1->num=a1->num+b1->num+cf;
        if(c1->num>9999){        /* 如果产生进位(借位) */
            cf=1;
            c1->num-=10000;
        }else{
            cf=0;
        }
        a1=a1->high1;b1=b1->high1;c1=c1->high1;
    }
    return cf;                /* 最高位的进位(借位) */
}
int passa(xlong *a,xlong *b,xlong *c){        /* 两个数字的相减 */
    int cf=0;
    longnode a1=a->Low,b1=b->Low,c1=c->Low;
    while(a1){
        c1->num=a1->num-b1->num-cf;
        if(c1->num>9999){        /* 如果产生进位(借位) */
            cf=1;
            c1->num-=10000;
        }else{
            cf=0;
        }
        a1=a1->high1;b1=b1->high1;c1=c1->high1;
    }
    return cf;                /* 最高位的进位(借位) */
}
void nep(xlong *a){            /* 求a的相反数 */
    int cf=1;        /* 因为求相反数是取反加一,所以这里cf=1; */
    longnode a1=a->Low;
    while(a1){
        a1->num=9999-(a1->num)+cf;
        if(a1->num>9999){
            a1->num-=10000;
        }else{
            cf=0;
        }
        a1=a1->high1;
    }
    return;
}
void printlong(xlong *a){        /* 打印长整数a */
    longnode i=a->High;
    if(i->num>=5000){    /* 最高位(bit)=1表示负数,即用补码表示 */
        printf("-");
        nep(a);        /* 求反打印其绝对值 */
    }
    while(i&&i->num==0) i=i->low1;    /* 跳过最位的0 */
    if(i){
        printf("%d",i->num);
        i=i->low1;
        if(i) printf(",");
    }else printf("0");            /* a=0 打0 */
    while(i){
         printf("%04d",i->num);
        if(i->low1)
         printf(",");
        i=i->low1;
    }
}
int ston(char in[],xlong *out)
{        /* 把字符串转化为数字赋给a */
    int bit,i,jishu=1,num0=0;
    longnode j=out->Low;
    i=strlen(in)-1;
    printf("strlen=%d\n",i);
    while(i>=0 /*&& j*/)
    {        /* 循环每一个字节 */
        bit=in[i]-'0';        /* 把字符形式的值赋给整数形式的bit */
        if(bit>=0 && bit <=9)
        {
            num0+=jishu*bit;    /* 加进num0 */
            jishu*=10;    /* 基数自乘10 */
            printf("%d\n",num0);
            if(jishu>=10000)
            { /* 数字以外的字符 */
                j->num=num0;
                j=j->high1;    /* 存入一个节点 */
                num0=0;
                jishu=1;
            }
        }    i--;
    }
    if(num0){j->num=num0;j=j->high1;}    /* 把最后一个没存入节点的数存入节点 */
    for(;j;j=j->high1) j->num=0;    /* 最位不足补0 */
    if(out->High->num>=5000) return 1;    /* 如果最高位是1,返回1表示出错 */
    if(in[0]=='-') nep(out);        /* 如果最后一个字符是'-'则取反 */
    return 0;
}
void add(){                              /*加*/
        char *a1,*b1;
        int digit4,cf=0;
        xlong a,b,c;
    do{
    printf("How much digits do you need(0<n<16)?");    /* 输入最多位数 */
    scanf("%d",&digit4);
     }while(digit4<=0);
     a1=(char*)malloc(sizeof(digit4+1));
     b1=(char*)malloc(sizeof(digit4+1));
     digit4=digit4/4+1;
    init(&a,digit4);init(&b,digit4);init(&c,digit4); /* 初始化a,b,c */
   do{
    cf=0;
    printf("Enter 2 number:\n");
    scanf("%s",a1);
    printf("+\n");cf=ston(a1,&a);
    scanf("%s",b1);
    
    cf=ston(b1,&b);
   }while(cf);        /* 输入被加数和加数,如果转换出错,则重输 */
   pass(&a,&b,&c);        /* 执行相加运算 */
   printlong(&a);printf("+");    /* 打印结果 */
   printlong(&b);printf("=");
   printlong(&c);printf("\n");
}
void subtract()              /*减*/
{     char *a1,*b1;
        int digit4,cf=0;
        xlong a,b,c;
    do{
    printf("How much digits do you need(0<n<16)?");    /* 输入最多位数 */
    scanf("%d",&digit4);
     }while(digit4<=0);
     a1=(char*)malloc(digit4+1);
     b1=(char*)malloc(digit4+1);
     digit4=digit4/4+1;
    init(&a,digit4);init(&b,digit4);init(&c,digit4); /* 初始化a,b,c */
   do{
    cf=0;
    printf("Enter 2 number:\n");
    scanf("%s",a1);
    printf("-\n");
    scanf("%s",b1);
    cf|=ston(a1,&a);
    cf|=ston(b1,&b);
   }while(cf);        /* 输入被减数和减数,如果转换出错,则重输 */
   passa(&a,&b,&c);        /* 执行相减运算 */
   printlong(&a);printf("-");    /* 打印结果 */
   printlong(&b);printf("=");
   printlong(&c);printf("\n");
}
void main()
{      int c;
      printf("\n***本程序实现长整数四则运算***\n");
      printf("1: ------ADD\n");
      printf("2: ------SUBTRACT\n");
    c=getch();
    switch(c){
            case '1': add();break;
            case '2': subtract();    break;
              }
}