用C语言编写一个简单的计算器

要求以实现十进制浮点数的连续四则运算,并能够对括号的嵌套进行正确解析,能够解析“减号”和“负号”

img

img

花了一个多小时纯手工帮你写好了,你只需要加上你的学号姓名即可交差,如果满意,还请赏个采纳吧,谢谢

// Q7937325.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"

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

/*****************************************/
/* 将数字字符转化成浮点型实数进行计算 */
/*****************************************/
double readnum(char f[], int*i)
{
    double x = 0.0;
    int k = 0;
    while (f[*i] >= '0'&&f[*i] <= '9')
    {
        x = x * 10 + (f[*i] - '0');
        (*i)++;
    }
    if (f[*i] == '.')
    {
        (*i)++;
        while (f[*i] >= '0'&&f[*i] <= '9')
        {
            x = x * 10 + (f[*i] - '0');
            (*i)++;
            k++;
        }
    }
    while (k-->0)
    {
        x = x / 10.0;
    }
    return (x);
}
/*******************************/
/* 计算后缀表达式的值 */
/*******************************/
double evalpost(char f[])
{
    double obst[10];
    int top = 0;
    int i = 0;
    double x1, x2;
    while (f[i] != '=')
    {
        if (f[i] >= '0'&&f[i] <= '9')
        {
            obst[top] = readnum(f, &i); top++;
        }
        else if (f[i] == ' ')
            i++;
        else if (f[i] == '+')
        {
            x1 = obst[--top];
            x2 = obst[--top];
            obst[top] = x1 + x2;
            i++;
            top++;
        }
        else if (f[i] == '-')
        {
            x1 = obst[--top];
            x2 = obst[--top];
            obst[top] = x2 - x1;
            i++;
            top++;
        }
        else if (f[i] == '*')
        {
            x1 = obst[--top];
            x2 = obst[--top];
            obst[top] = x1*x2;
            i++;
            top++;
        }
        else if (f[i] == '*')
        {
            x1 = obst[--top];
            x2 = obst[--top];
            obst[top] = x1*x2;
            i++;
            top++;
        }
        else if (f[i] == '/')
        {
            x1 = obst[--top];
            x2 = obst[--top];
            obst[top] = x2 / x1;
            i++;
            top++;
        }
    }
    return obst[0];
}
/***********************************/
/* 判断字符是否为操作字符 */
/***********************************/
int is_operation(char op)
{
    switch (op)
    {
    case'^':
    case'K':
    case'+':
    case'-':
    case'*':
    case'/': return 1;
    default: return 0;
    }
}
/*****************************/
/* 判断字符的优先级 */
/*****************************/
int priority(char op)
{
    switch (op)
    {
    case'=': return -1;
    case'(': return 0;
    case'+':
    case'-': return 1;
    case'*':
    case'/': return 2;
    default: return -1;
    }
}
/******************************/
/* 中缀表达式转化成后缀表达式*/
/******************************/
void postfix(char e[], char f[])
{
    int i = 0, j = 0, k = 0;
    char opst[100];
    int top = 0;
    opst[0] = '='; top++;
    while (e[i] != '=')
    {
        if ((e[i] >= '0'&&e[i] <= '9') || e[i] == '.')
            f[j++] = e[i];
        else if (e[i] == '(')
        {
            opst[top] = e[i]; top++;
        }
        else if (e[i] == ')')
        {
            k = top - 1;
            while (opst[k] != '(') { f[j++] = opst[--top]; k = top - 1; }
            top--;
        }
        else if (is_operation(e[i]))
        {
            f[j++] = ' ';
            while (priority(opst[top - 1]) >= priority(e[i]))
                f[j++] = opst[--top];
            opst[top] = e[i];
            top++;
        }
        i++;
    }
    while (top) f[j++] = opst[--top]; f[j] = '\0';
}
void print_1(char val[])
{
    system("cls");
    printf("| ______________________________________ | \n");
    printf("| |                                    | | \n");
    printf("| |        欢迎使用多功能计算器        | | 本计算器能够进行10进制数 \n");
    printf("| |____________________________________| | +,/,*,/,()的连续运算\n");
    printf("| |____________________________________| | \n");
    printf("| |       设计人:这里放你的学号姓名   | | 输入所要经计算的表达式 \n");
    printf("| |____________________________________| | 如:a*b/(c-d)\n");
    printf("|                                        | \n");
    printf("|   %s", val);
    for (int i = 0; i < 35 - strlen(val); i++) 
        printf(" ");
    printf("  | \n");
    printf("| ___  ___  ___  ___  ___  ___  ___  ___ | \n");
    printf("|  ________ ________ ________ ________   | \n");
    printf("|  |      | |      | |      | |      |   | \n");
    printf("|  |  ⑨  | |  ⑧  | |  ⑦  | |  ×  |   | \n");
    printf("|  |______| |______| |______| |______|   | \n");
    printf("|  ________ ________ ________ ________   | \n");
    printf("|  |      | |      | |      | |      |   | \n");
    printf("|  |  ⑥  | |  ⑤  | |  ④  | |  -  |   | \n");
    printf("|  |______| |______| |______| |______|   | \n");
    printf("|  ________ ________ ________ ________   | \n");
    printf("|  |      | |      | |      | |      |   | \n");
    printf("|  |  ③  | |  ②  | |  ①  | |  +  |   | 继续计算/退出?1/0\n");
    printf("|  |______| |______| |______| |______|   | \n");
    printf("|  ________ ________ ________ ________   | \n");
    printf("|  |      | |      | |      | |      |   | \n");
    printf("|  |  〇  | |   = | |  AC  | |  ÷  |   | \n");
    printf("|  |______| |______| |______| |______|   | \n");
    printf("|________________________________________| \n");
    getch();
    system("cls");
}
void printf_2()
{
    system("cls");
    printf("\n\n\n\n\n\n\n\n\t\t\t ##############################\n");
    printf("\t\t\t # #\n");
    printf("\t\t\t #----------谢谢使用----------#\n");
    printf("\t\t\t # #\n");
    printf("\t\t\t ##############################\n");
    printf("\t\t\t --制作\n ");
}
/****************/
/* 转化 */
/****************/
void zhuanhuan(char g[], char e[])
{
    int k, i, j = 0;
    for (i = 0; g[i] != '='; i++)
    {
        k = i + 1;
        if (g[i] == '('&&g[k] == '-')
        {
            e[j++] = g[i];
            e[j++] = '0';
        }
        else e[j++] = g[i];
    }
    e[j] = '=';
}
int main()
{
    int wei;
    char e[100], f[100], g[100];
    int sign; int flag;
    print_1("0");
    do
    {
        printf("输入所要经计算的表达式(如:a*b/(c-d)=):\n");
        scanf("%s", g);
        zhuanhuan(g, e);
        postfix(e, f);
        printf("输出保留几位小数:\n");
        scanf("%d", &wei);
        char resstr[100];
        sprintf(resstr, "%s%.*lf", g, wei, evalpost(f));
        print_1(resstr);
        while (1)
        {
            flag = 3;
            printf("继续计算/退出?1/0?");
            sign = getch();
            printf("%c\n", sign);
            switch (sign)
            {
            case '1':flag = 1; getch(); break;
            case '0':flag = 0; getch(); break;
            default: printf("非法输入,请重新输入:\n");
            }
            if (flag == 1 || flag == 0)break;
        }
    } while (flag == 1);
    printf_2();
    return 0;
}

