




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、安徽新華學(xué)院數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告題目: 模擬計(jì)算器程序 學(xué)院: 信息工程學(xué)院 專業(yè): 信息與計(jì)算科學(xué) 班級(jí): 12級(jí)信息與計(jì)算科學(xué)一班 姓名: 孫偉偉 學(xué)號(hào): 1242155116 指導(dǎo)教師: 李明 設(shè)計(jì)時(shí)間: 2013.12.162013.12.31 課程設(shè)計(jì)任務(wù)書(shū)一、 設(shè)計(jì)任務(wù)設(shè)計(jì)一個(gè)模擬計(jì)算器的程序二、 設(shè)計(jì)要求1、 要求對(duì)包含加、減、乘、除、括號(hào)運(yùn)算符及SQR和ABS函數(shù)的任意整型表達(dá)式進(jìn)行求解2、程序基本功能要求實(shí)現(xiàn)完整,并有簡(jiǎn)單的驗(yàn)證。3、設(shè)計(jì)報(bào)告要求格式規(guī)范,符合學(xué)校課程設(shè)計(jì)報(bào)告要求。4、報(bào)告中流程圖要求描述規(guī)范,算法設(shè)計(jì)清楚正確。 三、 設(shè)計(jì)期限2013年12月16日到2013
2、年12月31日前言利用本學(xué)期所學(xué)的C語(yǔ)言程序設(shè)計(jì)課程,運(yùn)用相關(guān)知識(shí),查閱相關(guān)資料,編寫(xiě)C語(yǔ)言程序,設(shè)計(jì)一個(gè)簡(jiǎn)單計(jì)算器,要求編寫(xiě)的簡(jiǎn)單計(jì)算器能夠模擬windows系統(tǒng)的計(jì)算器,用戶能夠用鍵盤(pán)輸入相關(guān)數(shù)據(jù),要求對(duì)包含加、減、乘、除、括號(hào)運(yùn)算符及SQR和ABS函數(shù)的任意整型表達(dá)式進(jìn)行求解,并且在程序運(yùn)行過(guò)程中能夠正常的退出程序。這個(gè)程序?qū)嶋H上就是對(duì)一個(gè)表達(dá)式進(jìn)行計(jì)算。而一個(gè)算術(shù)表達(dá)式中包含各種運(yùn)算符,每個(gè)運(yùn)算符的等級(jí)可能會(huì)不同,這就成了本程序需要解決的一個(gè)主要的問(wèn)題之一了。另外計(jì)算器中需要有各種數(shù)學(xué)函數(shù),比如:abs sqrt sin cos tan等,如何對(duì)這些函數(shù)進(jìn)行處理,也是本程序能成功的一個(gè)
3、關(guān)鍵。還有一個(gè)問(wèn)題就是如何處理操作符和操作數(shù)之間的關(guān)系也是一個(gè)要點(diǎn)。例如:1+2*(3-2/1),經(jīng)過(guò)怎么樣的變換和處理能得出結(jié)果。數(shù)據(jù)的輸入這里應(yīng)該要用字符,然后通過(guò)字符和整形之間的關(guān)系進(jìn)行轉(zhuǎn)換即可,這樣處理的話,就方便很多了。在計(jì)算器程序運(yùn)行中,輸入數(shù)據(jù)時(shí)如果遇到輸入錯(cuò)誤的情況,能夠能過(guò)鍵盤(pán)上的退格鍵進(jìn)行刪除,并且重新輸入正確的數(shù)據(jù)。在數(shù)據(jù)輸入完成后,如果需要放棄本次計(jì)算操作,可以利用程序中設(shè)置好的按鍵進(jìn)行清零,并為下一次運(yùn)算作準(zhǔn)備。本課程設(shè)計(jì)主要解決的是傳統(tǒng)計(jì)算器中,不能對(duì)表達(dá)式進(jìn)行運(yùn)算的問(wèn)題,通過(guò)制作該計(jì)算器模擬程序,可以做到快速的求解表達(dá)式的值,并且能夠判定用戶輸入的表達(dá)式是否合法。
4、該模擬計(jì)算器的核心部分就在用戶輸入的中綴表達(dá)式的轉(zhuǎn)化,程序中用到了“?!钡暮筮M(jìn)先出的基本性質(zhì)。目錄第1章 需求分析 5 1.1 系統(tǒng)設(shè)計(jì)流程圖 5 1.2 主要功能表 6第2章 總體設(shè)計(jì) 7 2.1 數(shù)據(jù)結(jié)構(gòu)的選擇 7 2.2 程序?qū)崿F(xiàn)流程圖 8第3章 詳細(xì)設(shè)計(jì)和編碼 9 3.1 表達(dá)式的判斷 10 3.2 棧的定義及存儲(chǔ) 113.3 表達(dá)式的嵌套處理 143.4 中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式 14第 4章 編碼與調(diào)試 17 4.1 系統(tǒng)測(cè)試 17 4.2 調(diào)試 17 4.3錯(cuò)誤原因分析 17 4.4 調(diào)試結(jié)果 19第 5章 總結(jié) 21參考文獻(xiàn) 22 附錄 23第1章 需求分析1.1系統(tǒng)流程圖本
5、課程設(shè)計(jì)主要解決的是傳統(tǒng)計(jì)算器中,不能對(duì)表達(dá)式進(jìn)行運(yùn)算的問(wèn)題,通過(guò)制作該計(jì)算器模擬程序,可以做到快速的求解表達(dá)式的值,并且能夠判定用戶輸入的表達(dá)式是否合法。該模擬計(jì)算器的核心部分就在用戶輸入的中綴表達(dá)式的轉(zhuǎn)化,程序中用到了“?!钡暮筮M(jìn)先出的基本性質(zhì)。利用兩個(gè)“?!?,一個(gè)“數(shù)據(jù)棧”,一個(gè)“運(yùn)算符?!眮?lái)把中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式。最后利用后綴表達(dá)式來(lái)求解表達(dá)式的值。該算法的復(fù)雜度為O(n),能夠高效、快速地求解表達(dá)式的值,提高用戶的效率。本次課程設(shè)計(jì)為計(jì)算器模擬程序,主要解決表達(dá)式計(jì)算的問(wèn)題,實(shí)現(xiàn)分別按表達(dá)式處理的過(guò)程分解為幾個(gè)子過(guò)程,詳細(xì)的求解過(guò)程如下:1 、用戶輸入表達(dá)式。2
6、60;、判定表達(dá)式是否合法。3 、把中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式。4 、求出后綴表達(dá)式的結(jié)果。5 、輸出表達(dá)式的結(jié)果。通過(guò)設(shè)計(jì)該程序,從而做到方便的求出一個(gè)表達(dá)式的值,而不需要一步一步進(jìn)行運(yùn)算。輸入第一個(gè)操作數(shù)加法減法乘法除法清零ABSSQRT顯示結(jié)果輸入第二個(gè)操作數(shù)結(jié)束開(kāi)始 1.1系統(tǒng)設(shè)計(jì)流程圖1.2主要功能表序號(hào)文件名主要功能備注1+加法兩個(gè)操作數(shù)2-減法兩個(gè)操作數(shù)3*乘法兩個(gè)操作數(shù)4/除法兩個(gè)操作數(shù)5aqrt開(kāi)方一個(gè)操作數(shù)6abs絕對(duì)值一個(gè)操作數(shù)7Enter等于8Tab清零90退出除了實(shí)現(xiàn)基本的功能外,我還增加了其它一些功能,比如支持輸入數(shù)據(jù)為浮點(diǎn)數(shù),更重要的
7、是本程序還支持表達(dá)式的嵌套運(yùn)算,例如:A(1+2*S(2)我的實(shí)現(xiàn)方法是利用函數(shù)的遞歸調(diào)用來(lái)解決此問(wèn)題,即把1+2*S(2)看成一個(gè)子表達(dá)式,這個(gè)子表達(dá)式中2也看成子表達(dá)式。這樣使得程序的適用范圍更加的廣泛,適應(yīng)性更強(qiáng),能支持更復(fù)雜的表達(dá)式的運(yùn)算。這也是本程序的優(yōu)點(diǎn)之一。第2章 總體設(shè)計(jì)2.1 數(shù)據(jù)結(jié)構(gòu)選擇輸入的時(shí)候?qū)⒁粋€(gè)算術(shù)表達(dá)式用一個(gè)字符數(shù)組來(lái)接收,故需要對(duì)這個(gè)數(shù)組進(jìn)行處理,讓操作數(shù)和操作符分開(kāi),這里我想把開(kāi)始的算術(shù)表達(dá)式轉(zhuǎn)換成一個(gè)后綴表達(dá)式,這樣在進(jìn)行計(jì)算的時(shí)候就簡(jiǎn)單多了。而在轉(zhuǎn)換的過(guò)程中,對(duì)運(yùn)算符的處理極為重要,這里運(yùn)用堆棧,用堆棧的先進(jìn)后出的特點(diǎn),來(lái)處理運(yùn)算符優(yōu)先級(jí)的問(wèn)題,讓其成功轉(zhuǎn)
8、換成后綴表達(dá)式。而在對(duì)后綴表達(dá)式進(jìn)行處理的時(shí)候,又需要一個(gè)堆棧,這個(gè)堆棧存放操作數(shù)的。并將運(yùn)算結(jié)果存入該棧中。兩個(gè)堆棧的數(shù)據(jù)結(jié)構(gòu)如下:struct char dataMaxlen; int top; optr; /定義運(yùn)算符棧struct double dataMaxlen; int top; opnd; /定義操作數(shù)棧這里定義了類型,并且一起定義了兩者類型的對(duì)象optr,opnd。在將算術(shù)表達(dá)式轉(zhuǎn)換成后綴表達(dá)式,定義change函數(shù);在對(duì)后綴表達(dá)式進(jìn)行處理時(shí),定義jisuan函數(shù),另外本程序有個(gè)歡迎界面,由meun函數(shù)實(shí)現(xiàn)。因此主函數(shù)于各函數(shù)之間的關(guān)系為: meun()main() chan
9、ge() jisuan() 2.2程序?qū)崿F(xiàn)流程圖 2.2程序設(shè)計(jì)流程圖這里的兩個(gè)主要的函數(shù)具體算法在詳細(xì)設(shè)計(jì)中有說(shuō)明本課程設(shè)計(jì)需要考慮許多的問(wèn)題,首先是表達(dá)式的合法判斷,然后是字符串表達(dá)式提取分離的問(wèn)題,核心部分就是中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式。對(duì)于第一個(gè)問(wèn)題,我是分步來(lái)判斷,首先表達(dá)式中是否含有其它非法字符,然后判斷括號(hào)是否合法,接著判斷運(yùn)算法兩邊是否合法比如除法時(shí),除數(shù)不能為零。對(duì)于第二個(gè)問(wèn)題,我是直接轉(zhuǎn)換的,從左到右遍歷中綴表達(dá)式,把數(shù)據(jù)全部取出來(lái)。對(duì)于核心問(wèn)題,利用了“?!边@種“后進(jìn)先出”的數(shù)據(jù)結(jié)構(gòu),利用兩個(gè)“?!?,一個(gè)“數(shù)據(jù)?!保粋€(gè)“運(yùn)算符?!眮?lái)把中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式。最后利用
10、后綴表達(dá)式來(lái)求解表達(dá)式的值。本程序用戶界面總共分為3個(gè)模塊,分別是操作提示,數(shù)據(jù)輸入,數(shù)據(jù)輸出。如圖2.3所示。 2.3用戶界面第3章 詳細(xì)設(shè)計(jì)和編碼3.1表達(dá)式的判斷表達(dá)式的合法判定過(guò)程如圖3.1所示首先是其它字符的判定,從左到右遍歷中綴表達(dá)式,看是否存在其它非法的。然后是判定括號(hào)是否的匹配是否和合法,首先把“(”對(duì)應(yīng)為1,相應(yīng)的“)”對(duì)應(yīng)為-1。從左到右遍歷表達(dá)式,如果遇到括號(hào)就加上其對(duì)應(yīng)的值,用sum來(lái)保存其累加值。如果在中途出現(xiàn)小于零的情況,即出現(xiàn)“. )”那么的情況,即非法。在遍歷的最后,還要判斷sum的值是否為零,如果為零就是合法,否則就是非法。代碼如下: for(i=0;i<
11、;s.length();i+) /檢驗(yàn)括號(hào)是否合法,以及是否存在非法字符 if(!IsNum(si) && !IsSign(si) && si!='(' && si!=')' && si!='A' && si!='S' && si!='.')return false; if(si='(')sum+=1; else if(si=')')sum-=1; if(sum<0)return f
12、alse; /括號(hào)匹配不合法 運(yùn)算符判斷是否合法,也是遍歷一遍表達(dá)式,遇到“/”,看其后面的除數(shù)是否為零。這里要考慮表達(dá)式中出現(xiàn)負(fù)數(shù)的情況,因此特殊考慮“-”號(hào),判斷它的前面是“(”還是沒(méi)有字符了,那么就是負(fù)數(shù)。3.2棧的定義、存儲(chǔ)然后定義兩個(gè)數(shù)組,p400用來(lái)存放算術(shù)表達(dá)式,q400用來(lái)存放后綴表達(dá)式。由前面的數(shù)據(jù)結(jié)構(gòu)定義兩個(gè)對(duì)象,。當(dāng)輸入一個(gè)表達(dá)式后,定義i作為q的下標(biāo),定義dh=1表示是負(fù)號(hào),初始化運(yùn)算符棧optr.top=-1;讓后對(duì)進(jìn)行掃描,當(dāng)指向的為數(shù)字字符,則將此字符如,后在往中輸入,具體為:while (*p>='0' && *p<=
13、'9') qi=*p;i+; p+; if (*p='.') qi='.' i+; p+; while (*p>='0' && *p<='9') qi=*p;i+; p+; qi='#' i+; dh=0; p后移,繼續(xù)掃描,當(dāng)遇到或時(shí),執(zhí)行if (dh=1) if (*p='-') optr.top+;optr.dataoptr.top='' p+; break; while (optr.top!=-1 && optr.d
14、ataoptr.top!='(') qi=optr.dataoptr.top; optr.top-; i+; optr.top+;optr.dataoptr.top=*p; p+; dh=0; break;當(dāng)遇到*或/時(shí),先查看操作符棧中是否有優(yōu)秀級(jí)比它大的或者一樣大的運(yùn)算符,有的話就將其他的出棧,最后自己入棧。執(zhí)行:while (optr.dataoptr.top='*' | optr.dataoptr.top='/'| optr.dataoptr.top='s') qi=optr.dataoptr.top; optr.top-
15、; i+; optr.top+;optr.dataoptr.top=*p; p+; dh=0; break;當(dāng)遇到(時(shí),此時(shí)不需要?jiǎng)e的其他的操作,只需將其入操作符棧,并將dh=0;當(dāng)遇到)時(shí),此時(shí)需要將(之前的操作符全部出棧,具體操作如下:while (optr.dataoptr.top!='(') qi=optr.dataoptr.top; optr.top-; i+; optr.top-; p+; dh=0; break;當(dāng)遇到時(shí),根據(jù)運(yùn)算符的優(yōu)先級(jí),執(zhí)行:while (optr.dataoptr.top='') qi=optr.dataoptr.top;
16、optr.top-;i+; optr.top+;optr.dataoptr.top=*p;p+;dh=0;break;遇到時(shí)的操作和差不多,這里就不做介紹了。當(dāng)遇到數(shù)學(xué)函數(shù)的相關(guān)符號(hào)時(shí),這里以sin 為例,當(dāng)掃描時(shí),還需要掃描后面的兩個(gè)字符,當(dāng)它們是in時(shí),說(shuō)明就是sin函數(shù)的符號(hào),此時(shí)將此函數(shù)的標(biāo)志入操作符棧,當(dāng)其為sqrt時(shí),說(shuō)明是sqrt函數(shù),此時(shí)將sqrt函數(shù)的標(biāo)志入棧,這里的標(biāo)志是自己定的。如果都不是上面兩種情況,說(shuō)明輸入有誤,跳回。具體的程序如下: if(*(p+1)='i' | *(p+1)='I')&&(*(p+2)='n
17、' | *(p+2)='N') optr.top+;optr.dataoptr.top='s' p+=3; dh=0; break; else if(*(p+1)='q'| *(p+1)='Q')&&(*(p+2)='r' | *(p+2)='R')&&(*(p+3)='t' | *(p+3)='T') optr.top+;optr.dataoptr.top='q' p+=4;dh=0;break; else c
18、out<<endl<<"有錯(cuò)誤符號(hào)"<<endl; return error; 其他的數(shù)學(xué)函數(shù)的操作都是類似的,這里就不一一說(shuō)明了。這里值得注意的是,當(dāng)將掃描完時(shí),操作符棧并未一定為空,故需要將操作符棧里的數(shù)據(jù)全部出棧:while (optr.top!=-1) qi=optr.dataoptr.top; i+; optr.top-; 以上是將算術(shù)表達(dá)式轉(zhuǎn)換成后綴表達(dá)式。還要對(duì)后綴表達(dá)式進(jìn)行計(jì)算,才能得到結(jié)果。首先還是對(duì)表達(dá)式進(jìn)行掃描,遇到數(shù)字符時(shí),先將其轉(zhuǎn)換成整形后,再判斷是否有小數(shù)點(diǎn)存在,繼續(xù)掃描直到遇到運(yùn)算符,讓后通過(guò)運(yùn)算,將次數(shù)轉(zhuǎn)換
19、成小數(shù),最后入棧。具體程序?qū)崿F(xiàn):d=0; while (*q>='0' && *q<='9') d=10*d+(*q-'0'); q+; x=0.1; if (*q='.') q+; while (*q>='0' && *q<='9') d=d+x*(*q-'0'); x*=0.1; q+; 當(dāng)遇到操作符時(shí),為雙目運(yùn)算符時(shí),只需要將操作數(shù)棧的棧頂和次棧頂數(shù)拿出來(lái)進(jìn)行相應(yīng)的計(jì)算,并將其壓入次棧頂。為單目運(yùn)算符時(shí),只需將操作數(shù)棧頂元
20、素進(jìn)行運(yùn)算即可,并將運(yùn)算符壓入棧即可。這里以/和為例。 其余的均和此類似。if (opnd.dataopnd.top!=0) opnd.dataopnd.top-1=opnd.dataopnd.top-1/opnd.dataopnd.top; else cout<<endl<<"除數(shù)不能為零!"<<endl; return error; 和 opnd.top-;break;opnd.dataopnd.top=sin(opnd.dataopnd.top);當(dāng)q都掃描完時(shí), 返回操作數(shù)棧頂元素就是計(jì)算的結(jié)果。3.3表達(dá)式嵌套處理如果遇到A()
21、和S()中含有表達(dá)式,而不是單純的數(shù)字,例如A(1.1+3.4*S(2.5),那么就需要對(duì)其字表達(dá)式“1.1+3.4*S(2.5)”進(jìn)行遞歸處理,這個(gè)子表達(dá)式中還含有子表達(dá)式“2.5”,然后再遞歸處理,依次類推下去。其核心代碼如下if(si='A' | si='S') /遇到Abs()或者Sqrt()遞歸處理子表達(dá)式 Expression temp; /創(chuàng)建子表達(dá)式 temp.Init(); for(j=0;i+j+2<Posi+1;j+) /復(fù)制表達(dá)式 stj=si+j+2; stj=0; temp.s=st; /復(fù)制表達(dá)式 temp.SloveExp(
22、); /得到子表達(dá)式的值 numk.first=(si='A'?fabs(temp.Ans):sqrt(temp.Ans); numk.second=0; /標(biāo)記為數(shù)據(jù) if(si-1='-' && (i-1=0 | si-2='(')numk.first=-numk.first; k+,i=Posi+1; 3.4 中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式,利用兩個(gè)“?!保粋€(gè)“數(shù)據(jù)?!?,一個(gè)“運(yùn)算符?!眮?lái)把中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式。最后利用后綴表達(dá)式來(lái)求解表達(dá)式的值。設(shè)一個(gè)stack存后綴數(shù)據(jù),一個(gè)rout棧存運(yùn)算
23、符。 算法流程如下: (1)從右向左依次取得數(shù)據(jù)ch。 (2)如果ch是操作數(shù),直接加進(jìn)stack中。 (3)如果ch是運(yùn)算符(含左右括號(hào)),則: a:如果ch = '(',放入堆棧rou中。 b:如果ch = ')'依次輸出堆棧rout中的運(yùn)算符,直到遇到'('為止。 c:如果ch不是')'或者'(',那么就和堆棧rout頂點(diǎn)位置的運(yùn)算符top做優(yōu)先級(jí)比較。 1:如果ch優(yōu)先級(jí)比rtop高,那么將ch放入堆棧rout。 2:如果ch優(yōu)先級(jí)低于或者等于rtop,那么輸出top到stack中(直到!top或者滿足 1
24、),然后將ch放入堆棧rout。 可以看出算法復(fù)雜度是O(n)的,因此效率是比較高的,能夠在1s內(nèi)處理百萬(wàn)級(jí)別長(zhǎng)度的表達(dá)式。算法的主要思想是利用“?!钡暮筮M(jìn)先出的特性,以及運(yùn)算符的優(yōu)先級(jí),這里我們定義運(yùn)算符的優(yōu)先級(jí);代碼如下:int GetKey(char c) /定義運(yùn)算符的關(guān)鍵字 int key; switch(c) case '+':key=1;break; case '-':key=1;break; case '*':key=2;break; case '/':key=2;break; case '(':k
25、ey=4;break; case ')':key=5;break; return key; 第 4章 編碼與調(diào)試程序的調(diào)試是指對(duì)程序的差錯(cuò)和排錯(cuò),為了便于差錯(cuò)、閱讀,在設(shè)計(jì)該程序的過(guò)程中我們采用了結(jié)構(gòu)化程序方法編輯,添加了盡可能多的注釋,這就為接下來(lái)的調(diào)試過(guò)程帶來(lái)了很多方便。經(jīng)過(guò)仔細(xì)檢查之后進(jìn)行上機(jī)調(diào)試。進(jìn)行編譯,如果在編譯和連接過(guò)程中發(fā)現(xiàn)錯(cuò)誤,屏幕上顯示了出錯(cuò)信息,根據(jù)提示找到出錯(cuò)的位置,加以改正,在進(jìn)行編譯如此反復(fù),直到順利通過(guò)編譯和連接為止。在本次實(shí)習(xí)過(guò)程中碰到的編譯、連接的錯(cuò)誤主要有:缺少變量定義、定義為置不正確、語(yǔ)法錯(cuò)誤、轉(zhuǎn)義字符漏用、邏輯錯(cuò)誤等。4.1 系統(tǒng)測(cè)試 4
26、.1系統(tǒng)測(cè)試圖4.2 調(diào)試根據(jù)電腦所給的提示出現(xiàn)語(yǔ)法錯(cuò)誤,缺少變量的定義大多的語(yǔ)法錯(cuò)誤在通過(guò)書(shū)本參考下能夠修改。主要是平時(shí)看書(shū)不仔細(xì)、不太注意而產(chǎn)生的,如沒(méi)有注意具體數(shù)據(jù)使用是有一定的范圍限定;過(guò)分重視分號(hào)的重要性而在for、if、while語(yǔ)句中畫(huà)蛇添足加分號(hào);在使用文件的時(shí)候忘記將文件先打開(kāi),對(duì)打開(kāi)的方式與使用的情況不太注意而造成不匹配;還有漏掉形參的定義是值不能傳遞等等。這些語(yǔ)法錯(cuò)誤有信息框的提示一般是能夠排除的。另外還有部分注釋的位置也錯(cuò)了,最重要的是邏輯上的錯(cuò)誤,一般電腦不容易發(fā)現(xiàn)。所以更對(duì)程序仔細(xì)的檢查。經(jīng)認(rèn)真修改之后重新保存文件。4.3 錯(cuò)誤原因分析4.3.1 缺少變量定義,定義
27、位置不正確由于該程序相對(duì)來(lái)講稍有些長(zhǎng),前后有些變量不容易聯(lián)系起來(lái),但是在錯(cuò)誤信息的提示下一般還是很容易找到,不過(guò)需要注意的是在定義的時(shí)候有些函數(shù)使用同樣的變量名而表示不同的作用,因而使用要很小心,定義及定義的位置特別留意。為減少這樣的錯(cuò)誤我后來(lái)還是用不同的變來(lái)名來(lái)表示,結(jié)果引起的那些錯(cuò)誤解決了。4.3.2 語(yǔ)法錯(cuò)誤大多的語(yǔ)法錯(cuò)誤在通過(guò)書(shū)本參考下能夠修改。主要是平時(shí)缺乏鍛煉、不太注意而產(chǎn)生的。如沒(méi)有注意具體數(shù)據(jù)使用是有一定的范圍限定;過(guò)分重視分號(hào)的重要性而在for、if、while語(yǔ)句中畫(huà)蛇添足加分號(hào)。4.3.3 注釋的位置程序設(shè)計(jì)中在注釋的時(shí)候不能同我們平常寫(xiě)字一樣隨心所欲,我們應(yīng)該注意注釋的
28、格式。注釋中不能含有C語(yǔ)言可執(zhí)行的語(yǔ)句。4.3.4 邏輯錯(cuò)誤編譯、連接的成功并不意味著程序的最終成功,邏輯上的錯(cuò)誤機(jī)器不易檢查出來(lái),這時(shí)需要多數(shù)據(jù)結(jié)果進(jìn)行分析。這種錯(cuò)誤的查找是最難的,需要有相當(dāng)?shù)哪托暮图?xì)心去把問(wèn)題找出來(lái),這也是本次程序編輯過(guò)程中碰到的最大的難題。往往運(yùn)行之后得不到令人滿意的結(jié)果。此時(shí)解決的方法一則用“分段檢查”的方法,在程序的不同位置設(shè)幾個(gè)printf函數(shù)語(yǔ)句,輸出有關(guān)變量的值,逐段往下檢查,對(duì)檢查出的錯(cuò)誤進(jìn)行修改,當(dāng)調(diào)試完畢將設(shè)置的printf都刪去,若在程序中找不到問(wèn)題,則再來(lái)考慮算法是否邏輯嚴(yán)謹(jǐn),再進(jìn)行修改,如此循環(huán)往復(fù),直到最后程序運(yùn)行成功。在本次程序編輯過(guò)程中,我就
29、是這樣處理這個(gè)問(wèn)題的。所以到最后我找到了錯(cuò)誤,及時(shí)改正,終于把程序完成了,一切功能顯示正常。在邏輯上的錯(cuò)誤,主要就是算法中出現(xiàn)的問(wèn)題,本程序中的算法有點(diǎn)復(fù)雜,在表達(dá)式轉(zhuǎn)換成后綴表達(dá)式的過(guò)程中就出現(xiàn)了很多的錯(cuò)誤。這里舉出一個(gè)簡(jiǎn)單的錯(cuò)誤,由于本程序在寫(xiě)的時(shí)候,定義了derror=1234567在程序中就不能出現(xiàn)這個(gè)計(jì)算結(jié)果,雖然它超過(guò)了本程序的能處理的范圍,可是其結(jié)果還是1234567,故返回主函數(shù)時(shí),在if (change(p,q)=1) k=jisuan(q); if(k=derror)cout<<"" else cout<<"計(jì)算結(jié)果為:
30、"<<k<<endl;這里就會(huì)出錯(cuò)。導(dǎo)致圖中的錯(cuò)誤。解決辦法,這里我對(duì)這中情況沒(méi)有做特殊的處理。應(yīng)為在實(shí)際的運(yùn)算過(guò)程中,很少有1234567這個(gè)結(jié)果出現(xiàn),幾乎是不出現(xiàn)的。如何去定義這個(gè)數(shù),一直是個(gè)問(wèn)題。本程序的,在定義的時(shí)用了兩個(gè)數(shù)組,故其空間復(fù)雜度是n,在算法上,這里我用了一個(gè)死循環(huán),當(dāng)輸入不為0時(shí),會(huì)一直運(yùn)行。所以只討論運(yùn)行一次的時(shí)間復(fù)雜度。在轉(zhuǎn)換的函數(shù)中,有個(gè)while()循環(huán),這里的復(fù)雜度是n,而在這個(gè)循環(huán)里,還存在while()循環(huán),故其時(shí)間復(fù)雜度是n的平方。在計(jì)算函數(shù)中,其復(fù)雜度也是n的平方。故可知本程序的時(shí)間復(fù)雜度是n平方。4.4調(diào)試結(jié)果4.4.
31、1普通計(jì)算圖4.4.2Abs函數(shù)計(jì)算圖4.4.3Aqrt函數(shù)計(jì)算圖4.4.4嵌套計(jì)算圖4.4.5輸入錯(cuò)誤提示圖4.4.6輸入錯(cuò)誤提示圖4.4.7輸入錯(cuò)誤提示圖4.4.8結(jié)束程序圖經(jīng)過(guò)人工計(jì)算,可知以上結(jié)果是正確的第5章 總結(jié)通過(guò)兩周的課程設(shè)計(jì),我學(xué)會(huì)了如何寫(xiě)一個(gè)精簡(jiǎn)、快速、健壯的程序。一個(gè)好的程序應(yīng)該是一個(gè)所占空間小、運(yùn)行時(shí)間短、其他性能也好的程序。而要做出一個(gè)好的程序則應(yīng)該通過(guò)對(duì)算法與其數(shù)據(jù)結(jié)構(gòu)的時(shí)間復(fù)雜度和空間復(fù)雜度進(jìn)行實(shí)現(xiàn)與改進(jìn)。然而,實(shí)際上很難做到十全十美,原因是各要求有時(shí)相互抵觸,要節(jié)約算法的執(zhí)行時(shí)間往往要以犧牲更多的存儲(chǔ)空間為代價(jià):而為了節(jié)省存儲(chǔ)空間又可能要以更多的時(shí)間為代價(jià)。因此
32、,只能根據(jù)具體情況有所側(cè)重:如果程序的使用次數(shù)較少,則應(yīng)該力求算法簡(jiǎn)明易懂,而易于轉(zhuǎn)換為上機(jī)程序;如果程序反復(fù)多次使用,則應(yīng)該盡可能選用快速算法;如果解決問(wèn)題的數(shù)據(jù)量極大,機(jī)器的內(nèi)存空間較小,則在編寫(xiě)算法時(shí)應(yīng)該考慮如何節(jié)省空間。 本次課程設(shè)計(jì)培養(yǎng)了了我們獨(dú)立思考的能力,提高了我們的動(dòng)手操作水平。在具體設(shè)計(jì)操作中,我們鞏固了本學(xué)期所學(xué)的數(shù)據(jù)結(jié)構(gòu)與算法的理論知識(shí),進(jìn)一步提高了自己的編程能力。這也是課程設(shè)計(jì)的最終目的所在。通過(guò)實(shí)際操作,開(kāi)發(fā)了自己的邏輯思維能力,培養(yǎng)了分析問(wèn)題、解決問(wèn)題的能力。 但在程序設(shè)計(jì)的過(guò)程中我也深刻的感受到自己實(shí)力的不足,無(wú)法靈活的運(yùn)用各種工具和函數(shù),對(duì)于課程所講的東西也無(wú)法
33、在脫離課本的情況中完成,我意識(shí)到自己在今后的學(xué)習(xí)生活中,一定要勤于思考,扎實(shí)掌握理論知識(shí),靈活運(yùn)用課上所學(xué)的東西,做一個(gè)優(yōu)秀的程序員。參考文獻(xiàn)1 謝希仁. 計(jì)算機(jī)網(wǎng)絡(luò)(第五版)M. 北京:電子工業(yè)出版社,2008年2月2 胡小強(qiáng) 計(jì)算機(jī)網(wǎng)絡(luò)M 北京:北京郵電大學(xué)出版社2005年1月3 李麗娟 C語(yǔ)言程序設(shè)計(jì)教程(第2版)M,人民郵電出版社 2009年3月4 王昆侖,李紅. 數(shù)據(jù)結(jié)構(gòu)與算法. 北京:中國(guó)鐵道出版社,2006年5月。5 鄭莉 ,董淵,張瑞豐 c+語(yǔ)言程序設(shè)計(jì) 北京:清華大學(xué)出版社,2004附錄(源程序代碼)#include "iostream"#include
34、"math.h"#include "string"#include "stdlib.h"#include "windows.h"#define derror 1234567#define Maxlen 400using namespace std; struct char dataMaxlen; int top; optr;/定義運(yùn)算符棧,并定義全局變量struct double dataMaxlen; int top; opnd;/定義操作數(shù)棧,并定義全局變量void main() char p400,q400;
35、 double k;void meun(); /聲明菜單函數(shù)int change(char *p, char q);/聲明轉(zhuǎn)換函數(shù)double jisuan(char *q);/聲明計(jì)算函數(shù)meun();for(;) /循環(huán)執(zhí)行 cout <<"請(qǐng)輸入:" cin>>p; if (strcmp(p,"0")=0) return; if (change(p,q)=1) k=jisuan(q); if(k=derror)cout<<"" else cout<<"計(jì)算結(jié)果為:&quo
36、t;<<k<<endl;system("pause"); /控制輸出格式system("cls"); meun(); void meun()system("color 0a"); cout<<"tt *"<<endl; cout<<" 歡迎使用本計(jì)算器"<<endl; cout<<"tt *"<<endl;cout<<endl;cout<<"按0結(jié)
37、束本程序"<<endl;int change(char *p, char q) /將算術(shù)表達(dá)式p轉(zhuǎn)換成表達(dá)式后綴表達(dá)式q int i=0; /i作為q的下標(biāo) int dh=1; /dh=1表示是負(fù)號(hào) optr.top=-1; /初始化運(yùn)算符棧 while (*p!='0') /p表達(dá)式未掃描完時(shí)循環(huán) switch(*p) /判斷各種情況,并做相應(yīng)的處理 case '(': optr.top+;optr.dataoptr.top=*p; dh=1;p+;break; case ')': while (optr.dataoptr
38、.top!='(') qi=optr.dataoptr.top; optr.top-; i+; optr.top-; p+; dh=0; break; case '+': case '-': if (dh=1) / +,-是正負(fù)號(hào) if (*p='-') optr.top+;optr.dataoptr.top='' p+; break; while (optr.top!=-1 && optr.dataoptr.top!='(') qi=optr.dataoptr.top; optr.
39、top-; i+; optr.top+;optr.dataoptr.top=*p; p+; dh=0; break; case '*': case '/': while (optr.dataoptr.top='*' | optr.dataoptr.top='/'| optr.dataoptr.top='s') qi=optr.dataoptr.top; optr.top-; i+; optr.top+;optr.dataoptr.top=*p; p+; dh=0; break; case '': w
40、hile (optr.dataoptr.top='') qi=optr.dataoptr.top; optr.top-;i+; optr.top+;optr.dataoptr.top=*p;p+;dh=0;break; case '%': while (optr.dataoptr.top='%') qi=optr.dataoptr.top; optr.top-;i+; optr.top+;optr.dataoptr.top=*p;p+;dh=0;break; case ' ': p+; break; /消除空格 case '
41、;s': case 'S': if(*(p+1)='i' | *(p+1)='I')&&(*(p+2)='n' | *(p+2)='N') optr.top+;optr.dataoptr.top='s' p+=3; dh=0; break; else if(*(p+1)='q'|*(p+1)='Q')&&(*(p+2)='r'| *(p+2)='R')&&(*(p+3)='
42、t' | *(p+3)='T') optr.top+;optr.dataoptr.top='q' p+=4;dh=0; break; else cout<<endl<<"有錯(cuò)誤符號(hào)"<<endl; return derror; case 'c': case 'C': if(*(p+1)='o' | *(p+1)='O')&&(*(p+2)='s' | *(p+2)='S') optr.to
43、p+;optr.dataoptr.top='c' p+=3; dh=0; break; else cout<<endl<<"有錯(cuò)誤符號(hào)"<<endl; return derror; case 'T': case 't':if(*(p+1)='a'| *(p+1)='A')&&(*(p+2)='n' | *(p+2)='N') optr.top+;optr.dataoptr.top='t' p+=3
44、;dh=0; break; else cout<<endl<<"有錯(cuò)誤符號(hào)"<<endl; return derror; case 'e': case 'E':if(*(p+1)='x'| *(p+1)='X')&&(*(p+2)='p' | *(p+2)='P') optr.top+;optr.dataoptr.top='e' p+=3;dh=0; break; else cout<<endl<
45、;<"有錯(cuò)誤符號(hào)"<<endl; return derror; case 'a': case 'A': if(*(p+1)='b'| *(p+1)='B')&&(*(p+2)='s' | *(p+2)='S') optr.top+;optr.dataoptr.top='a' p+=3;dh=0; break; else cout<<endl<<"有錯(cuò)誤符號(hào)"<<endl; r
46、eturn derror; default: while (*p>='0' && *p<='9') /判斷是否為數(shù)字 qi=*p;i+; p+; if (*p='.') qi='.' i+; p+; while (*p>='0' && *p<='9') qi=*p;i+; p+; qi='#' i+; dh=0;/用#標(biāo)識(shí)一個(gè)數(shù)值串結(jié)束 while (optr.top!=-1) /此時(shí)p掃描完畢,棧不空時(shí)循環(huán) qi=optr.d
47、ataoptr.top; i+; optr.top-; qi='0' /給q表達(dá)式添加結(jié)束標(biāo)識(shí) return 1;double jisuan(char *q) /計(jì)算后綴表達(dá)式的值 double d,x; opnd.top=-1; /初始化操作數(shù)棧 while (*q!='0') /q字符串未掃描完時(shí)循環(huán) switch (*q) /判斷各種情況,并做相應(yīng)的運(yùn)算,并入棧 case '+':opnd.dataopnd.top-1=opnd.dataopnd.top-1+opnd.dataopnd.top; opnd.top-;break; case '-':opnd.dataopnd.top-1=opnd.dataopnd.top-1-opnd.dataopnd.top; opnd.top-;break; case '*':opnd.dataopnd.top-1=opnd.dataopnd.top-1*opnd.dataopnd.top; opnd.top-;break; case '/': if (opnd.dataopnd.top!=0) opnd.dataopnd.top-1=opnd.
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度特色甜品餐飲店員工勞動(dòng)聘請(qǐng)協(xié)議
- 2025至2030年中國(guó)電信設(shè)備裝置用通信電纜數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025至2030年中國(guó)甘氨酸鈉數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 知識(shí)產(chǎn)權(quán)流程優(yōu)化從申請(qǐng)到維護(hù)的全方位管理
- 科技創(chuàng)新在商業(yè)領(lǐng)域的機(jī)遇與挑戰(zhàn)
- 2025年中儲(chǔ)糧儲(chǔ)運(yùn)有限公司校園招聘吉林省崗位(9人)筆試參考題庫(kù)附帶答案詳解
- 有關(guān)師德師風(fēng)自查報(bào)告
- 2025至2030年中國(guó)玉米胚芽粕數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025至2030年中國(guó)濫用藥品測(cè)試劑數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 社會(huì)管理中磁性技術(shù)的應(yīng)用與發(fā)展趨勢(shì)分析
- 大樹(shù)移栽合同范本
- 柔性印刷技術(shù)探索-深度研究
- 最終版附件1:“跨學(xué)科主題學(xué)習(xí)”教學(xué)設(shè)計(jì)(2025年版)
- 4.2依法履行義務(wù) 教案 -2024-2025學(xué)年統(tǒng)編版道德與法治八年級(jí)下冊(cè)
- NB/T 11526-2024煤礦微震監(jiān)測(cè)系統(tǒng)通用技術(shù)條件
- 2025年福建長(zhǎng)汀金龍稀土有限公司招聘筆試參考題庫(kù)含答案解析
- (2024)云南省公務(wù)員考試《行測(cè)》真題及答案解析
- 2022年“正確認(rèn)識(shí)新疆四史”《民族團(tuán)結(jié)鑄牢中華民族共同體意識(shí)》全文解讀
- 公司安全事故隱患內(nèi)部舉報(bào)、報(bào)告獎(jiǎng)勵(lì)制度
- 靜脈治療護(hù)理技術(shù)操作標(biāo)準(zhǔn)解讀
- 大學(xué)生創(chuàng)新創(chuàng)業(yè)基礎(chǔ)教程(高校創(chuàng)新創(chuàng)業(yè)教育課程)全套教學(xué)課件
評(píng)論
0/150
提交評(píng)論