C语言程序设计(简单一些更好)

设计一种结构能表示最多1000位的大整数,(正负均可),并实现这类数的加、减运算。
在座的各位程序员,下午五点就要交了,谢谢!

供参考:http://www.javashuo.com/article/p-nvngulti-nk.html

这是我以前写的算法,有点复杂凌乱,仅供参考!

#include<stdio.h>
#include<string.h>


//减法算法
char *sub(char *s1, char *s2);

//加法算法
char *add(char *s1, char *s2);



int main(int argc, char** argv){
    char *res;//结果
    int i=0;
    char a[1000];//第一个操作数
    char b[1000];//第二个操作数
    
    printf("分别输入a,b\n");
    printf("a=");
    scanf("%s",a);
    printf("\n");
    printf("b=");
    scanf("%s",b);
    
    printf("\n输入运算符,加则输入1,减则输入2。\n");
    scanf("%d",&i);
    if(i==1)
    {
        res=add(a,b);
        printf("(%s)+(%s)=%s\n",a,b,res);
    }
    else if(i==2)
    {
        res=sub(a,b);
        printf("(%s)-(%s)=%s\n",a,b,res);
    
    }
     
    free(res);
    
    return 0;
  }






//加法算法
char *add(char *s1, char *s2)
{
    int s1len=strlen(s1);
    int s2len=strlen(s2);
    int len1 = 0, len2 = 0;//对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的

    
    int count1=0,count11=0;//分别是第一个数的小数部分长度 和 整数部分长度
        int F1 = 0; //用于判断是否是小数,是小数F1=1,否则F1=0
    for (int i = 0; i < s1len; i++)
    {
        if (*(s1 + i) == '.') { F1 = 1; break; }
    }

    //若是小数则 计算小数部分长度
    for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
    {
        if (*(s1 + i) != '.')
            count1++;
        else
            break;
    }
    //计算第一个加数的整数部分长度
    count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;

    //相同方法处理第二个加数
    int count2 = 0, count22 = 0;
    int F2 = 0;
    for (int i = 0; i < s2len; i++)
    {
        if (*(s2 + i) == '.') { F2 = 1; break; }
    }

    for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
    {
        if (*(s2 + i) != '.')
            count2++;
        else
            break;
    }
    count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;

    len1 = (count1 > count2) ? count1 : count2;
    int cc = len1;//用于后面标记小数的位置,这几行语句顺序不能颠倒
    len1 += (count11 > count22) ? count11 : count22;
    len2 = len1;

    //为两个加数定义为a和b并为其动态分配内存空间
    int *a = (int*)malloc(sizeof(int)*len1);
    int *b = (int*)malloc(sizeof(int)*len2);
    if (!a || !b)return "error";
    //初始化a和b  len1和len2其实是一样大的
    for (int i = 0; i < len1; i++)
    {
        *(a + i) = 0;
        *(b + i) = 0;
    }

    //定义和变量 以及取得长度
    int len = len1 + 1;
    int *sum = (int*)malloc(sizeof(int)*len);
    if (!sum)return "error";
    //初始化和变量
    for (int i = 0; i < len; i++)*(sum + i) = 0;

    int tt1 = count1 - count2;//用计算补齐几个0用
    for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
    {
        if (tt1 < 0)
        {
            while (tt1) 
            {
                *(a + j--) = 0; tt1++;
            }
        }
        if (*(s1 + i) == '.')i--;
        if (i >= 0)
            *(a + j) = *(s1 + i) - '0';
        else
            *(a + j) = 0;
    }

    int tt2 = count2 - count1;//用计算补齐几个0用
    for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
    {
        if (tt2 < 0)
        {
            while (tt2)
            {
                *(b + j--) = 0; 
                tt2++;
            }
        }
        if (*(s2 + i) == '.')i--;
        if (i >= 0)
            *(b + j) = *(s2 + i) - '0';
        else
            *(b + j) = 0;
    }

    int cou = 0;
    for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
    {
        cou++;
        if (cou <= len1)
        {
            *(sum + i) = *(a + j) + *(b + k);
        }
        else *(sum + i) = 0;
    }

    int temp1 = 0;
    for (int i = len - 1; i >= 0; i--)
    {
        temp1 = *(sum + i);
        *(sum + i) =*(sum + i) % 10;
        if (i > 0)
            *(sum + i - 1) += temp1 / 10;
    }

    //输出
    char *sumres = (char*)malloc(sizeof(char)*(len+1));
    if(!sumres)return "error!";
    memset(sumres,'0',len+1);
 
    int i,j;
    for ( i = 0, j=0; i < len; i++,j++)
    {
        if( (F1 || F2) && ( i == (len - cc) ) )
        {
            *(sumres+i)='.';
            j=i+1;
        }
        *(sumres+j)=(char)(*(sum+i)+'0');
    }
    *(sumres+j)='\0';

    //释放
    free(a);
    free(b);
    free(sum);

    return sumres;
}


