演習5-10 K&R プログラミング言語C

演習5-10

4.3 外部変数 K&R プログラミング言語C の逆ポーランド計算機をコマンド引数の文字列を利用するように修正する。
積算の記号 * は、コマンド引数ではシェルに展開されてしまうので x を利用する。

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

#define NUMBER '0'
#define MAXVAL 100

int getop(char*);
void push(double);
double pop(void);
int sp = 0;
double val[MAXVAL];

int main(int argc, char *argv[])
{
    int type;
    double op2;

    while (--argc > 0) {
        switch (type = getop(*++argv)) {
        case NUMBER:
            push(atof(*argv));
            break;
        case '+':
            push(pop() + pop());
            break;
        case '-':
            op2 = pop();
            push(pop() - op2);
            break;
        case 'x':
            push(pop() * pop());
            break;
        case '/':
            op2 = pop();
            if (op2 != 0.0) {
                push(pop() / op2);
            } else {
                fprintf(stderr, "error : zero divisor\n");
            }
            break;
        default:
            fprintf(stderr, "error : unknown command %c\n", type);
            break;
        }
    }
    printf("\t%.8g\n", pop());

    return 0;
}

int getop(char *s)
{
    char c;
    if (isdigit(c = s[0])) {
        return NUMBER;
    } else if (c == '-' && isdigit(s[1])) {
        return NUMBER;
    } else {
        return c;
    }
}

void push(double f)
{
    if (sp < MAXVAL) {
        val[sp++] = f;
    } else {
        fprintf(stderr, "error : stack full, can't push %g\n", f);
    }
}

double pop(void)
{
    if (sp > 0) {
        return val[--sp];
    } else {
        fprintf(stderr, "error : stack empty\n");
        return 0.0;
    }
}

実行結果

$ ./expr 2 3 4 + x
        14
プログラミング言語C 第2版 ANSI規格準拠
B.W. カーニハン D.M. リッチー
共立出版
売り上げランキング: 9726
«
»