JingHe1997 发表于 2021-8-6 17:52:37

关于s1e40动动手代码中ungetch的疑问

本帖最后由 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 MAXVAL100   // 栈val的最大深度

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

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

void push(double f)
{
      if (sp < MAXVAL)
                val = 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;      // 缓冲区
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 = c;
}

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

      while ((s = c = getch()) == ' ' || c == '\t')
                ;
      s = '\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 = '\0';

   if (c != EOF)
                ungetch(c);

      return NUMBER;
}

#define MAXOP   100

int main(void)
{
      int type;
      double op2;
      char s;

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

有朋友能够帮忙解释一下吗,谢谢{:5_107:}

万千只cnm 发表于 2021-8-6 18:53:50

为什么没有 ungetch 函数,当遇到像 1 2 3-4++ 这种操作符之间不留空的式子就会出现计算错误。
这句话什么意思?? 到底留没留空

JingHe1997 发表于 2021-8-6 19:23:53

本帖最后由 JingHe1997 于 2021-8-6 19:28 编辑

万千只cnm 发表于 2021-8-6 18:53
为什么没有 ungetch 函数,当遇到像 1 2 3-4++ 这种操作符之间不留空的式子就会出现计算错误。
这句话什么 ...

不好意思,我不太了解图片这部分的内容。

万千只cnm 发表于 2021-8-6 20:05:43

JingHe1997 发表于 2021-8-6 19:23
不好意思,我不太了解图片这部分的内容。

    while (isdigit(s[++i] = c = getch()))

循环终止时 :
getchar取了一个不是非数字字符(如操作符)
但其实是有用的,你得退回缓冲区留下一次使用

JingHe1997 发表于 2021-8-6 21:16:28

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

噢!我懂意思了,谢谢你{:5_110:}

懒狗李 发表于 2021-8-7 10:01:54

{:10_254:}

一条|咸鱼 发表于 2021-8-7 10:04:02

{:10_254:}

Kayko 发表于 2021-8-7 10:40:04

{:10_254:}

Kayko 发表于 2021-8-7 10:40:36

{:10_266:}

hornwong 发表于 2021-8-7 11:03:42

{:5_95:}

burntlime 发表于 2021-8-7 16:57:05

{:10_254:}

chenmingfan 发表于 2021-8-7 17:19:34

{:5_97:}

懒狗李 发表于 2021-8-8 18:58:35

{:10_254:}

burntlime 发表于 2021-8-10 16:54:42

学习

burntlime 发表于 2021-8-10 16:55:37

{:10_256:}

超级玛尼哄 发表于 2021-8-10 20:32:07

学习学习

DOGDOG59 发表于 2021-8-10 21:35:17

{:5_96:}

Kayko 发表于 2021-8-11 09:05:53

{:10_257:}

TramBradr 发表于 2021-8-11 17:28:56

{:10_249:}

wangka 发表于 2021-8-11 19:18:17

页: [1] 2
查看完整版本: 关于s1e40动动手代码中ungetch的疑问