开发截图

img

以下是程序运行效果

img

img

threenewbee 不错

以下是一个简单的用C语言实现计算器的例子,可以支持四则运算和括号嵌套,仅供参考,可以根据实际需求进行优化。

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

#define MAX_EXPR_LEN 1024

char expr[MAX_EXPR_LEN + 1];
int cur_pos;

double parse_expr();

// 解析数字
double parse_number() {
    double num = 0.0;
    int decimal = 0;
    
    while (isdigit(expr[cur_pos])) {
        num = num * 10.0 + (expr[cur_pos] - '0');
        cur_pos++;
    }

    if (expr[cur_pos] == '.') {
        cur_pos++;
        while (isdigit(expr[cur_pos])) {
            num = num * 10.0 + (expr[cur_pos] - '0');
            decimal++;
            cur_pos++;
        }
    }

    while (decimal > 0) {
        num /= 10.0;
        decimal--;
    }

    return num;
}

// 解析加减法表达式
double parse_addsub() {
    double left, right, result;
    char op;

    left = parse_expr();
    while ((op = expr[cur_pos]) == '+' || op == '-') {
        cur_pos++;

        right = parse_expr();

        if (op == '+') {
            left += right;
        } else {
            left -= right;
        }
    }

    return left;
}

// 解析乘除法表达式
double parse_muldiv() {
    double left, right, result;
    char op;

    left = parse_number();
    while ((op = expr[cur_pos]) == '*' || op == '/') {
        cur_pos++;

        right = parse_number();

        if (op == '*') {
            left *= right;
        } else if (op == '/') {
            if (right == 0) {
                fprintf(stderr, "Error: divide by zero\n");
                exit(-1);
            }
            left /= right;
        }
    }

    return left;
}

