1. 程式人生 > >C程式設計語言逆波蘭式計算器學習心得

C程式設計語言逆波蘭式計算器學習心得

#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; }