C语言实现数学表达式运算

C语言实现数学表达式运算

概述

C语言提供了一系列函数库,可以实现数学表达式的运算。本篇攻略将介绍如何使用C语言实现数学表达式的运算的方法。

函数库

在C语言中实现数学表达式计算,可以使用数学函数库<math.h>和字符串处理函数库<string.h>

<math.h>函数库

该函数库中包括了常见的数学函数,例如四则运算、幂函数、三角函数等等。

<string.h>函数库

该函数库中包括了对字符串的处理函数,例如字符串的初始化、复制、连接等等。

思路

实现数学表达式计算,需要考虑以下的几个因素:

  • 表达式的输入和存储:使用字符数组存储输入的表达式。
  • 表达式的解析:将输入的字符串解析成数字和运算符,可以用数字栈和符号栈实现。
  • 表达式的计算:根据前缀、中缀或后缀表达式计算表达式的值。

示例

下面是使用C语言计算数学表达式的两个示例。

示例一:计算中缀表达式的值

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

#define MAX_EXPR_SIZE   100

typedef struct {
    int top;
    char data[MAX_EXPR_SIZE];
} Stack;

int is_empty(Stack* stack) {
    return (stack->top == -1);
}

int is_full(Stack* stack) {
    return (stack->top == MAX_EXPR_SIZE - 1);
}

char pop(Stack* stack) {
    if (is_empty(stack)) {
        printf("Stack is empty.\n");
        exit(1);
    } else {
        return stack->data[stack->top--];
    }
}

void push(Stack* stack, char c) {
    if (is_full(stack)) {
        printf("Stack is full.\n");
        exit(1);
    } else {
        stack->data[++(stack->top)] = c;
    }
}

char peek(Stack* stack) {
    if (is_empty(stack)) {
        printf("Stack is empty.\n");
        exit(1);
    } else {
        return stack->data[stack->top];
    }
}

int is_operator(char c) {
    return ((c == '+') || (c == '-') || (c == '*') || (c == '/') || (c == '^'));
}

int precedence(char op) {
    if ((op == '+') || (op == '-'))
        return 1;
    else if ((op == '*') || (op == '/'))
        return 2;
    else if (op == '^')
        return 3;
    else
        return 0;
}

double calculate(double opnd1, char optr, double opnd2) {
    switch (optr) {
        case '+': return opnd1 + opnd2;
        case '-': return opnd1 - opnd2;
        case '*': return opnd1 * opnd2;
        case '/': return opnd1 / opnd2;
        case '^': return pow(opnd1, opnd2);
        default : return 0.0;
    }
}

double evaluate(char* exp) {
    Stack opnd;  // 操作数栈
    Stack optr;  // 运算符栈

    opnd.top = -1;
    optr.top = -1;

    int i = 0;
    char c;

    while ((c = exp[i++]) != '\0') {
        if (isdigit(c)) {  // 如果是数字
            double d = atof(&c);
            while (isdigit(exp[i]) || (exp[i] == '.')) {
                strncat(&c, &exp[i++], 1);  // 将连续的数字字符拼接成浮点数
            }
            push(&opnd, d);
        } else if (is_operator(c)) {  // 如果是运算符
            while ((!is_empty(&optr)) && (precedence(c) <= precedence(peek(&optr)))) {
                double opnd2 = pop(&opnd);
                double opnd1 = pop(&opnd);
                push(&opnd, calculate(opnd1, pop(&optr), opnd2));
            }
            push(&optr, c);
        } else if (c == '(') {  // 如果是左括号
            push(&optr, c);
        } else if (c == ')') {  // 如果是右括号
            while (peek(&optr) != '(') {
                double opnd2 = pop(&opnd);
                double opnd1 = pop(&opnd);
                push(&opnd, calculate(opnd1, pop(&optr), opnd2));
            }
            pop(&optr);
        } else {  // 如果是空格或其他非法字符,忽略
            continue;
        }
    }

    while (!is_empty(&optr)) {
        double opnd2 = pop(&opnd);
        double opnd1 = pop(&opnd);
        push(&opnd, calculate(opnd1, pop(&optr), opnd2));
    }

    return pop(&opnd);
}

int main() {
    char expression[MAX_EXPR_SIZE];

    printf("Please enter an infix expression: ");
    fgets(expression, MAX_EXPR_SIZE, stdin);

    double result = evaluate(expression);

    printf("The result of the expression is: %lf\n", result);

    return 0;
}

示例二:计算后缀表达式的值

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

#define MAX_EXPR_SIZE   100

typedef struct {
    int top;
    double data[MAX_EXPR_SIZE];
} Stack;

int is_empty(Stack* stack) {
    return (stack->top == -1);
}

int is_full(Stack* stack) {
    return (stack->top == MAX_EXPR_SIZE - 1);
}

double pop(Stack* stack) {
    if (is_empty(stack)) {
        printf("Stack is empty.\n");
        exit(1);
    } else {
        return stack->data[stack->top--];
    }
}

void push(Stack* stack, double d) {
    if (is_full(stack)) {
        printf("Stack is full.\n");
        exit(1);
    } else {
        stack->data[++(stack->top)] = d;
    }
}

