鱼C论坛

 找回密码
 立即注册
查看: 4328|回复: 24

[已解决]关于s1e40动动手代码中ungetch的疑问

[复制链接]
发表于 2021-8-6 17:52:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 JingHe1997 于 2021-8-6 18:15 编辑

看过答案以后依旧不太理解void ungetch(int)的作用,为什么没有 ungetch 函数,当遇到像 1 2 3-4++ 这种操作符之间不留空的式子就会出现计算错误。
附上源码(ungetch部分已标红):

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

#define MAXVAL  100     // 栈val的最大深度

void push(double);      // 将f压入到值栈中
double pop(void);       // 弹出并返回栈顶的值
int getch(void);        // 从输入缓冲区取出一个字符
void ungetch(int)   // 将字符送回缓冲区中
int getop(char s[]);   

int sp = 0;             // 栈指针,指向下一个空闲位置
double val[MAXVAL];     // 值栈

void push(double f)
{
        if (sp < MAXVAL)
                val[sp++] = f;
        else
                printf("错误:栈已满!\n", f);
}

double pop(void)
{
        if (sp > 0)
                return val[--sp];
        else
        {
                printf("错误:栈已空!\n");
                return 0.0;
        }
}

#define BUFSIZE 100     // 缓冲区的最大尺寸
#define NUMBER  '0'

char buf[BUFSIZE];      // 缓冲区
int bufp = 0;           // 缓冲区指针,指向下一个空闲位置

int getch(void)
{
        // 从从标准输入流中获取一个字符
        // 如果buf缓冲区中有存在字符,先从buf中获取
        return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
        if (bufp >= BUFSIZE)
                printf("错误:缓冲区已满!\n");
        else
                buf[bufp++] = c;
}


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 MAXOP   100

int main(void)
{
        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;
                        case '\n':
                                printf("\t%.8g\n", pop());
                                break;
                        default:
                                printf("error: unknown comand %s\n", s);
                                break;
                }
        }

        return 0;
}

有朋友能够帮忙解释一下吗,谢谢
最佳答案
2021-8-6 20:05:43
JingHe1997 发表于 2021-8-6 19:23
不好意思,我不太了解图片这部分的内容。
    while (isdigit(s[++i] = c = getch()))

循环终止时 :
  getchar取了一个不是非数字字符(如操作符)
  但其实是有用的,你得退回缓冲区留下一次使用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-6 18:53:50 | 显示全部楼层

回帖奖励 +5 鱼币

为什么没有 ungetch 函数,当遇到像 1 2 3-4++ 这种操作符之间不留空的式子就会出现计算错误。
这句话什么意思?? 到底留没留空
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-6 19:23:53 | 显示全部楼层
本帖最后由 JingHe1997 于 2021-8-6 19:28 编辑
万千只cnm 发表于 2021-8-6 18:53
为什么没有 ungetch 函数,当遇到像 1 2 3-4++ 这种操作符之间不留空的式子就会出现计算错误。
这句话什么 ...


不好意思,我不太了解图片这部分的内容。
WechatIMG289.jpeg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-6 20:05:43 | 显示全部楼层    本楼为最佳答案   
JingHe1997 发表于 2021-8-6 19:23
不好意思,我不太了解图片这部分的内容。
    while (isdigit(s[++i] = c = getch()))

循环终止时 :
  getchar取了一个不是非数字字符(如操作符)
  但其实是有用的,你得退回缓冲区留下一次使用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-6 21:16:28 | 显示全部楼层
万千只cnm 发表于 2021-8-6 20:05
循环终止时 :
  getchar取了一个不是非数字字符(如操作符)
  但其实是有用的,你得退回缓冲区留 ...

噢!我懂意思了,谢谢你
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-7 10:01:54 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 10:04:02 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 10:40:04 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 10:40:36 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 11:03:42 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 16:57:05 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-7 17:19:34 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-8 18:58:35 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-10 16:54:42 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-10 16:55:37 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-10 20:32:07 | 显示全部楼层

回帖奖励 +5 鱼币

学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-10 21:35:17 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 09:05:53 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 17:28:56 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 19:18:17 | 显示全部楼层

回帖奖励 +5 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 03:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表