//减法算法
char *sub(char *s1, char *s2)
{
    int abc = 1;//用于判断结果正负  负数abc赋值为-1
    int s1len=strlen(s1);
    int s2len=strlen(s2);
    int len1 = 0, len2 = 0;//对拷s1和s2并转换成数字后补齐位数后的长度,若是小数其实len1和len2的长度是一样的


    int count1 = 0, count11 = 0;//分别是第一个数的小数部分长度 和 整数部分长度
    int F1 = 0; //用于判断是否是小数,是小数F1=1,否则F1=0
    for (int i = 0; i < s1len; i++)
    {
        if (*(s1 + i) == '.') { F1 = 1; break; }
    }

    //若是小数则 计算小数部分长度
    for (int i = s1len - 1; i >= 0 && (F1 == 1); i--)
    {
        if (*(s1 + i) != '.')
            count1++;
        else
            break;
    }
    //计算第一个加数的整数部分长度
    count11 = (F1 == 1) ? (s1len - 1 - count1) : s1len;

    //相同方法处理第二个加数
    int count2 = 0, count22 = 0;
    int F2 = 0;
    for (int i = 0; i < s2len; i++)
    {
        if (*(s2 + i) == '.') { F2 = 1; break; }
    }

    for (int i = s2len - 1; i >= 0 && (F2 == 1); i--)
    {
        if (*(s2 + i) != '.')
            count2++;
        else
            break;
    }
    count22 = (F2 == 1) ? (s2len - 1 - count2) : s2len;

    len1 = (count1 > count2) ? count1 : count2;
    int cc = len1;//用于后面标记小数的位置,这几行语句顺序不能颠倒
    len1 += (count11 > count22) ? count11 : count22;
    len2 = len1;

    //为两个加数定义为a和b并为其动态分配内存空间
    int* a = (int*)malloc(sizeof(int)*len1);
    int* b = (int*)malloc(sizeof(int)*len2);
    if (!a || !b)return "error";
    //初始化a和b  len1和len2其实是一样大的
    for (int i = 0; i < len1; i++)
    {
        *(a + i) = 0;
        *(b + i) = 0;
    }

    //定义结果变量c  以及取得长度
    int len = len1 ;
    int* c= (int*)malloc(sizeof(int)*len);
    if (!c)return "error";
    //初始化和变量
    for (int i = 0; i < len; i++)*(c + i) = 0;

    int tt1 = count1 - count2;//用计算补齐几个0用
    for (int i = s1len - 1, j = len1 - 1; j >= 0; i--, j--)
    {
        if (tt1 < 0)
        {
            while (tt1)
            {
                *(a + j--) = 0; tt1++;
            }
        }
        if (*(s1 + i) == '.')i--;
        if (i >= 0)
            *(a + j) = *(s1 + i) - '0';
        else
            *(a + j) = 0;
    }

    int tt2 = count2 - count1;//用计算补齐几个0用
    for (int i = s2len - 1, j = len2 - 1; j >= 0; i--, j--)
    {
        if (tt2 < 0)
        {
            while (tt2)
            {
                *(b + j--) = 0;
                tt2++;
            }
        }
        if (*(s2 + i) == '.')i--;
        if (i >= 0)
            *(b + j) = *(s2 + i) - '0';
        else
            *(b + j) = 0;
    }
    //-------------------
    //判断a与b的大小,大数作为第一个数 
    int a1 = 0, b1 = 0;//用于判断a和b哪个大大的就赋值为1
    for (int i = 0; i < len1; i++)
    {
        int tmp=*(a + i) - *(b + i);
        if (tmp > 0)
        {
            a1 = 1; break;
        }
        else if (tmp < 0)
        {
            b1 = 1;
            abc = -1;
            break;
        }
        //如果循环结束a1==0 && b1==0表示a和b相等 结果直接为0即可
    }

    //a>=b时情况
    int cou = 0;
    if((a1 == 1) || (a1 == 0 && b1 == 0))
    for (int i = len - 1, j = len1 - 1, k = len2 - 1;   i >= 0; i--, j--, k--)
    {
        int vv = 0; //是否借位的记号  借位赋值1
        int n = 0;//借位移动了几位
        cou++;
        int tmp1=  *(a + j) - *(b + k);
        
        if (cou <= len1 )
        {
             if(tmp1>=0)
             { 
                *(c + i) = tmp1;
             }
             else//向高位(低索引处借位)
             {
                 tmp1 += 10;
                 *(c + i) = tmp1;
                 vv = 1;
             }            
        }
        else *(c + i) = 0;

        //处理借位
        if (vv == 1)
        for (int ccc = j-1;ccc >= 0 && j>0;ccc--)
        {
            if (*(a + ccc) == 0)n++;
            else
                break;
        }
        if (vv == 1)
            for (int bb = n; bb<j && bb>0;  bb--)
            {
                *(a +j-bb) += 9;
            }

        //借位处减去1
        if (vv == 1 && j >= (n + 1))
            *(a + (j - n - 1)) -= 1;        

        //重置
        vv = 0;
        n = 0;
    }

    //a<b情况
    int cou2 = 0;
    if ((b1 == 1))
        for (int i = len - 1, j = len1 - 1, k = len2 - 1; i >= 0; i--, j--, k--)
        {
            int vv = 0; //是否借位的记号  借位赋值1
            int n = 0;//借位移动了几位
            cou2++;
            int tmp1 = *(b + k)-*(a + j) ;

            if (cou2 <= len2)
            {
                if (tmp1 >= 0)
                {
                    *(c + i) = tmp1;
                }
                else//向高位(低索引处借位)
                {
                    tmp1 += 10;
                    *(c + i) = tmp1;
                    vv = 1;
                }
            }
            else *(c + i) = 0;

            //处理借位
            if(vv==1)
            for (int ccc = j - 1; ccc >= 0 && j>0; ccc--)
            {
                if (*(b+ ccc) == 0)n++;
                else
                    break;
            }
            if (vv == 1)
            for (int bb = n;  bb<k && bb>0;  bb--)
            {
                *(b +k - bb ) += 9;
            }
            
            //借位处减去1
            if (vv == 1 && k>=(n+1) )
                *(b + (k - n - 1)) -= 1;
         
            //重置
            vv = 0;
            n = 0;
        }

    char *resc= (char*)malloc(sizeof(char)*(len+1));
    if(!resc)return "error!";
    memset(resc,'0',len+1);
    //输出
    int i,j;
    for (i = 0,j=0; i < len; i++,j++)
    {
        if(abc==-1)
        {
            *(resc+j++)='-';
            abc = 1;
        }
        if((F1 || F2) && (i == (len - cc)))
        {
            *(resc+j++)='.';
        }
        *(resc+j)=(char)(*(c + i)+'0');
    }
    *(resc+j)='\0';

    //释放
    free(a);
    free(b);
    free(c);
    
    return resc;
}




img

img

img

img