You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《C程序设计语言》第2版4.3节RPN代码异常:数字未入栈等问题

逆波兰表达式(RPN)代码问题排查与修复

核心问题拆解与修复方案

1. 数字压栈后显示为0

  • 检查push()函数的栈指针操作:必须是先赋值再自增栈指针,即val[sp++] = f;,如果写成val[++sp] = f;会写入错误的栈位置,导致读取到未初始化的0值。
  • 验证getop()的数字转换逻辑:确认读取到数字字符后,正确通过atof()(或手动转换)得到浮点数,且将转换结果完整传递给push()。
  • 确认栈初始化:sp初始值必须为0,val数组的大小要足够(书中定义为MAXVAL 100),避免数组越界导致数值被覆盖。

2. 空格未被跳过,触发未知命令错误

  • 重点检查getop()的空白字符跳过逻辑:书中的getop()开头会跳过所有空格、制表符,代码必须包含这段逻辑:
    int c;
    while ((c = getch()) == ' ' || c == '\t')
        ;
    
    如果这段代码缺失或条件写错(比如误判为换行符),空格会被当作有效字符返回,触发未知命令。
  • 检查getch()和ungetch()的实现:如果用了自定义字符缓冲,要确保缓冲逻辑正确,不会丢失或重复读取字符,影响空白跳过流程。

3. 运算符'+'被识别为未知命令

  • 核对getop()的返回值分支:读取到运算符时应直接返回该字符,确保这段逻辑正确:
    if (!isdigit(c) && c != '.' && c != '-')
        return c; // 返回运算符或未知字符
    
    若条件判断错误,会把运算符误判为非有效字符。
  • 检查主函数的命令处理分支:必须存在'+'对应的case分支,示例:
    case '+':
        push(pop() + pop());
        break;
    
    遗漏该分支会走到默认的错误处理逻辑。

关键代码片段验证

书中getop()的核心逻辑参考(确保空白跳过、数字收集、运算符返回逻辑正确):

#include <ctype.h>
#define NUMBER '0'  // 自定义常量,标记返回的是数字

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

    while ((s[0] = c = getch()) == ' ' || c == '\t')
        ;
    s[1] = '\0';
    if (!isdigit(c) && 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;
}

push()和pop()的标准实现:

#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;
    }
}

内容的提问来源于stack exchange,提问作者theperson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:50:28