重温C语言(1)----计算算术表达式的值

本文介绍了一个使用C语言实现的逆波兰表达式计算器程序。该程序可以从命令行接收输入,并计算逆波兰表达式的值。文章提供了getfloat.c和expr.c两个源文件的详细代码及解析。

《C程序设计语言》练习题 5-10

编写程序 expr,计算从命令行输入的逆波兰表达式的值,其中每个运算符或操作数用一个单独的参数表示。例如,命令

expr 2 3 4 + *

计算表达式2x(3+4)的值

算法实现

getfloat.c:

// getfloat.c
#include<stdio.h>
#include<ctype.h>
int getfloat(char* str, double* store)
{
    while (isspace(*str))
        str++;
    int ch, sign;
    double power = 1.0;
    ch = *str++;
    sign = ch == '-' ? -1 : 1;
    if (ch == '+' || ch == '-') {
        ch == *str++;
    }
    for (*store == 0.0; isdigit(ch); ch = *str++) {
        *store = *store*10.0 + ch - '0';
    }
    if (ch == '.') {
        ch=*str++;
    }
    for (; isdigit(ch); ch = *str++) {
        *store = *store*10.0 + ch - '0';
        power *= 10.0;
    }
    if (ch == 0 || isspace(ch) || ch == EOF) {
        //如果不能继续读取数字,那么跳出的原因必须是 ch==0 || isspace(ch) || ch==EOF
        *store /= power;
        *store *= sign;
        return 1;
    }
    else {
        return -1;
    }
}

expr.c:

//expr.c
#include<stdio.h>
#include<ctype.h>
#define MAX_NUM 100
double stack[MAX_NUM];
extern int getfloat(char* str,double*);
int main(int argc, char* argv[])
{
    if (argc < 2) {
        printf("usage: expr num1 num2 operator ...\n");
        return 1;
    }
    else {
        int stackp = 0;
        int ch = 0;
        double num1, num2, ans;
        while (--argc >= 1) {
            ch = (*++argv)[0];
            if (ch == '-'){
                if (!isdigit(ch = (*argv)[1])) {
                    //是负号
                    if (stackp >= 2) {
                        num2 = stack[--stackp];
                        num1 = stack[--stackp];
                        stack[stackp++] = num1 - num2;
                        continue;
                    }
                    else {
                        printf("Error: at least two numbers are needed before operator '-'\n");
                        return -1;
                    }
                }
            }
            if (isdigit(ch)) {
                if (stackp < 0) {
                    printf("stack is underflowed!\n");
                    return -2;
                }
                else if (stackp >= MAX_NUM) {
                    printf("stack is overflowed!\n");
                    return -3;
                }
                else if (getfloat(*argv, &stack[stackp++]) == -1) {
                    printf("wrong argument to get number: %s\n", *argv);
                    return -4;
                }
            }
            else if (ch == '+'||ch=='*'||ch=='/'||ch=='%') {
                if (stackp >= 2) {
                    num2 = stack[--stackp];
                    num1 = stack[--stackp];
                    switch (ch) {
                    case '+':
                        ans = num1 + num2;
                        break;
                    case '*':
                        ans = num1*num2;
                        break;
                    case '/':
                        if (num2 == 0.0) {
                            printf("error zero divisor: %f / %f\n", num1, num2);
                            return -5;
                        }
                        ans = num1 / num2;
                        break;
                    case '%':
                        ans = (int)num1%(int)num2;
                        break;
                    }
                    stack[stackp++] = ans;
                }
                else {
                    printf("Error: at least two numbers are needed before operator '%c'\n",ch);
                    return -6;
                }
            }
            else {
                printf("wrong arguments for %c,usage: expr num1 num2 operator ...\n", ch);
                return -7;
            }
        }
        if (stackp == 1) {
            printf("%.4f\n", stack[0]);
        }
        else {
            printf("the format of input is wrong!\n");
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/dongling/p/5974191.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值