第4.3节 编写一个具有加、减、乘、除四则运算功能的计算机程序

来源:互联网 发布:联想笔记本网络开关 编辑:程序博客网 时间:2024/05/19 05:01
#include <stdio.h>#include <stdlib.h>#define MAXOP 100#define NUMBER '0'int getop(char []);void push(double);double pop(void);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;        }    }    return 0;}

getop(s)返回结果是数则压入栈中;是操作符则将计算结果压入栈中;是换行符则返回栈顶值。数值储存于字符串s中,压入栈前需要由atof(s)转换。判断等于0和不等于0哪个容易?答案是判断是否等于0。

#define MAXVAL 100int sp=0;double val[MAXVAL];void push(double f){    if(sp<MAXVAL)        val[sp++]=f;    else        printf("error: stack full,can't push %g\n",f);}

栈大小为100,能储存100个双精度数。

double pop(void){    if(sp>0)        return val[--sp];    else{        printf("error: stack empty\n");        return 0.0;    }}

弹出储存于栈中的数。push和pop都要用到栈位置,sp为全局变量。

#include <ctype.h>int getch(void);void ungetch(int);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;}

把数存入字符串s,首先要跳过空白符,再判断是否数字或小数点(用到库ctype.h的函数isdigit),若不是返回c,若是则将数存入字符串s。isdigit(s[++i]=c=getch())不能写作isdigit(s[++i]=getch()),否则出错。

#define BUFSIZE 100char buf[BUFSIZE];int bufp=0;int getch(void){    return (bufp>0)? buf[--bufp]:getchar();}void ungetch(int c){    if(bufp>=BUFSIZE)        printf("ungetch: too many characters\n");    else        buf[bufp++]=c;}

由于需要多读取一个以判断是否存入结束,需要利用缓冲,buf[BUFSIZE]、bufp为全局变量,来输出缓冲的一个字符。例如输入如下:

12 3+

把12压入栈中,多读取一个空格,存入buf[0]中,bufp为1;再运行getch()时,先读取buf[0],跳过空格,将3压入栈中,多读取’+’字符,存入buf[0]中,bufp为1;再运行getch(),读取’+’字符。bufp一直是0,1,0,1……。

测试:

    if(isdigit(c))        while(isdigit(s[++i]=c=getch())){            //;            putchar(s[i]);            printf("i:%d\n",i);        }

输入:

12345 67+

输出:

2i:13i:24i:35i:47i:1        12412

去掉=c则输出:

2i:13i:24i:35i:46i:17i:2

原因在于后面ungetch(c)需要以c作为输入,再次读入c,此时c并非多读的一个字符,而是最开始读的数。’+’为多读取的字符,但是重新输入的却是1。

0 0
原创粉丝点击