C和指针第二章--表达式计算器的C语言实现

本文介绍了一种使用栈将中缀表达式转换为后缀表达式并计算其结果的方法。通过定义两个栈分别存储运算符和数字,利用优先级规则实现逐项解析与计算,最终得出表达式的计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二章的题目没有太多可以记的,其中第二题让验证所有花括号都正确成对出现让我想起“表达式计算器”,现实现如下:

#include <stdio.h>

//存储操作符 
struct OpeStack
{
    int iTop;
    char acStack[100];
};

//存储数字 
struct NumStack
{
    int iTop;
    int aiStack[100];
};

//是数字 
static int isNumber(char ch)
{
    return (ch <= '9' && ch >= '0') ? ch - '0' : -1;
}

//是运算符
static int isOperator(char ch)
{
    return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' );
}

//返回运算符优先级 
static int OpePriority(char ch)
{
    switch(ch)
    {
        case '+':
        case '-':
        {
            return 1;   
        }
        case '*':
        case '/':
        {
            return 2;
        }
        case '(':
        {
            return 3;
        }
        default:
            return -1;
    }
}

//根据输入运算符和数做运算,a是运算符左边的数,b是运算符右边的数 
static int CalPart(int a, char Operator, int b)
{
    switch(Operator)
    {
        case '+':
        {
            return a + b; 
        }
        case '-':
        {
            return a - b;   
        }
        case '*':
        {
            return a * b; 
        }
        case '/':
        {
            return a / b; 
        }
        default:
            return ~0;
    }
}

//对输入表达式进行计算,并将结果保存在iResult中 
static int Calculate(const char *acExpression, int *iResult)
{
    int i;
    int tmpNum;
    int iNum;
    //两个栈一个用来放运算符,一个用来放数字
    struct OpeStack tOperator;
    struct NumStack tNumber;

    tOperator.iTop = 0;
    tNumber.iTop   = 0;

    for(i = 0; acExpression[i] != '\0'; i++)
    {
        iNum = 0;

        //如果是数字的话处理数字 
        if(isNumber(acExpression[i]) != -1)
        {
            int j = i; 
            while((tmpNum = isNumber(acExpression[j])) != -1)
            {
                iNum = iNum *10 + tmpNum;
                j++;
            }
            tNumber.aiStack[++tNumber.iTop] = iNum;
        }
        //如果是运算符的话 
        else if(isOperator(acExpression[i]) == 1) 
        {
            //如果遇到右括号就计算直到左括号为止 
            if(acExpression[i] == ')')
            {
                while(tOperator.acStack[tOperator.iTop] != '(')
                {
                    if(tOperator.iTop < 1)
                    {
                        printf("bracket is not match\n");
                        return -1;
                    }
                    int a = tNumber.aiStack[tNumber.iTop--];
                    int b = tNumber.aiStack[tNumber.iTop--];
                    int iResult = CalPart(b, tOperator.acStack[tOperator.iTop--], a);
                    tNumber.aiStack[++tNumber.iTop] = iResult;
                }
                tOperator.iTop--;
            }

            //如果是第一个符号或者是括号后的第一符号,直接入栈 
            else if(tOperator.iTop == 0 || tOperator.acStack[tOperator.iTop] == '(')
            {
                tOperator.acStack[++tOperator.iTop] = acExpression[i];
            }
            else
            {           
                //如果当前优先级低或相等,就先计算栈顶的符号             
                //如果优先级高就入栈
                if(OpePriority(acExpression[i]) <= OpePriority(tOperator.acStack[tOperator.iTop]))
                {
                    int a = tNumber.aiStack[tNumber.iTop--];
                    int b = tNumber.aiStack[tNumber.iTop--];
                    char cOpr =  tOperator.acStack[tOperator.iTop--];
                    int iResult = CalPart(b, cOpr, a);
                    tNumber.aiStack[++tNumber.iTop] = iResult;
                    tOperator.acStack[++tOperator.iTop] = acExpression[i];
                } 
                else
                {
                    tOperator.acStack[++tOperator.iTop] = acExpression[i];
                } 
            }
        }
        else
        {
            return -1;
        }

    }

    //表达式读完后开始计算 
    while(tOperator.iTop >= 1)
    {
        int a = tNumber.aiStack[tNumber.iTop--];
        int b = tNumber.aiStack[tNumber.iTop--];
        int iResult = CalPart(b, tOperator.acStack[tOperator.iTop--], a);
        tNumber.aiStack[++tNumber.iTop] = iResult;
    }

    //如果数字栈中最后只剩一个元素,说明计算正确;否则计算错误 
    if(tNumber.iTop == 1)
    {
        *iResult = tNumber.aiStack[1];
    }
    else
    {
        return -2;
    }

    return 0;
}

int main(void)
{
    char acExprestion[100] = "2*4/(1+3)+4";
    int iRes;

    int ret = Calculate(acExprestion, &iRes);
    if(!ret)
        printf("result:%d\n", iRes);    

    return 0;
}

总体思路是用栈来将中缀表达式转换为后缀表达式,注释的还是很清楚的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值