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

yizhihongxing

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日

相关文章

  • 深入解析C语言中的内存分配相关问题

    深入解析C语言中的内存分配相关问题 概述 在C语言中,内存分配是至关重要的。这是因为在C语言中,程序员需要手动地分配和释放内存以存储数据。C语言提供了几种内存分配方式,包括数据段、栈和堆。使用不当的内存分配方法可能导致程序运行时出现各种严重的问题,例如内存泄漏和段错误。本攻略将重点介绍C语言中的内存分配方式,并提供一些示例以帮助您更好地理解内存分配的概念。 …

    C 2023年5月23日
    00
  • C++函数指针+对象指针+this指针+指向类静态和非静态成员的指针

    C++函数指针、对象指针、this指针以及指向类静态和非静态成员的指针是C++语言中常用的指针类型。这些指针类型的使用可以让我们更加灵活地实现一些复杂的功能和设计模式。下面我们会逐一讲解它们的使用。 函数指针 函数指针是指向函数的指针类型。函数指针可以用于实现回调函数、函数指针数组等功能。函数指针的通用形式为:返回值类型(*函数指针变量名)(参数列表)。 例…

    C 2023年5月22日
    00
  • C语言 文件I/O

    下面是C语言文件I/O的完整使用攻略。 什么是文件I/O 文件I/O是指文件的输入/输出操作。C语言中,文件的读写操作主要通过<stdio.h>头文件中提供的函数实现。 文件的读写操作 打开文件 在进行文件读写前,首先需要打开文件: FILE *fopen(const char *filename, const char *mode); 其中,f…

    C 2023年5月9日
    00
  • C语言实现Floyd算法

    C语言实现Floyd算法 什么是Floyd算法 Floyd算法是一种用于寻找给定的加权图中多源点之间最短路径的算法,也称为Floyd-Warshall算法。 其时间复杂度为O(N^3),适用于需要求解所有顶点对间最短路径的场景。 算法思路 Floyd算法的思路是利用动态规划的思想,通过逐步考虑添加中间顶点的方式来逐步求得顶点对间的最短路径。 也就是说,我们首…

    C 2023年5月22日
    00
  • Win10预览版19042升级后浏览器网页异常内容显示不全怎么办?

    对于Win10预览版19042升级后浏览器网页异常内容显示不全的情况,可能是因为升级过程中出现了一些问题导致系统出现了一些错误,或者是因为浏览器插件以及设置的问题所导致的。以下是处理该问题的完整攻略。 步骤一:更新浏览器插件 第一步需要检查浏览器是否有最新版本的插件可用,如果有,则需要更新插件以解决可能出现的兼容性问题。比如,用户在使用谷歌浏览器时,可以按照…

    C 2023年5月23日
    00
  • win10系统出现0x000000c5蓝屏的修复方法

    Win10系统出现0x000000c5蓝屏的修复方法 前言 在Windows10系统运行过程中,可能会碰到各种各样的蓝屏错误。其中,0x000000c5蓝屏错误是较为常见的一种,表示驱动程序试图访问非法内存地址。这可能是因为驱动程序不能正确处理该内存地址,或者因为某些未知原因导致内存地址错误。本文将详细介绍修复0x000000c5蓝屏错误的步骤。 步骤 步骤…

    C 2023年5月24日
    00
  • C语言实现文件读写

    文件读写是C语言的一个重要部分,文件读写操作主要是通过函数库提供的各种操作文件的函数来实现的。在实现文件读写时,主要分为以下几个步骤: 打开文件 C语言提供了fopen函数来打开文件,并返回一个指向文件的指针,该函数原型如下: FILE *fopen(const char *filename, const char *mode); 其中,filename表示…

    C 2023年5月23日
    00
  • C 文件读写

    下面是关于C文件读写的完整使用攻略。 一. 文件读写概述 文件读写是指对硬盘中的文件进行读取或写入的操作,主要使用文件指针、文件流、文件模式、文件大小、文件类型等概念和函数来实现。在C语言中,文件读写操作主要通过 头文件和相关的函数来实现。 二. 文件读写的基本操作 文件读写需要先打开文件,然后读写文件,最后关闭文件,这是基本的文件读写流程。 2.1 打开文…

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