C語言表達式求值(帶詳細注釋)_第1頁
C語言表達式求值(帶詳細注釋)_第2頁
C語言表達式求值(帶詳細注釋)_第3頁
C語言表達式求值(帶詳細注釋)_第4頁
C語言表達式求值(帶詳細注釋)_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、/*表達式求值,輸入一個表達式,如1+2*3#,程序可計算出結(jié)果為7支持以下符號:+ - * / ( ) .可以計算整數(shù)、小數(shù)其中表示次方,25表示2的5次方*/*頭文件*/#include <stdio.h>#include <malloc.h>#include <string.h>#include <math.h>#include <stdlib.h>/*宏定義*/#define INIT_STACK_SIZE 100#define SET_NUM 8#define N 100/*字符優(yōu)先級表*/unsigned char pri

2、orSET_NUMSET_NUM = /* '+' '-' '*' '/' '(' ')' '#' '' */ /*'+'*/'>', '>', '<', '<', '<', '>', '>', '<', /*'-'*/'>', '&

3、gt;', '<', '<', '<', '>', '>', '<', /*'*'*/'>', '>', '>', '>', '<', '>', '>', '<', /*'/'*/'>', '>', '

4、;>', '>', '<', '>', '>', '<', /*'('*/'<', '<', '<', '<', '<', '=', ' ', '<', /*')'*/'>', '>', '>', '>

5、;', ' ', '>', '>', '>', /*'#'*/'<', '<', '<', '<', '<', ' ', '=', '<', /*''*/'>', '>', '>', '>', '<',

6、'>', '>', '>' ; unsigned char priorSetSET_NUM = '+', '-', '*', '/', '(', ')', '#', ''/*結(jié)構(gòu)體定義,這是用來存放字符的棧*/typedef structchar *base;char *top;int stacksize; SqStackC;/*結(jié)構(gòu)體定義,這是用來存放數(shù)字的棧*/推薦精選typedef structd

7、ouble *base;double *top;int stacksize; SqStackN;void initStackN(SqStackN &);void initStackC(SqStackC &);void pushN(SqStackN &, double);void pushC(SqStackN &, double);void popN(SqStackN &, double &);void popC(SqStackN &, double &);double calculate(double, char, double)

