4.3 外部変数, 演習4-3 K&R プログラミング言語C
2010年01月08日
4.3 外部変数
演習4-10まで以下の電卓プログラムを修正していく。
#include <stdio.h> #include <stdlib.h> /* atof() 用 */ #define MAXOP 100 /* 被演算子数、演算子の最大サイズ */ #define NUMBER '0' /* 数字があったという記号 */ int getop(char []); void push(double); double pop(void); /* 逆ポーランド電卓プログラム */ int main(int argc, char *argv[]) { int type; double op2; char s[MAXOP]; while ((type = getop(s)) != EOF) { switch (type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': op2 = pop(); /* pop() を2回呼ぶ場合の評価順序は定義されていないので、最初の pop() の値を一時変数に保存する。 */ push(pop() - op2); break; case '/': op2 = pop(); /* pop() を2回呼ぶ場合の評価順序は定義されていないので、最初の pop() の値を一時変数に保存する。 */ if (op2 != 0.0) { push(pop() / op2); } else { printf("error: zero divisor\n"); } break; case '\n': printf("\t%.8g\n", pop()); break; default: printf("error: unknown command %s\n", s); break; } } return 0; } #define MAXVAL 100 /* val スタックの最大の深さ */ int sp = 0; /* スタック・ポインタ */ double val[MAXVAL]; /* 値のスタック */ /* push: f を値スタックにプッシュする */ void push(double f) { if (sp < MAXVAL) { val[sp++] = f; } else { printf("error: stack full, can't push %g\n", f); } } /* pop: スタックから一番上の値をポップして返す */ double pop(void) { if (sp > 0) { return val[--sp]; } else { printf("error: stack empty\n"); return 0.0; } } #include <ctype.h> int getch(void); void ungetch(int); /* getop: 次の演算子あるいは数値の被演算数をとってくる */ int getop(char s[]) { int i, c; while ((s[0] = c = getch()) == ' ' || c == '\t') ; s[1] = '\0'; if (!isdigit(c) && c != '.') { return c; /* 数ではない */ } i = 0; if (isdigit(c)) { /* 整数部を集める */ while (isdigit(s[++i] = c = getch())) ; } if (c == '.') { /* 小数部を集める */ while (isdigit(s[++i] = c = getch())) ; } s[i] = '\0'; if (c != EOF) { ungetch(c); } return NUMBER; } #define BUFSIZE 100 char buf[BUFSIZE]; /* ungetch 用のバッファ */ int bufp = 0; /* buf 中の次の空き位置 */ int getch(void) /* (押し戻された可能性もある)1文字をとってくる */ { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if (bufp >= BUFSIZE) { printf("ungetch: too many characters\n"); } else { buf[bufp++] = c; } }
演習4-3
モジュロ (%
) の追加。
main
関数の switch
に以下のケースを追加する。
/* 省略 */ case '%': op2 = pop(); if (op2 != 0.0) { push((int) pop() % (int) op2); } else { printf("error: zero divisor\n"); } break; /* 省略 */
単項の -
演算子の追加。
getop
関数に -
の場合を追加する。
/* 省略 */ if (!isdigit(c) && c != '.' && c != '-') { /* 省略 */ if (c == '-') { if (!isdigit(s[++i] = c = getch())) { /* 次の文字が数字でない場合 */ ungetch(c); /* 1文字押し戻す */ return '-'; } } /* 省略 */
実行結果
$ ./calc 5 3 % 2 -4 3 * -12
プログラミング言語C 第2版 ANSI規格準拠
posted with amazlet at 09.11.27
B.W. カーニハン D.M. リッチー
共立出版
売り上げランキング: 9726
共立出版
売り上げランキング: 9726