double evaluate(char* exp) {
    Stack stack;  // 操作数栈

    stack.top = -1;

    int i = 0;
    char c;

    while ((c = exp[i++]) != '\0') {
        if (isdigit(c)) {  // 如果是数字
            double d = atof(&c);
            while (isdigit(exp[i]) || (exp[i] == '.')) {
                strncat(&c, &exp[i++], 1);  // 将连续的数字字符拼接成浮点数
            }
            push(&stack, d);
        } else if (c == ' ') {  // 如果是空格,忽略
            continue;
        } else {  // 如果是运算符
            double opnd2 = pop(&stack);
            double opnd1 = pop(&stack);
            switch (c) {
                case '+': push(&stack, opnd1 + opnd2); break;
                case '-': push(&stack, opnd1 - opnd2); break;
                case '*': push(&stack, opnd1 * opnd2); break;
                case '/': push(&stack, opnd1 / opnd2); break;
                case '^': push(&stack, pow(opnd1, opnd2)); break;
                default : printf("Unknown operator: %c\n", c); exit(1);
            }
        }
    }

    return pop(&stack);
}

int main() {
    char expression[MAX_EXPR_SIZE];

    printf("Please enter a postfix expression: ");
    fgets(expression, MAX_EXPR_SIZE, stdin);

    double result = evaluate(expression);

    printf("The result of the expression is: %lf\n", result);

    return 0;
}

结论

以上就是使用C语言实现数学表达式的运算的完整攻略。涵盖了表达式的输入和存储、解析以及计算,同时提供了两个示例:中缀表达式和后缀表达式的计算。对于实现数学表达式的计算功能的使用者来说,只需根据自己的需求使用不同的表达式,就可以获得自己想要的计算结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现数学表达式运算 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 比特币原理是什么?比特币原理详解

    比特币原理是什么? 比特币(Bitcoin)是一种去中心化的数字货币,是基于点对点网络技术和密码学算法实现的。它的核心原领是区块链技术,是一种分布式账本技术,使得比特币能够实现去中心化、防篡改。 比特币采用共识机制来保证交易的安全和可靠性。它没有中心化的发行机构,每一笔交易都被记录到区块链上。同时,比特币的发行数量是有限的,最大发行量不超过2100万枚。 比…

    C 2023年5月22日
    00
  • c++实现LinkBlockedQueue的问题

    让我们来详细讲解“c++实现LinkBlockedQueue的问题”该如何解决。 首先,我们需要阅读题目并理解其中所涉及的术语。“LinkBlockedQueue”是一个队列类,其中“Link”指的是链表,“Blocked”指的是阻塞,即队列为空时,出队操作会一直阻塞等待直到队列中有元素可出队。 接下来,我们可以通过以下步骤实现LinkBlockedQueu…

    C 2023年5月23日
    00
  • C语言实现学生消费管理系统

    【C语言实现学生消费管理系统攻略】 一、需求分析 对于学生来说,管理自己的消费是很有必要的。因此我们需要实现一款学生消费管理系统,具备以下功能: 学生信息管理:包括姓名、学号、性别等信息。 消费信息管理:包括日期、消费品种(如食物、书籍等)、消费金额等信息。 消费查询功能:能够查询某一段时间内的消费情况。 统计分析功能:能够统计学生的消费情况,如消费总额、平…

    C 2023年5月23日
    00
  • Qt实现UDP多线程数据处理及发送的简单实例

    下面我详细讲解一下“Qt实现UDP多线程数据处理及发送的简单实例”的完整攻略。 1. 确定需求 首先需要明确我们的需求,这里我们需要实现一个UDP多线程的数据处理及发送的示例程序,用于实现UDP数据包的接收、处理和发送功能。 2. 环境搭建 接着,我们需要搭建Qt的开发环境,即安装Qt Creator和Qt库。这里我们使用Qt Creator 4.14.0和…

    C 2023年5月22日
    00
  • 详解如何利用C++实现一个反射类

    实现一个反射类需要在设计编译时对代码进行注入,故需要使用C++的元编程能力。下面是具体步骤: 1. 定义一个工厂类 反射需要一个通用的工厂类来创建所需类的实例。这个工厂类需要能够被任何需要使用反射类的代码访问。下面是一个通用工程类的示例。 template<typename Base, typename… Args> struct Facto…

    C 2023年5月23日
    00
  • C语言实现简单学生管理系统

    C语言实现简单学生管理系统攻略 1. 确定需求 在C语言实现简单学生管理系统之前,我们首先需要明确该系统的需求,例如: 能够添加学生信息 能够删除学生信息 能够修改学生信息 能够查询学生信息 能够显示所有学生信息 2. 设计数据库 在明确了系统的需求后,我们需要设计一个合适的数据库来存储学生信息。在我们的例子中,我们可以使用一个结构体来存储学生信息: typ…

    C 2023年5月23日
    00
  • C语言切割多层字符串(strtok_r strtok使用方法)

    下面就给大家讲解一下C语言中切割多层字符串的使用方法。常用的函数有strtok_r()和strtok()。 strtok_r()使用方法 该方法是线程安全的字符串分割函数。需要注意的是,strtok_r()除了是线程安全的之外,用法和一个另一个非线程安全的函数strtok()是类似的。 strtok_r()函数的基本用法 strtok_r()函数的语法如下:…

    C 2023年5月24日
    00
  • 浅析VSCode launch.json中的各种替换变量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等

    对于”浅析VSCode launch.json中的各种替换变量的意思”这个话题,以下是我准备好的完整攻略。 1. 简介 在 VSCode 调试过程中,通常需要配置一个 .vscode/launch.json 文件。这个配置文件中包括了很多参数,其中一些参数需要填写变量,这些变量通常用于在不同情况下动态生成参数值。这些变量被称为“替换变量”,是一种非常方便的技…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部