《C编程语言》第2版第4.3节中的RPN,未将数字压入堆栈

3df52oht  于 2023-02-03  发布在  其他
关注(0)|答案(1)|浏览(68)

我一直在阅读C编程语言书,在4. 3节中,我试图编译和运行第76-79页中提供的代码。我想我已经完全按照教科书中的要求做了,但它没有按照它应该的方式工作。
从一些printf中,我发现输入的数字实际上并没有被推到val[sp]的堆栈中。相反,当打印出数字时,它显示了0
此外,空格不会被跳过

while((s[0] = c = getch()) == ' ' || c == '\t'{
    ;
}

所以getop()把它们当作非数字,只返回空格,因此在读取空格时输出只打印error unknown command
另外,“+”没有被作为命令读取!所以当程序遇到它时,它只返回error unknown command。我不知道这是如何发生的,因为我逐字复制了教科书上的代码并运行了它。我不确定这段代码是否过时,是否也不能在较新的机器上运行。如果有帮助的话,我也使用CodeBlocks来运行这段代码。
任何帮助是非常感谢!
这是我的密码

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

#define MAXOP 100
#define NUMBER '0'

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



int main()
{
    //extern double val[MAXVAL];
    int type;
    double op2;
    char s[MAXOP];

    while((type = getop(s)) != EOF){
        switch(type){
        case NUMBER:
            puts("a 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 division");
            }
            break;

        case '\n':
            printf("\t%.8g\n", pop());
            break;
        default:
            printf("error unknown command %s\n", s);
            break;

        }
    }
    printf("Hello world!\n");
    return 0;
}

#define MAXVAL 100
int sp = 0;
double val[MAXVAL];

void push(double f)
{
    //extern int sp;
    //extern double val[MAXVAL];

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

double pop(void)
{
    //extern int sp;
    //extern double val[MAXVAL];

    if(sp > 0){
        return val[--sp];
    }
    else{
        printf("stack is empty\n");
        return 0.0;
    }
}

int getch(void);
void ungetch(int c);

int getop(char s[])
{
    int i, c;

    while((s[0] = c = getch()) == ' ' || c == '\t'){
        ;
    }

    s[1] = '\0';
    if(!isdigit(c) && c != '.'){
        printf("%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];
int bufp = 0;

int getch(void)
{
    //extern int bufp;
    //extern char buf[BUFSIZE];

    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
    //extern int bufp;
    //extern char buf[BUFSIZE];

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

以及3 4 +1的输出
我试着打印出每一部分(当它被推的时候的数字),也打印出“+”,看看它是否真的被返回为“+”。是的,我不知道这是怎么发生的。

yzuktlbb

yzuktlbb1#

一个问题是您的代码具有:

void ungetch(int c)
{
    //extern int bufp;
    //extern char buf[BUFSIZE];

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

这本书(p79)有:

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

++bufpbufp++之间的差异至关重要。
这不是唯一的问题,但当这个问题得到解决时,事情就更接近于工作了。

  • 您总是将++x重写为x++,将x++重写为++x,这些表达式是不可互换的,因此确保这些表达式的正确性非常非常重要。
  • 正如Oka所指出的,在getop()函数中,您有(两次):
while(isdigit(s[i++] = c = getch())){
    ;
}

其中该书具有:

while (isdigit(s[++i] = c = getch()))
    ;
  • push()函数中,您有:
val[++sp] = f;

其中该书具有:

val[sp++] = f;

至关重要的是:
1.您可以准确地复制代码。
1.您了解++xx++之间的区别。
有了这些额外的修正--意味着修改代码以匹配书中的内容--代码似乎可以工作,至少在输入3 4 +上是这样。

相关问题