在后缀计算器中的第二个堆栈上拼图

时间:2019-04-27 10:20:38

标签: c algorithm

我最近正在阅读“ TCPL”。第4.3节中有一个经典案例“后缀计算器”。我对此案有疑问: 请参阅案例代码(从书中复制):

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

#define MAXOP 100
#define NUMBER '0'
#define MAXVAL 100 /* maxmium depth of val stack */
#define BUFFSIZE 100


int sp = 0;
double val[MAXVAL];

int bufp = 0; /* next free size in buf*/
char buf[BUFFSIZE]; /* buffer in ungetch */


int getch(void);
void ungetch(int);
int getop(char []);
void push(double);
double pop(void);

int main()
{
    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();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0) {
                    push(pop() / op2);
                }
                else
                {
                    printf("error: zero divisor. \n");
                }
                break;
            default:
                printf("\t%.8g\n", pop());
                break;
        }
    }
    return 0;
}


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


/* pop: pop and return value on the top of the stack */
double pop(void)
{
    if (sp > 0) {
        return val[--sp]; 
    }
    else {
        printf("error: stack empty.\n");
        return 0.0;
    }
}



/* getop: get next character or numeric operand */
int getop(char s[])
{
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t') {
        ;
    }
    s[1] = '\0';
    if (!isdigit(c) && c != '.' ) { /* operator */
        return c;
    }
    i = 0;
    if (isdigit(c)) {               /* collect integer part */
        while (isdigit(s[++i] = c = getch())) {
            ;
        }
    }
    if (c == '.') {                 /* collect fraction part */
        while (isdigit(s[++i] = c = getch())) {
            ;
        }
    }
    s[i] = '\0';
    if (c != EOF) {
        ungetch(c);
    }
    return NUMBER;
}


/* getch:  get a (possibly pushed-back) character */
int getch(void)
{
    return (bufp > 0)? buf[--bufp] : getchar();
}


/* ungetch: push character back on input */
void ungetch(int c)
{
    if (bufp >= BUFFSIZE) {
        printf("ungetch: too many characters in buufer.\n");
    }
    else {
        buf[bufp++] = c;
    }
}

有一个全局字符数组buf,就像一个堆栈,最后两个函数是在buf上“弹出”和“推入”。

我的问题是,buf堆栈在哪种情况下包含多个元素?

可以调用ungetch()的唯一机会是在函数getop()中,但是在getop()中,函数getch()至少被调用一次。

1 个答案:

答案 0 :(得分:0)

  

我的问题是在什么情况下堆栈buf包含多个元素?

从不, buf 只能是一个字符,它仅用于记住放在数字后的字符,以免丢失

可以将代码修改为不使用它:

/* getch:  get a (possibly pushed-back) character */
int getch(void)
{
    return getchar();
}


/* ungetch: push character back on input */
void ungetch(int c)
{
  ungetc(c, stdin);
}

编译和执行:

pi@raspberrypi:/tmp $ gcc pf.c
pi@raspberrypi:/tmp $ ./a.out
1 2 3 4 + + +
    10

或者使用这样的事实,只能保存一个字符:

int SavedChar = EOF;

/* getch:  get a (possibly pushed-back) character */
int getch(void)
{
  if (SavedChar == EOF)
    return getchar();

  int r = SavedChar;

  SavedChar = EOF;

  return r;
}

/* ungetch: push character back on input */
void ungetch(int c)
{
  SavedChar = c;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc pf.c
pi@raspberrypi:/tmp $ ./a.out
1 2 3 4 + + +
    10