/*
时间:2017/8/17
地点:工程北629
功能:逆波兰算法实现计算器
思想:逆波兰算法 、全局变量,局部变量 、栈内存
问题:特别注意:该程序对首先输入负数的情况,有待编写。
理解:自己思考并调试程序。
*/
#include<stdio.h>
#include<stdlib.h>
#define MAXOP 100 //全局变量MAXOP,作用范围全局。
#define NUMBER '0'
int getop(char []); //获取下一个运算符或数值
void push(double); //把f压入到值栈中
double pop(void); //弹出返回栈顶值
/* 主函数 */
int main(void)
{
printf("请按照逆波兰运算,以空格分开:\n");
int type;
double op2;
char s[MAXOP]; //定义局部变量, 作用范围main函数中。含100个元素的全0数组s
while((type = getop(s)) != EOF) //main函数调用getop函数,向getop函数发送长度100的全0数组s
{
switch(type)
{
case NUMBER:
push(atof(s)); //请参考atof函数,将字符串转换成数字,参考《The C Programming Language》4.3节
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;
}
}
return 0;
}
#include<ctype.h>
int getch(void);
void ungetch(int);
/* 获取下一个数值或者操作数 */
int getop(char s[])
{
int i, c;
while((s[0] = c = getch()) == ' ' || c == '\t') //getop函数 纯调用getch函数,不发送任何实参。 算术> 关系> 逻辑> 赋值
;
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 BUFSIZE 100 //定义缓冲区
char buf[BUFSIZE]; // 用于ungetch函数的缓冲区
int bufp = 0; // buf中给下一个空闲位置,输出缓冲的字符,bufp是全局变量,该变化的数值下一次要使用。
/* 取出一个字符(可能是压回的字符) */
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar(); //getch函数调用getchar函数
}
/* 把字符压回到输入中*/
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
#define MAXVAL 100
int sp = 0; //定义全局变量,sp的值,下一次调用要使用。
double val[MAXVAL];
/* 把f压入到值栈中 */
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;
}
}
/*
在Vc++6.0中的输出结果是:
----------------------------
请按照逆波兰运算,以空格分开:
1 2 - 4 5 + *
运算结果是:-9
1 2 - 4 5 + /
运算结果是:-0.11111111
1.1 2.2 - 3.3 4.4 + *
运算结果是:-8.47
1.1 2.2 + 3.3 4.4 - *
运算结果是:-3.63
-1 2 +
error: stack empty
error: stack empty
运算结果是:3
-1 2 -
error: stack empty
运算结果是:-1
-1 2 + 4 5 - *
error: stack empty
运算结果是:-3
-1 2 - 4 5 + /
error: stack empty
运算结果是:-0.11111111
^Z
Press any key to continue
----------------------------
总结:1、因为需要共享,所以需要定义全局变量。因为变量的值在内存中不断变化。
当下一次需要继续使用该变量时,不得不使用全局的变量,因为局部变量跳出函数后,系统将权限收回,不能再使用,
所以定义全局变量是必须的。
2、程序较长,可以从简单的逆波兰表达式 1 2 - \n 入手,将程序运行一遍,这样更有利于理解全局变量的意义。
3、对于 + - * /也可以不用空格分离。
*/
4.3节 逆波兰计算器——程序理解
最新推荐文章于 2024-01-22 17:06:58 发布