4.3节 逆波兰计算器——程序理解

来源:互联网 发布:java字符串占位符替换 编辑:程序博客网 时间:2024/06/08 02:01
/*时间: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);elseprintf("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");elsebuf[bufp++] = c;}#define MAXVAL 100  int sp = 0;  //定义全局变量,sp的值,下一次调用要使用。double val[MAXVAL];  /*  把f压入到值栈中  */void push(double f){if(sp < MAXVAL)val[sp++] = f;elseprintf("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 + *运算结果是:-91 2 - 4 5 + /运算结果是:-0.111111111.1 2.2 - 3.3 4.4 + *运算结果是:-8.471.1 2.2 + 3.3 4.4 - *运算结果是:-3.63-1 2 +error: stack emptyerror: 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^ZPress any key to continue----------------------------总结:1、因为需要共享,所以需要定义全局变量。因为变量的值在内存中不断变化。     当下一次需要继续使用该变量时,不得不使用全局的变量,因为局部变量跳出函数后,系统将权限收回,不能再使用,     所以定义全局变量是必须的。  2、程序较长,可以从简单的逆波兰表达式  1 2 - \n  入手,将程序运行一遍,这样更有利于理解全局变量的意义。     3、对于 + - * /也可以不用空格分离。  */

原创粉丝点击