C语言程序设计——A+B A-B

题目描述

【难度系数】3 级

【任务描述】 我们知道,计算机程序中,某种数据类型的变量能存储的数的取值范围是有限的,这是因为分配给 变量的存储空间是有限的。但在实际问题中运算的数,可能超过基本数据类型的表示范围,例如,如果 一个星球距离我们 100 万光年,那么将其化简为公里或米时,我们会发现这是一个很大的数,计算机无 法直接对其进行计算。 本问题的要求是:编写程序,实现任意长度正整数的加法、减法运算。

【功能要求】

(1) 被计算的正整数长度在 10 位以上,1000 位以下。

(2) 任意输入两个长整数,可进行它们的加、减运算,输出运算结果。

(3) 设计一个简单的交互界面,根据用户要求,完成指定的大数运算。

代码思路

我们只要实现大数的加和减即可,具体思路见代码。

功能模块

代码

/*题目 A+B A-B
 实现功能
 (1) 被计算的正整数长度在 10 位以上,1000 位以下。
 (2) 任意输入两个长整数,可进行它们的加、减运算,输出运算结果。
 (3) 设计一个简单的交互界面,根据用户要求,完成指定的大数运算
 */
/*设计思路:
具体设计思路如下:
*声明了主要的函数和全局变量;
*add函数是加法操作的核心代码,采用了将输入的数字倒序存储在字符串中的方式,然后进行加法运算;
*cmp函数用于比较两个数的大小,以确定减法的运算方式;
*sub函数是减法操作的核心代码,采用了借位相减法的方式来实现减法运算;
*subready函数用于减法的准备工作,接收用户输入并进行减法运算;
*addready函数用于加法的准备工作,接收用户输入并进行加法运算;
*choice函数根据用户的选择进行相应的操作,并提供继续或退出的选项;
*UI函数是界面函数,展示交互界面,接收用户的选择并调用choice函数。
实现思路如下:
*数组对于尾部的增删操作比较方便,因此本程序采用将输入的数字倒序存储在字符串中的方式;
*加法运算使用进位的方法,在有效位数中保存当前位的数字,并将进位保存;
*减法运算中,需要考虑前大还是后大,以确定是否添加负号,并通过借位相减法的方式来实现减法运算;
*通过比较字符串长度来判断是否超出范围;
*支持用户的交互选择,提供加法和减法运算的选项,并根据用户的选择进行相应的操作。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>

/*声明函数*/
void UI();//界面
int* add(int* a,int* b,int alen,int blen);//加法操作核心代码
int cmp(int *a, int *b, int size_a, int size_b);//减法比较函数
void sub(int *a, int *b, int size_a, int size_b, int *c);//减法函数
void subready();//减法准备
void addready();//加法准备
void choice(char c);//选择

/*全局变量*/
int len;

int main(){
    UI();
    return 0;
}

// 加法函数
int* add(int* a,int* b,int alen,int blen){
    int* c;
    len=0; // 长度初始化
    int t=0,i;
    c=(int*) malloc(sizeof (int)*1000); // 分配内存
    for(i=0;i<alen||i<blen;i++){ // 逐位相加
        if(i<alen) t+=*(a+i);  // 如果a数组有数字,就加上
        if(i<blen) t+=*(b+i);  // 如果b数组有数字,就加上
        *(c+i)=(t%10);  // 通过模运算来计算出当前位的数字
        t/=10; // 将进位保存
        len++; // 更新长度
    }
    if(t){ // 处理超出原字符串长度的进位
        *(c+i)=1; // 处理进位
        len++; // 更新长度
    }
    return c; // 返回结果数组
}

// 减法比较函数
int cmp(int *a, int *b, int size_a, int size_b){
    if(size_a != size_b) return size_a > size_b; // 比较字符串长度
    for(int i = size_a - 1; i >= 0; i--){ // 逐位比较
        if(a[i] != b[i]){ // 当前位数值不相等
            return a[i] > b[i]; // 返回前大还是后大
        }
    }
    return 1; // 默认返回前大
}

// 减法函数
void sub(int *a, int *b, int size_a, int size_b, int *c){
    len=0; // 初始化长度
    int t = 0; // 临时变量,表示借位或当前数
    for(int i = 0; i < size_a; i++){
        t = a[i] - t; // 用当前数前去借位数,并存储在t中
        if(i < size_b) t -= b[i]; // 如果b的长度够,再减去b的当前位数
        c[i] = (t + 10) % 10; // 计算当前位的减法结果
        if(t < 0) t = 1; // 判断是否需要借位
        else t = 0;
        len++;  // 更新长度
    }
    while(size_a > 1 && c[size_a - 1] == 0) { // 去除前导0
        size_a--;
        len--;
    }
}