8、;int findInSet(char);char compare(char, char);void getSolution();/*主函數(shù)*/void main()getSolution();/*初始化數(shù)字棧*/void initStackN(SqStackN &S)S.base = (double*) malloc(INIT_STACK_SIZE * sizeof(double);S.top = S.base;S.stacksize = INIT_STACK_SIZE;/*初始化字符棧*/void initStackC(SqStackC &S)S.base = (char*

9、) malloc(INIT_STACK_SIZE * sizeof(char);S.top = S.base;S.stacksize = INIT_STACK_SIZE;/*向數(shù)字棧中存放數(shù)字*/void pushN(SqStackN &S, double x)if (S.top-S.base >= S.stacksize) 推薦精選return;*(S.top+) = x;/*向字符棧中存放字符*/void pushC(SqStackC &S, char x)if (S.top - S.base >= S.stacksize) return;*(S.top+) =

10、 x;/*從數(shù)字棧中取出數(shù)字*/void popN(SqStackN &S, double &x)if (S.top=S.base) return;x = *(-S.top);/*從字符棧中取出字符*/void popC(SqStackC &S, char &x)if (S.top = S.base) return;x = *(-S.top);/*這個函數(shù)返回a operation b的值。假如operation為'+',則返回a+b的值*/double calculate(double a, char operation, double b)/

11、*判斷operation,返回對應(yīng)的計算結(jié)果*/switch (operation) case '+':return a + b;case '-':return b - a;case '*':return a * b;case '/':return b / a;case '':return pow(b, a);default:推薦精選return 0;/*查找字符c在priorSet中的什么位置*/*priorSet是所支持的所有字符的集合*/int findInSet(char c)int i;for (i =

12、0; i < SET_NUM; i+) if (priorSeti = c)return i;return -1;/*比較optrtop和c的優(yōu)先關(guān)系*/char compare(char optrtop, char c)int i, j;/*從priorSet中取出optrtop和c的位置*/i = findInSet(optrtop);j = findInSet(c);/*如果返回值中有-1表示這個符號不支持,結(jié)束程序*/if (i = -1 | j = -1) printf("不支持的符號類型n");exit(0);/*否則返回二者優(yōu)先級關(guān)系*/elseretu

13、rn priorij;/*取得計算結(jié)果*/*解釋下代碼處理數(shù)字的原理:假如輸入為10+2.2*3-2#循環(huán)會從這個字符串第一個位置開始,也就是1如果當(dāng)前字符是個數(shù)字,則要把這個數(shù)字從字符串里取出來這個時候涉及兩個問題,一是數(shù)字可能是大于10的整數(shù),二是可能有小數(shù)。處理方法是這樣的:當(dāng)遇到數(shù)字,先將數(shù)字保存在n上,判斷下一個字符是數(shù)字還是運算符推薦精選如果是數(shù)字,則將n乘以10加上這個數(shù)字,這樣即可以處理大于10的數(shù)字。如果遇到運算符,就退出循環(huán)去處理運算符如果遇到的是小數(shù)點,表示這個數(shù)字是小數(shù)。小數(shù)不會立刻計算出來,而是先將小數(shù)點忽視掉,將整數(shù)計算出。比如2.2會先計算成22 變量j和begi

14、n在遇到小數(shù)點時候用來計算小數(shù)點后面有幾個數(shù)字,即這個小數(shù)有多少位。當(dāng)begin = 1時候,表示現(xiàn)在要計算小數(shù)點后的數(shù)字位數(shù)。這時候j會在每次循環(huán)加1這樣計算后,n = 22, j = 1;此時算 n = n / pow(10, j);即將n縮小10的j次方。就變成了2.2*/void getSolution()/*operation是當(dāng)前的運算符*/char operation;/*temp是輸入的字符串*/char tempN;/*i是循環(huán)變量,j和begin用來控制什么時候計算出小數(shù)*/int i = 0, j = -1, begin = 0;/*sum是每次的計算結(jié)果,a和b是從數(shù)字

15、棧中取出的數(shù)字,n用來存放從字符串中取出的數(shù)*/double sum, a, b, n;/*定義堆棧并初始化*/SqStackC OPTR;SqStackN OPND;initStackC(OPTR);initStackN(OPND);/*向字符棧中壓入#,標志開始*/pushC(OPTR, '#');/*獲得輸入*/printf("請輸入一個表達式,輸入#結(jié)束n");gets(temp);/*開始計算,當(dāng)遇到#表示結(jié)束*/while (tempi != '#' | *(OPTR.top - 1) != '#') /*如果當(dāng)前

16、字符是個數(shù)字字符*/推薦精選if (tempi >= '0' && tempi <= '9') /*重置n為0*/n = 0;/*當(dāng)當(dāng)前字符是數(shù)字或者小數(shù)點*/while (tempi >= '0' && tempi <= '9' | tempi = '.') /*如果是小數(shù)點,begin=1,表示要從字符串中取出一個小數(shù)*/if (tempi = '.') begin = 1;/*否則作為整數(shù)取出*/else n = n * 10 + tem

17、pi - '0'/*如果begin不為0,表示遇到了一個小數(shù)點,表示需要合并為小數(shù)*/*j表示這個小數(shù)的小數(shù)點后面有幾位*/if (begin != 0) j+;/*循環(huán)變量加1*/i+;/*如果j不為-1,則表示這是個小數(shù),n是整數(shù)結(jié)果,除以pow(10,j)則變成了小數(shù)*/if (j != -1) n = n / pow(10, j);/*將數(shù)字壓入棧*/pushN(OPND, n);/*重置j和begin的值*/j = -1;begin = 0; else /*如果當(dāng)前字符不是數(shù)字,比較棧頂字符和當(dāng)前字符優(yōu)先級,根據(jù)優(yōu)先級處理*/switch (compare(*(OPTR.top - 1), tempi) /*如果棧頂字符優(yōu)先級大,則可以取出計算*/case '>':/*取出字符棧頂運算符,和數(shù)字棧頂?shù)膬蓚€數(shù)字*/popC(OPTR, operation);popN(OPND, a);popN(OPND, b);/*計算結(jié)果*/sum = calculate(a, operation, b);/*結(jié)果入棧*/推薦精選pushN(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論