关于反向波兰表示法计算器的运算符优先级问题
operator priority problem about Reverse Polish Notation Calculator
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
void push(double);
double pop(void);
/* reverse Polish calculator */
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;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
}
#define MAXVAL 100
int sp = 0;
double val[MAXVAL];
void push(double f)
{
if(sp < MAXVAL)
val[sp++]=f;
else
printf("error:stack full, cant push %g\n",f);
}
double pop(void)
{
if(sp>0)
return val[--sp];
else
{
printf("error: stack empty\n");
return 0.0;
}
}
#include<ctype.h>
int getch(void);
void ungetch(int);
int getop(char *s)
{
char c;
while ((*s = c = getch()) == ' ' || c == '\t')
;
*(s + 1) = '[=10=]';
if (!isdigit(c) && c != '.')
return c;
if (isdigit(c))
{
while (isdigit(*s++ = c = getch()))
;
}
if (c == '.')
{
while (isdigit(*s++ = c = getch()))
;
}
*s = '[=10=]';
if (c != EOF)
ungetch(c);
return number;
}
char buf[30];
char *Bufp = buf;
int getch(void)
{
return (Bufp > buf) ? *(--Bufp) : getchar();
}
void ungetch(int c)
{
if (c != EOF)
*Bufp++ = c;
else
printf("no space\n”);
}
结果如下。
enter image description here
当我更改此部分时。
int getch(void);
void ungetch(int);
int getop(char *s)
{
char c;
while ((*s = c = getch()) == ' ' || c == '\t')
;
*(s + 1) = '[=11=]';
if (!isdigit(c) && c != '.')
return c;
if (isdigit(c))
{
while (isdigit(*++s = c = getch()))
;
}
if (c == '.')
{
while (isdigit(*++s = c = getch()))
;
}
*s = '[=11=]';
if (c != EOF)
ungetch(c);
return number;
}
结果是正确的。
结果如下enter image description here
所以我知道
肯定有区别
while (isdigit(*++s = c = getch()))
和
while (isdigit(* s++ = c = getch()))
这个问题一定是跟运营商的优先级有关。但是我仍然不明白它发生的原因。你愿意帮助我吗?或者你能告诉我类似的问题吗?因为我找了很久
—————————————————————— 上面的问题已经solved.The新问题如下
首先,谢谢大家帮助我,并为我提供了解决上述问题的新方向。
但我仍然有疑问。
对于
while (isdigit(*++s = c = getch()))
我用更好理解的方式来达到同样的效果
while (c = getch())
{
++s;
if (isdigit(*s = c))
;
else
break;
}
同理
while (isdigit(* s++ = c = getch()))
更好理解的代码
while (c = getch())
{
if (isdigit(*s = c))
{
s++;
}
else
break;
}
我不明白的是 * s++ = c
等于 * (s++) = c
。为什么语句和下面的代码不一样?
s++;
*s = c;
运算符++
的优先级高于*
和=
,对吧?
哦,我知道了。 具有更高优先级的运算符并不一定意味着它首先发生。特别是,对于post增量,它不会发生直到变量具有有效值(或该值已被使用).
所以,首先我们得到一个字符 getch()
,然后将它赋值给c
变量。接下来,对于* s++ = c
,虽然它等于* (s++) = c
,但直到s
指针变量有它的有效值时才会发生递增。执行语句*s = c
。
最后,如果 *s
是数字,则执行 s++
.
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
void push(double);
double pop(void);
/* reverse Polish calculator */
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;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
}
#define MAXVAL 100
int sp = 0;
double val[MAXVAL];
void push(double f)
{
if(sp < MAXVAL)
val[sp++]=f;
else
printf("error:stack full, cant push %g\n",f);
}
double pop(void)
{
if(sp>0)
return val[--sp];
else
{
printf("error: stack empty\n");
return 0.0;
}
}
#include<ctype.h>
int getch(void);
void ungetch(int);
int getop(char *s)
{
char c;
while ((*s = c = getch()) == ' ' || c == '\t')
;
*(s + 1) = '[=10=]';
if (!isdigit(c) && c != '.')
return c;
if (isdigit(c))
{
while (isdigit(*s++ = c = getch()))
;
}
if (c == '.')
{
while (isdigit(*s++ = c = getch()))
;
}
*s = '[=10=]';
if (c != EOF)
ungetch(c);
return number;
}
char buf[30];
char *Bufp = buf;
int getch(void)
{
return (Bufp > buf) ? *(--Bufp) : getchar();
}
void ungetch(int c)
{
if (c != EOF)
*Bufp++ = c;
else
printf("no space\n”);
}
结果如下。 enter image description here
当我更改此部分时。
int getch(void);
void ungetch(int);
int getop(char *s)
{
char c;
while ((*s = c = getch()) == ' ' || c == '\t')
;
*(s + 1) = '[=11=]';
if (!isdigit(c) && c != '.')
return c;
if (isdigit(c))
{
while (isdigit(*++s = c = getch()))
;
}
if (c == '.')
{
while (isdigit(*++s = c = getch()))
;
}
*s = '[=11=]';
if (c != EOF)
ungetch(c);
return number;
}
结果是正确的。 结果如下enter image description here
所以我知道
肯定有区别while (isdigit(*++s = c = getch()))
和
while (isdigit(* s++ = c = getch()))
这个问题一定是跟运营商的优先级有关。但是我仍然不明白它发生的原因。你愿意帮助我吗?或者你能告诉我类似的问题吗?因为我找了很久
—————————————————————— 上面的问题已经solved.The新问题如下
首先,谢谢大家帮助我,并为我提供了解决上述问题的新方向。 但我仍然有疑问。 对于
while (isdigit(*++s = c = getch()))
我用更好理解的方式来达到同样的效果
while (c = getch())
{
++s;
if (isdigit(*s = c))
;
else
break;
}
同理
while (isdigit(* s++ = c = getch()))
更好理解的代码
while (c = getch())
{
if (isdigit(*s = c))
{
s++;
}
else
break;
}
我不明白的是 * s++ = c
等于 * (s++) = c
。为什么语句和下面的代码不一样?
s++;
*s = c;
运算符++
的优先级高于*
和=
,对吧?
哦,我知道了。 具有更高优先级的运算符并不一定意味着它首先发生。特别是,对于post增量,它不会发生直到变量具有有效值(或该值已被使用).
所以,首先我们得到一个字符 getch()
,然后将它赋值给c
变量。接下来,对于* s++ = c
,虽然它等于* (s++) = c
,但直到s
指针变量有它的有效值时才会发生递增。执行语句*s = c
。
最后,如果 *s
是数字,则执行 s++
.