C程式設計語言逆波蘭式計算器學習心得
阿新 • • 發佈:2019-02-05
#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){//只要輸出的不是一個完整的EOF,這個迴圈就會持續呼叫getop錄入資料
switch(type){
case NUMBER://如果是數字,getop函式將返回我們設定好的標誌'0',則把s中的字串轉數字入棧
push(atof(s));
break;
case '+'://加法運算和乘法運算都是提取出最近的兩個值,計算後把結果入棧。
push(pop()+pop());
break;
case '*':
push(pop()*pop());
break;
case '-'://減法和除法,需要考慮除數不為0以及先後次序,再計算後入棧
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;
}
#define MAXVAL 100 //棧 val的最大深度
int sp = 0; //下一個空棧位置
double val[MAXVAL]; //值棧val用於在計算中儲存所有有效資料(不儲存任何計算符號!)
//運算子號在被getop函式錄入的同時,計算後的值就已經被錄入到了val,且被肌酸的數也會出棧。
// push 函式:把 f 壓入值棧中,並把空棧位置後移(乾淨利落)
void push(double f)
{
if(sp < MAXVAL)
val[sp++] = f;
else
printf("棧已滿不能壓入 %g\n",f);
}
//pop 函式:彈出並返回棧頂!頂的值,也就是最後一位的值,同時把空棧標記前移
double pop(void)
{
if(sp > 0)
return val[--sp];
else
{
printf("棧是空的\n");
return 0.0;
}
}
//以下是獲取下一個輸入的函式
#include<ctype.h>
int getch(void);//這兩個函式可以被稱作是,“壓入”和“釋放”緩衝區
void ungetch(int);
int getop(char s[]){//這個函式與緩衝區函式對接,篩選並返回出輸入的有效結果,用於main()函式
int i,c;
while((s[0]=c=getch())==' '||c=='\t')
;//空格與tab是允許出現的非數字及運算子號,用於表示間隔,沒有它們的話將無法分開多個連續數字。
s[1]='\0';//探測到間隔符,但是根據實測,沒必要增加結尾符,探測到空格則會自動結尾。
if (!isdigit(c) && c!='.')
return c; //非數字,直接返回,是否是合法符號main會探測。
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);//刪掉這句,例如 1 2+ 的寫法將無法讀取到+。按格式寫的話這句的確無用。
return NUMBER;
}
#define BUFSIZE 100
//緩衝區
char 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;
}