// 解析表达式
double parse_expr() {
    double result;

    if (expr[cur_pos] == '(') {
        cur_pos++;
        result = parse_addsub();
        if (expr[cur_pos] != ')') {
            fprintf(stderr, "Error: missing ')'\n");
            exit(-1);
        }
        cur_pos++;
    } else {
        result = parse_muldiv();
    }

    return result;
}

int main() {
    printf("Please enter an expression: ");
    scanf("%s", expr);

    cur_pos = 0;
    double result = parse_addsub();

    printf("Result: %lf\n", result);

    return 0;
}

这里提供一个简单的实现,只支持十进制浮点数的四则运算。同时支持括号嵌套,并可以解析减号和负号。另外需要注意的是,由于C语言中没有直接支持字符串处理的函数,所以本例中使用了字符数组来存储表达式。为了防止内存溢出,我们使用了一个宏定义MAX_EXPR_LEN来约束表达式最长的长度,如果表达式超过这个长度,程序会报错。

C语言实现简易计算器

可以借鉴下
https://blog.csdn.net/weixin_46531416/article/details/117401042

这个是我的结课作业,本人南京某大学生,如果和我有同样需求的同学,ip也相同的话,可以借鉴,但请不要像我一样照抄,拜托了

以下是一个简单的计算器程序,支持十进制浮点数的四则运算和括号嵌套,可以解析减号和负号:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <math.h>

#define STACK_SIZE 100

typedef struct {
    int top;
    double items[STACK_SIZE];
} Stack;

void push(Stack *s, double value) {
    if (s->top == STACK_SIZE - 1) {
        printf("Stack overflow!\n");
        exit(EXIT_FAILURE);
    }
    s->items[++(s->top)] = value;
}

double pop(Stack *s) {
    if (s->top == -1) {
        printf("Stack underflow!\n");
        exit(EXIT_FAILURE);
    }
    return s->items[(s->top)--];
}

