2013年8月15日木曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.10(コマンド行の引数)、演習5-10を解いてみる。

その他参考書籍

演習 5-10.

コード

sample.c

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

#define MAXOP 100
#define NUMBER '0'
#define NAME 'n'

void ungets(char []);
int getop(char []);
void push(double);
double pop(void);
void math_f(char []);

int main(int argc, char *argv[])
{
    int type, i, var_name;
    double op1, op2, variable[26];
    char s[MAXOP];
    
    for ( i = 0; i < 26; i++) {
        variable[i] = 0.0;
    }
    while (--argc > 0) {
        ungets(" ");
        ungets(*++argv);
        switch (type = getop(s)) {
            case NUMBER:
                push(atof(s));
                break;
            case NAME:
                math_f(s);
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pop());
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0) {
                    push(pop() / op2);
                } else {
                    printf("error: zero divisor\n");
                }
                break;
            case '%':
                op2 = pop();
                if (op2 != 0.0) {
                    push(fmod(pop(), op2));
                } else {
                    printf("error: zero %%\n");
                }
                break;
            /* スタックの一番上の要素を印刷 */
            case 't':
                op2 = pop();
                printf("\t%.8g\n", op2);
                push(op2);
                break;
            /* スタックの一番上の要素を複製 */
            case 'd':
                op2 = pop();
                push(op2);
                push(op2);
                break;
            /* スタックの上の二つの要素を交換 */
            case 's':
                op2 = pop();
                op1 = pop();
                push(op2);
                push(op1);
                break;
            case '=':
                pop();
                if ('A' <= var_name && var_name <= 'Z') {
                    variable[var_name - 'A'] = pop();
                } else {
                    printf("error: name %c\n", var_name);
                }
                break;
            default:
                if ('A' <= type && type <= 'Z') {
                    push(variable[type - 'A']);
                } else {
                    printf("error: unknown command %s\n", s);
                }
                break;
        }
        var_name = type;
    }
    printf("\t%.8g\n", pop());
    return 0;
}

#define MAXVAL 100

int sp = 0;
double val[MAXVAL];

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

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

#include <ctype.h>

int getch(void);

int getop(char s[])
{
    int i, c;
    static int last_c = 0;
    
    if (last_c == 0) {
        c = getch();
    } else {
        c = last_c;
        last_c = 0;
    }
    while ((s[0] = c) == ' '|| c == '\t')
        c = getch();
    s[1] = '\0';
    i = 0;
    if (islower(c)) {
        while (islower(s[++i] = c= getch()))
            ;
        s[i] = '\0';
        if (c != EOF) {
            last_c = c;
        }
        if (i > 1) {
            return NAME;
        }
        return s[0];
    }
    if (!isdigit(c) && c != '.' && c != '-') {
        return c;
    }
    if (c == '-') {
        if (isdigit(c = getch()) || c == '.') {
            s[++i] = c;
        } else {
            if (c != EOF) {
                last_c = c;
            }
            return '-';
        }
    }
    if (isdigit(c)) {
        while (isdigit(s[++i] = c = getch()))
            ;
    }
    if (c == '.') {
        while (isdigit(s[++i] = c = getch()))
            ;
    }
    s[i] = '\0';
    if (c != EOF) {
        last_c = c;
    }
    return NUMBER;
}

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0;

int getch(void)
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
    if (bufp >= BUFSIZE) {
        printf("ungetch: too many characters\n");
    } else {
        buf[bufp++] = c;
    }
}

#include <string.h>

void ungets(char s[])
{
    int len;
    void ungetch(int);
    
    len = strlen(s);
    while (len > 0) {
        ungetch(s[--len]);
    }
}

#include <string.h>

void math_f(char s[])
{
    double op2;
    if (strcmp(s, "sin") == 0) {
        push(sin(pop()));
    } else if (strcmp(s, "exp") == 0) {
        push(exp(pop()));
    } else if (strcmp(s, "pow") == 0) {
        op2 = pop();
        push(pow(pop(), op2));
    } else {
        printf("error: unknown func %s\n", s);
    }
}

入出力結果(Terminal)

$ ./a.out 2 3 4 + '*'
 14
$ ./a.out 1 2 - 4 5 + '*'
 -9
$

0 コメント:

コメントを投稿