逆ポーランド式を計算するプログラム

K&R本 演習5-10

コマンド行からの逆ポーランド式を計算するプログラムexprを書け。各演算子あるいは被演算数は引数として分離されているものとする。例えば

expr 2 3 4 + *

なら2×(3+4)を計算するようにせよ。

これはかなりプログラムらしい演習ですね。やってみます。

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

typedef struct {
    int data[100];
    int index;
} STACK;

int push (STACK *s,int data) {
    if ( s->index >= 100 ) {
        return 0;
    }
    s->data[s->index++] = data;
    return 1;
}

const int *pop (STACK *s) {
    if ( !s->index ) {
        return NULL;
    }
    return &s->data[--s->index];
}

int main (int argc,char *argv[]) {
    STACK s = {0};
    const int *n,*m;
    
    argc--;
    for(argv++;*argv;argv++){
        
        if ( isdigit(**argv) ) {
            push(&s,atoi(*argv));
        }
        else if ( strlen(*argv) == 1 ) {
            m = pop(&s);
            if ( m == NULL ) {
                puts("stack not found error");
                return 1;
            }
            n = pop(&s);
            if ( n == NULL ) {
                puts("stack not found error");
                return 1;
            }
            switch(**argv){
                case '+':
                    push(&s,*n + *m);
                    break;
                case '-':
                    push(&s,*n + *m);
                    break;
                case '*':
                    push(&s,*n * *m);
                    break;
                case '/':
                    if ( *m == 0 ) {
                        puts("0除算エラー");
                        return 1;
                    }
                    push(&s,*n / *m);
                    break;
                case '%':
                    if ( *m == 0 ) {
                        puts("0除算エラー");
                        return 1;
                    }
                    push(&s,*n % *m);
                    break;
                default :
                    puts("存在しない演算子");
                    return 1;
            }
        }
        else {
            puts("存在しない演算子");
            return 1;
        }
    }
    
    printf("result = %d\n",*pop(&s));
    return 0;
}
$ main 2 3 4 + *
result = 14

ばっちりできました。

今回はキッチリエラー周りも厳密にやってみました。

存在しない演算子や0除算エラー。またスタックが存在しないエラー等、割とうまくいっている模様です。