double evaluate(char *expr) {
    Stack values, ops;
    values.top = ops.top = -1;
    char *p = expr;
    while (*p != '\0') {
        if (*p == '(') {
            push(&ops, *p);
        } else if (isdigit(*p) || *p == '.') {
            double value = 0.0;
            while (isdigit(*p)) {
                value = value * 10.0 + (*p - '0');
                p++;
            }
            if (*p == '.') {
                p++;
                double fraction = 1.0;
                while (isdigit(*p)) {
                    fraction /= 10.0;
                    value += (*p - '0') * fraction;
                    p++;
                }
            }
            push(&values, value);
            continue;
        } else if (*p == '+' || *p == '-' || *p == '*' || *p == '/') {
            while (ops.top != -1 && ops.items[ops.top] != '(' &&
                ((*p != '+' && *p != '-') || (ops.items[ops.top] != '*' && ops.items[ops.top] != '/'))) {
                double b = pop(&values);
                double a = pop(&values);
                char op = pop(&ops);
                double result = 0.0;
                switch (op) {
                    case '+':
                        result = a + b;
                        break;
                    case '-':
                        result = a - b;
                        break;
                    case '*':
                        result = a * b;
                        break;
                    case '/':
                        result = a / b;
                        break;
                }
                push(&values, result);
            }
            push(&ops, *p);
        } else if (*p == ')') {
            while (ops.top != -1 && ops.items[ops.top] != '(') {
                double b = pop(&values);
                double a = pop(&values);
                char op = pop(&ops);
                double result = 0.0;
                switch (op) {
                    case '+':
                        result = a + b;
                        break;
                    case '-':
                        result = a - b;
                        break;
                    case '*':
                        result = a * b;
                        break;
                    case '/':
                        result = a / b;
                        break;
                }
                push(&values, result);
            }
            if (ops.top == -1) {
                printf("Mismatched parentheses!\n");
                exit(EXIT_FAILURE);
            }
            pop(&ops);
        } else {
            printf("Invalid character: %c\n", *p);
            exit(EXIT_FAILURE);
        }
        p++;
    }
    while (ops.top != -1) {
        if (ops.items[ops.top] == '(') {
            printf("Mismatched parentheses!\n");
            exit(EXIT_FAILURE);
        }
        double b = pop(&values);
        double a = pop(&values);
        char op = pop(&ops);
        double result = 0.0;
        switch (op) {
            case '+':
                result = a + b;
                break;
            case '-':
                result = a - b;
                break;
            case '*':
                result = a * b;
                break;
            case '/':
                result = a / b;
                break;
        }
        push(&values, result);
    }
    if (values.top != 0) {
        printf("Invalid expression!\n");
        exit(EXIT_FAILURE);
    }
    return pop(&values);
}

int main() {
    char expr[STACK_SIZE];
    printf("Enter an arithmetic expression: ");
    fgets(expr, STACK_SIZE, stdin);
    double result = evaluate(expr);
    printf("Result: %g\n", result);
    return 0;
}

该程序使用了两个栈来实现运算符优先级的解析,其中一个栈用于存储运算符,另一个栈用于存储操作数。

在处理数字时,程序使用了一个双精度浮点数来存储数值,并对小数点进行了特殊处理。

在处理运算符时,程序使用了一个循环来处理优先级较高的运算符,直到遇到优先级较低的或遇到括号为止。

在处理括号时,程序使用了一个栈来存储左括号,并在遇到右括号时弹出栈中的左括号,直到遇到匹配的左括号为止。

在处理错误情况时,程序使用了exit函数强制退出程序,并输出相应的错误信息。