// 减法准备
void subready(){
    char a[1500]={0}, b[1500]={0};
    printf("请输入第一个数:");
    gets(a);
    printf("请输入第二个数:");
    gets(b);
    for(int i=0;i<strlen(a);i++){
        if(a[i]<'0'||a[i]>'9'){
            puts("*系统提示:非法字符,请重新输入");
            return ;
        }
    }
    for(int i=0;i<strlen(b);i++){
        if(b[i]<'0'||b[i]>'9'){
            puts("*系统提示:非法字符,请重新输入");
            return ;
        }
    }
    if(strlen(a)>=1000|| strlen(b)>=1000){ // 检查输入长度
        puts("*系统提示:数字太长(10-1000位之内),请重新输入");
        Sleep(2000);
        return;
    }
    int size_a = strlen(a);
    int size_b = strlen(b);
    int A[size_a], B[size_b];
    for(int i = size_a - 1; i >= 0; i--){ // 倒序保存到数组中
        A[size_a - 1 - i] = a[i] - '0';
    }
    for(int i = size_b - 1; i >= 0; i--){
        B[size_b - 1 - i] = b[i] - '0';
    }
    if(cmp(A, B, size_a, size_b)){ // 比较字符串大小决定减数和被减数
        int c[size_a];
        sub(A, B, size_a, size_b, c); // 减法计算
        puts("请稍后.....");
        Sleep(800);
        printf("计算成功:%s-%s=",a,b);
        for(int i = len - 1; i >= 0; i--){ // 输出结果
            printf("%d", c[i]);
        }
    }else{
        int c[size_b];
        sub(B, A, size_b, size_a, c); // 减法计算
        puts("请稍后.....");
        Sleep(800);
        printf("计算成功:%s-%s=",a,b);
        printf("-"); // 比较谁大来添加-
        for(int i =len-1; i >= 0; i--){ // 输出结果
            printf("%d", c[i]);
        }
    }
    printf("\n");
}

// 加法准备
void addready(){
    char str1[1200]={0},str2[1200]={0};
    int a[1000]={0},b[1000]={0};
    printf("请输入第一个数:");
    gets(str1);
    printf("请输入第二个数:");
    gets(str2);
    for(int i=0;i<strlen(str1);i++){
        if(str1[i]<'0'||str1[i]>'9'){
            puts("*系统提示:非法字符,请重新输入");
            return ;
        }
    }
    for(int i=0;i<strlen(str2);i++){
        if(str2[i]<'0'||str2[i]>'9'){
            puts("*系统提示:非法字符,请重新输入");
            return ;
        }
    }
    if(strlen(str1)>=1000|| strlen(str2)>=1000){ // 检查输入长度
        puts("*系统提示:数字太长(10-1000位之内),请重新输入");
        Sleep(2000);
        return;
    }
    for(int i=strlen(str1)-1,j=0;i>=0;i--,j++){ // 倒序保存到数组中
        a[j]=str1[i]-'0';
    }
    for(int i=strlen(str2)-1,j=0;i>=0;i--,j++){
        b[j]=str2[i]-'0';
    }
    int* c;
    c=add(a,b, strlen(str1),strlen(str2)); // 调用加法函数
    puts("请稍后.....");
    Sleep(800);
    printf("计算成功:%s+%s=",str1,str2);
    for (int i = len-1; i >=0; i--) { // 输出结果
        printf("%d",*(c+i));
    }
    puts("");
}

// 选择操作
void choice(char c){
    while (1) {
        switch (c) {
            case '1':
                addready(); // 加法
                puts("还继续吗?(y,n)");
                Sleep(1000);
                char cc;
                scanf("%c",&cc); // 用户选择是否继续
                if(cc=='y'){
                    system("cls");
                    UI();
                }
                if(cc=='n') {
                    puts("感谢使用本产品");
                    Sleep(2000);
                    exit(0);
                }
                break;
            case '2':
                subready();  // 减法
                puts("还继续吗?(y,n)");
                Sleep(1000);
                char ch;
                scanf("%c",&ch); // 用户选择是否继续
                if(ch=='y'){
                    system("cls");
                    UI();
                }
                if(ch=='n'){
                    puts("感谢使用本产品");
                    Sleep(2000);
                    exit(0);
                }
                break;
            default:
                puts("您输入的数字错误,请重新输入");
                return;
        }
    }
}

// 界面函数
void UI(){
    char choise;
    system("cls");
    system("color 0F");
    printf("\t\t\t\t-----------------------------------\n");
    printf("\t\t\t\t|       欢迎使用计算系统           |\n");
    printf("\t\t\t\t-----------------------------------\n");
    printf("\t\t\t\t|       >1.加法运算                |\n");
    printf("\t\t\t\t-----------------------------------\n");
    printf("\t\t\t\t|       >2.减法运算                |\n");
    printf("\t\t\t\t-----------------------------------\n");
    printf("\t\t\t\t|       >0.退出系统                |\n");
    printf("\t\t\t\t-----------------------------------\n");
    Sleep(2000);
    printf("\t\t\t\t请选择功能> ");
    fflush(stdin);
    scanf("%c",&choise);
    fflush(stdin);
    choice(choise); // 用户选择
}

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值