该程序可以通过命令行输入算术表达式,并输出计算结果。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define MAX_STACK_SIZE 100
#define MAX_EXPRESSION_SIZE 200
typedef struct {
    double data[MAX_STACK_SIZE];
    int top;
} Stack;
void initStack(Stack *stack) {
    stack->top = -1;
}
int isStackEmpty(Stack *stack) {
    return stack->top == -1;
}
int isStackFull(Stack *stack) {
    return stack->top == MAX_STACK_SIZE - 1;
}
void push(Stack *stack, double value) {
    if (isStackFull(stack)) {
        printf("Stack overflow!\n");
        exit(1);
    }
    stack->data[++stack->top] = value;
}
double pop(Stack *stack) {
    if (isStackEmpty(stack)) {
        printf("Stack underflow!\n");
        exit(1);
    }
    return stack->data[stack->top--];
}
int isOperator(char c) {
    return (c == '+' || c == '-' || c == '*' || c == '/');
}
int priority(char c) {
    if (c == '+' || c == '-') return 1;
    else if (c == '*' || c == '/') return 2;
    else return 0;
}
void infixToPostfix(char infix[], char postfix[]) {
    Stack stack;
    initStack(&stack);
    int i = 0, j = 0;
    while (infix[i] != '\0') {
        if (isdigit(infix[i]) || infix[i] == '.') {
            postfix[j++] = infix[i++];
            while (isdigit(infix[i]) || infix[i] == '.') {
                postfix[j++] = infix[i++];
            }
            postfix[j++] = ' ';
        }
        else if (infix[i] == '(') {
            push(&stack, '(');
            i++;
        }
        else if (infix[i] == ')') {
            while (!isStackEmpty(&stack) && stack.data[stack.top] != '(') {
                postfix[j++] = pop(&stack);
                postfix[j++] = ' ';
            }
            if (!isStackEmpty(&stack) && stack.data[stack.top] == '(') {
                pop(&stack);
            }
            i++;
        }
        else if (isOperator(infix[i])) {
            while (!isStackEmpty(&stack) && stack.data[stack.top] != '(' && priority(stack.data[stack.top]) >= priority(infix[i])) {
                postfix[j++] = pop(&stack);
                postfix[j++] = ' ';
            }
            push(&stack, infix[i]);
            i++;
        }
        else {
            printf("Invalid character: %c\n", infix[i]);
            exit(1);
        }
    }
    while (!isStackEmpty(&stack)) {
        postfix[j++] = pop(&stack);
        postfix[j++] = ' ';
    }
    postfix[j] = '\0';
}
double evaluate(char postfix[]) {
    Stack stack;
    initStack(&stack);
    int i = 0;
    double operand1, operand2, result;
    while (postfix[i] != '\0') {
        if (isdigit(postfix[i]) || postfix[i] == '.') {
            char str[20];
            int j = 0;
            while (isdigit(postfix[i]) || postfix[i] == '.') {
                str[j++] = postfix[i++];
            }
            str[j] = '\0';
            push(&stack, atof(str));
        }
        else if (postfix[i] == '+') {
            operand2 = pop(&stack);
            operand1 = pop(&stack);
            result = operand1 + operand2;
            push(&stack, result);
            i++;
        }
        else if (postfix[i] == '-') {
            operand2 = pop(&stack);
            operand1 = pop(&stack);
            result = operand1 - operand2;
            push(&stack, result);
            i++;
        }
        else if (postfix[i] == '*') {
            operand2 = pop(&stack);
            operand1 = pop(&stack);
            result = operand1 * operand2;
            push(&stack, result);
            i++;
        }
        else if (postfix[i] == '/') {
            operand2 = pop(&stack);
            operand1 = pop(&stack);
            if (operand2 == 0) {
                printf("Divide by zero!\n");
                exit(1);
            }
            result = operand1 / operand2;
            push(&stack, result);
            i++;
        }
        else if (postfix[i] == ' ') {
            i++;
        }
        else if (postfix[i] == '-') {
            i++;
            char str[20];
            int j = 0;
            while (isdigit(postfix[i]) || postfix[i] == '.') {
                str[j++] = postfix[i++];
            }
            str[j] = '\0';
            push(&stack, -atof(str));
        }
    }
    return pop(&stack);
}
int main() {
    char infix[MAX_EXPRESSION_SIZE];
    char postfix[MAX_EXPRESSION_SIZE];
    printf("Enter an infix expression: ");
    fgets(infix, MAX_EXPRESSION_SIZE, stdin);
    infix[strlen(infix) - 1] = '\0';
    infixToPostfix(infix, postfix);
    printf("Postfix expression: %s\n", postfix);
    double result = evaluate(postfix);
    printf("Result: %g\n", result);
    return 0;
}