C 語(yǔ)言PPT譚浩強(qiáng)教材配套版第16章.ppt_第1頁(yè)
C 語(yǔ)言PPT譚浩強(qiáng)教材配套版第16章.ppt_第2頁(yè)
C 語(yǔ)言PPT譚浩強(qiáng)教材配套版第16章.ppt_第3頁(yè)
C 語(yǔ)言PPT譚浩強(qiáng)教材配套版第16章.ppt_第4頁(yè)
C 語(yǔ)言PPT譚浩強(qiáng)教材配套版第16章.ppt_第5頁(yè)
已閱讀5頁(yè),還剩55頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第16章常見錯(cuò)誤和程序調(diào)試 16 1常見錯(cuò)誤分析16 2程序調(diào)試 要真正學(xué)好C 用好C并不容易 靈活 固然是好事 但也使人難以掌握 尤其是初學(xué)者往往出了錯(cuò)還不知怎么回事 C編譯程序?qū)φZ(yǔ)法的檢查不如其他高級(jí)語(yǔ)言那樣嚴(yán)格 這是為了給程序人員留下 靈活 的余地 因此 往往要由程序設(shè)計(jì)者自己設(shè)法保證程序的正確性 調(diào)試一個(gè)C程序要比調(diào)試一個(gè)PASCAL或FORTRAN程序更困難一些 需要不斷積累經(jīng)驗(yàn) 提高程序設(shè)計(jì)和調(diào)試程序的水平 C語(yǔ)言有些語(yǔ)法規(guī)定和其他高級(jí)語(yǔ)言不同 學(xué)習(xí)過(guò)其他高級(jí)語(yǔ)言的讀者往往按照使用其他高級(jí)語(yǔ)言的習(xí)慣來(lái)寫C程序 這也是出錯(cuò)的一個(gè)原因 16 1常見錯(cuò)誤分析下面將初學(xué)者在學(xué)習(xí)和使用C語(yǔ)言 不包括C 時(shí)容易犯的錯(cuò)誤列舉出來(lái) 以起提醒的作用 這些內(nèi)容在以前各章中大多已談到 為便于查閱 在本章中集中列舉 供初學(xué)者參考 以此為鑒 1 忘記定義變量 如 main x 3 y 6 printf d n x y C要求對(duì)程序中用到的每一個(gè)變量都必須定義其類型 上面程序中沒(méi)有對(duì)x y進(jìn)行定義 應(yīng)在函數(shù)體的開頭加intx y 這是學(xué)過(guò)BASIC和FORTRAN語(yǔ)言的讀者寫C程序時(shí)常見的一個(gè)錯(cuò)誤 在BASIC語(yǔ)言中 可以不必先定義變量類型就可直接使用 在FORTRAN中 未經(jīng)定義類型的變量按隱含的I N規(guī)則決定其類型 而C語(yǔ)言則要求對(duì)用到的每一個(gè)變量都要在本函數(shù)中定義 除非已定義為外部變量 2 輸入輸出的數(shù)據(jù)的類型與所用格式說(shuō)明符不一致 例如 若a已定義為整型 b已定義為實(shí)型 a 3 b 4 5 printf f d n a b 編譯時(shí)不給出出錯(cuò)信息 但運(yùn)行結(jié)果將與原意不符 輸出為0 00000016402它們并不是按照賦值的規(guī)則進(jìn)行轉(zhuǎn)換 如把4 5轉(zhuǎn)換成4 而是將數(shù)據(jù)在存儲(chǔ)單元中的形式按格式符的要求組織輸出 如b占4個(gè)字節(jié) 只把最后兩個(gè)字節(jié)中的數(shù)據(jù)按 d 作為整數(shù)輸出 3 未注意int型數(shù)據(jù)的數(shù)值范圍 一般微型計(jì)算機(jī)上使用的C編譯系統(tǒng) 對(duì)一個(gè)整型數(shù)據(jù)分配兩個(gè)字節(jié) 因此一個(gè)整數(shù)的范圍為 215 215 1 即 32768 32767 常見這樣的程序段 intnum num 89101 printf d num 得到的卻是23565 原因是89101已超過(guò)32767 兩個(gè)字節(jié)容納不下89101 則將高位截去 見圖16 1 即將超過(guò)低16位的數(shù)截去 即將89101減去216 即16位二進(jìn)制所形成的模 89101 65536 23565 圖16 1有時(shí)還會(huì)出現(xiàn)負(fù)數(shù) 例如num 196607 輸出得 1 因?yàn)?96607的二進(jìn)制形式為00000000000000101111111111111111去掉高位10 低16位的值是 1 1的補(bǔ)碼是 1111111111111111 對(duì)于超過(guò)整個(gè)范圍的數(shù) 要用long型 即改為longintnum num 89101 printf ld num 請(qǐng)注意 如果只定義num為long型 而在輸出時(shí)仍用 d 說(shuō)明符 仍會(huì)出現(xiàn)以上錯(cuò)誤 4 輸入變量時(shí)忘記使用地址符 如 scanf d d a b 這是許多初學(xué)者剛學(xué)習(xí)C語(yǔ)言時(shí)一個(gè)常見的疏忽 或者說(shuō)是習(xí)慣性的錯(cuò)誤 因?yàn)樵谄渌Z(yǔ)言中在輸入時(shí)只需寫出變量名即可 而C語(yǔ)言要求指明 向哪個(gè)地址標(biāo)識(shí)的單元送值 應(yīng)寫成scanf d d 5 輸入時(shí)數(shù)據(jù)的組織與要求不符 用scanf函數(shù)輸入數(shù)據(jù) 應(yīng)注意如何組織輸入 數(shù)據(jù) 假如有以下scanf函數(shù) scanf d d 對(duì)scanf函數(shù)中格式字符串中除了格式說(shuō)明符外 對(duì)其他字符必須按原樣輸入 因此 應(yīng)按以下方法輸入 3 4 此時(shí)如果用 34 反而錯(cuò)了 還應(yīng)注意 不能企圖用scanf inputa scanf d d 若為零作為假 如果a的值為3 b的值為4 a b 按原意不應(yīng)輸出 aequaltob 而現(xiàn)在先將b的值賦給a a也為4 賦值表達(dá)式的值為4 if語(yǔ)句中的表達(dá)式值為真 非零 因此輸出 aequaltob 這種錯(cuò)誤在編譯時(shí)是檢查不出來(lái)的 但運(yùn)行結(jié)果往往是錯(cuò)的 而且由于習(xí)慣的影響 程序設(shè)計(jì)者自己往往也不易發(fā)覺(jué) 7 語(yǔ)句后面漏分號(hào) C語(yǔ)言規(guī)定語(yǔ)句末尾必須有分號(hào) 分號(hào)是C語(yǔ)句不可缺少的一部分 這也是和其他語(yǔ)言不同的 有的初學(xué)者往往忘記寫這一分號(hào) 如 a 3b 4編譯時(shí) 編譯程序在 a 3 后面未發(fā)現(xiàn)分號(hào) 就把下一行 b 4 也作為上一行的語(yǔ)句的一部分 這就出現(xiàn)語(yǔ)法錯(cuò)誤 有時(shí)編譯時(shí)指出某行有錯(cuò) 但在該行上并未發(fā)現(xiàn)錯(cuò)誤 應(yīng)該檢查上一行是否漏了分號(hào) 如果用復(fù)合語(yǔ)句 有的學(xué)過(guò)PASCAL語(yǔ)言的讀者往往漏寫最后一個(gè)語(yǔ)句的分號(hào) 如 t a a b b t 在PASCAL中分號(hào)是兩個(gè)語(yǔ)句間的分隔符而不是語(yǔ)句的一部分 而在C中 沒(méi)有分號(hào)的就不是語(yǔ)句 8 在不該加分號(hào)的地方加了分號(hào) 例如 if a b printf aislargerthanb n 本意為當(dāng)a b時(shí)輸出 aislargerthanb 的信息 但由于在if a b 后加了分號(hào) 因此if語(yǔ)句到此結(jié)束 即當(dāng) a b 為真時(shí) 執(zhí)行一個(gè)空語(yǔ)句 本來(lái)想a b時(shí)不輸出上述信息 但現(xiàn)在printf函數(shù)語(yǔ)句并不從屬于if語(yǔ)句 而是與if語(yǔ)句平行的語(yǔ)句 不論 a b還是a b 都輸出 aislargerthanb 又如 for i 0 i 10 i scanf d 本意為先后輸入10個(gè)數(shù) 每輸入一個(gè)數(shù)后輸出它的平方值 由于在for 后加了一個(gè)分號(hào) 使循環(huán)體變成了空語(yǔ)句 只能輸入一個(gè)整數(shù)并輸出它的平方值 總之 在if for while語(yǔ)句中 不要畫蛇添足多加分號(hào) 9 對(duì)應(yīng)該有花括弧的復(fù)合語(yǔ)句 忘記加花括弧 如 sum 0 i 1 while i 100 sum sum i i 本意是實(shí)現(xiàn)1 2 100 即 i 但上面的語(yǔ)句只是重復(fù)了sum 1的操作 而且循環(huán)永不終止 因?yàn)閕的值始終沒(méi)有改變 錯(cuò)誤在于沒(méi)有寫成復(fù)合語(yǔ)句形式 因此while語(yǔ)句的范圍到其后第一個(gè)分號(hào)為止 語(yǔ)句 i 不屬于循環(huán)體范圍之內(nèi) 應(yīng)改 100i 0 為while i 100 sum sum i i 10 括弧不配對(duì) 當(dāng)一個(gè)語(yǔ)句中使用多層括弧時(shí)常出現(xiàn)這類錯(cuò)誤 純屬粗心所致 如 while c getchar putchar c 少了一個(gè)右括弧 11 在用標(biāo)識(shí)符時(shí) 忘記了大寫字母和小寫字母的區(qū)別 例如 main inta b c a 2 b 3 C A B printf d d A B C 編譯時(shí)出錯(cuò) 編譯程序把a(bǔ)和A認(rèn)作是兩個(gè)不同的變量名處理 同樣b和B c和C都分別代表兩個(gè)不同的變量 12 引用數(shù)組元素時(shí)誤用了圓括弧 如 main inti a 10 for i 0 i 10 i scanf d C語(yǔ)言中對(duì)數(shù)組的定義或引用數(shù)組元素時(shí)必須用方括弧 13 在定義數(shù)組時(shí) 將定義的 元素個(gè)數(shù) 誤認(rèn)為是 可使用的最大下標(biāo)值 main inta 10 1 2 3 4 5 6 7 8 9 10 inti for i 1 i 10 i printf d a i 想輸出a 1 到a 10 但一些初學(xué)者常犯的錯(cuò)誤 C語(yǔ)言規(guī)定定義時(shí)用a 10 表示a數(shù)組有10個(gè)元素 而不是可以用的最大下標(biāo)值為10 數(shù)組只包括a 0 到a 9 10個(gè)元素 因此用a 10 就超出a數(shù)組的范圍了 14 對(duì)二維或多維數(shù)組的定義和引用的方法不對(duì) main inta 5 4 printf d a 1 2 2 2 對(duì)二維數(shù)組和多維數(shù)組在定義和引用時(shí)必須將每一維的數(shù)據(jù)分別用方括弧括起來(lái) 上面a 5 4 應(yīng)改為a 5 4 a 1 2 2 2 應(yīng)改為a 1 2 2 2 根據(jù)C的語(yǔ)法規(guī)則 在一個(gè)方括弧中的是一個(gè)維的下標(biāo)表達(dá)式 a 1 2 2 2 中方括弧中的 1 2 2 2 是一個(gè)逗號(hào)表達(dá)式 它的值是第二個(gè)數(shù)值表達(dá)式的值 即2 2的值為4 所以a 1 2 2 2 相當(dāng)于a 4 而a 4 是a數(shù)組的第4行的首地址 因此執(zhí)行printf函數(shù)輸出的結(jié)果并不是a 3 4 的值 而是a數(shù)組第4行的首地址 15 誤以為數(shù)組名代表數(shù)組中全部元素 例如 main inta 4 1 3 5 7 printf d d d d n a 企圖用數(shù)組名代表全部元素 在C語(yǔ)言中 數(shù)組名代表數(shù)組首地址 不能通過(guò)數(shù)組名輸出4個(gè)整數(shù) 16 混淆字符數(shù)組與字符指針的區(qū)別 main charstr 4 str Computerandc printf s n str 編譯出錯(cuò) str是數(shù)組名 代表數(shù)組首地址 在編譯時(shí)對(duì)str數(shù)組分配了一段內(nèi)存單元 因此在程序運(yùn)行期間str是一個(gè)常量 不能再被賦值 因此 str Computerandc 是錯(cuò)誤的 如果把 charstr 4 改成 char str 則程序正確 此時(shí)str是指向字符數(shù)據(jù)的指針變量 str Computerandc 是合法的 它將字符串的首地址賦給指針變量str 然后在printf函數(shù)語(yǔ)句中輸出字符串 Computerandc 因此應(yīng)當(dāng)弄清楚字符數(shù)組與字符指針變量用法的區(qū)別 17 在引用指針變量之前沒(méi)有對(duì)它賦予確定的值 main char p scanf s p 沒(méi)有給指針變量p賦值就引用它 編譯時(shí)給出警告信息 應(yīng)當(dāng)改為char p c 20 p c scanf s p 即先根據(jù)需要定義一個(gè)大小合適的字符數(shù)組c 然后將c數(shù)組的首地址賦給指針變量p 此時(shí)p有確定的值 指向數(shù)組c 再執(zhí)行scanf函數(shù)就沒(méi)有問(wèn)題了 把從鍵盤輸入的字符串存放到字符數(shù)組c中 18 switch語(yǔ)句的各分支中漏寫break語(yǔ)句 例如 switch score case5 printf erygood case4 printf Good case3 printf Pass case2 printf Fail defult printf dataerror 上述switch語(yǔ)句的作用是希望根據(jù)score 成績(jī) 打印出評(píng)語(yǔ) 但當(dāng)score的值為5時(shí) 輸出為 eryGood Good Pass Fail dataerror 原因是漏寫了break語(yǔ)句 case只起標(biāo)號(hào)的作用 而不起判斷作用 因此在執(zhí)行完第一個(gè)printf函數(shù)語(yǔ)句后接著執(zhí)行第2 3 4 5個(gè)printf函數(shù)語(yǔ)句 應(yīng)改為switch score case5 printf erygood break case4 printf Good break case3 printf Pass break case2 print Fail break defult print dataerror 19 混淆字符和字符串的表示形式 charsex sex M sex是字符變量 只能存放一個(gè)字符 而字符常量的形式是用單引號(hào)括起來(lái)的 應(yīng)改為sex M M 是用雙引號(hào)括起來(lái)的字符串 它包括兩個(gè)字符 M 和 0 無(wú)法存放到字符變量sex中 20 使用自加 和自減 運(yùn)算符時(shí)出的錯(cuò)誤 例如 main int p a 5 1 3 5 7 9 p a printf d p 不少人認(rèn)為 p 的作用是先使p加1 即指向第1個(gè)元素a 1 處 然后輸出第一個(gè)元素a 1 的值3 其實(shí)應(yīng)該是先執(zhí)行p 而p 的作用是先用p的原值 用完后使p加1 p的原值指向數(shù)組a的第0個(gè)元素a 0 因此 p就是第0個(gè)元素a 0 的值1 結(jié)論是先輸出a 0 的值 然后再使p加1 如果是 p 則先使p指向a 1 然后輸出a 1 的值 21 有人習(xí)慣用傳統(tǒng)的方式對(duì)函數(shù)形參進(jìn)行聲明 但卻把對(duì)函數(shù)的形參和函數(shù)中的局部變量混在一起定義 如 max x y intx y x y x y return 應(yīng)改為max x y intx y int x y x y return 22 所調(diào)用的函數(shù)在調(diào)用語(yǔ)句之后才定義 而又在調(diào)用前未加說(shuō)明 main floatx y x 3 5 y 7 6 max x y printf f n floatmax floatx floaty return x y x y 這個(gè)程序乍看起來(lái)沒(méi)有什么問(wèn)題 但在編譯時(shí)有出錯(cuò)信息 原因是max函數(shù)是實(shí)型的 而且在main函數(shù)之后才定義 也就是max函數(shù)的定義位置在main函數(shù)中的調(diào)用max函數(shù)之后 改錯(cuò)的方法可以用以下二者之一 在main函數(shù)中增加一個(gè)對(duì)max函數(shù)的聲明 即函數(shù)的原型 main floatmax float float 聲明將要用到的max函數(shù)為實(shí)型 floatx y x 3 5 y 7 6 max x y printf f n 將max函數(shù)的定義位置調(diào)到main函數(shù)之前 即 floatmax floatx floaty return x y x y main floatx y x 3 5 y 7 6 max x y printf f n 這樣 編譯時(shí)不會(huì)出錯(cuò) 程序運(yùn)行結(jié)果是正確的 23 誤認(rèn)為形參值的改變會(huì)影響實(shí)參的值 main inta b a 3 b 4 swap a b printf d d n a b swap intx inty intt t x x y y t 原意是通過(guò)調(diào)用swap函數(shù)使a和b的值對(duì)換 然后在main函數(shù)中輸出已對(duì)換了值的a和b 但是這樣的程序是達(dá)不到目的的 因?yàn)閤和y的值的變化是不傳送回實(shí)參a和b的 main函數(shù)中的a和b的值并未改變 如果想從函數(shù)得到一個(gè)以上的變化了的值 應(yīng)該用指針變量 用指針變量作函數(shù)參數(shù) 使指針變量所指向的變量的值發(fā)生變化 此時(shí)變量的值改變了 主調(diào)函數(shù)中可以利用這些已改變的值 如 main inta b p1 p2 a 3 b 4 p1 24 函數(shù)的實(shí)參和形參類型不一致 main inta 3 b 4 c fun a b fun floatx floaty 實(shí)參a b為整型 形參x y為實(shí)型 a和b的值傳遞給x和y時(shí) x和y的值并非3和4 C要求實(shí)參與形參的類型一致 如果在main函數(shù)中對(duì)fun作原型 聲明 fun float float 程序可以正常運(yùn)行 此時(shí) 按不同類型間的賦值的規(guī)則處理 在虛實(shí)結(jié)合后x 3 0 y 4 0 也可以將fun函數(shù)的位置調(diào)到main函數(shù)之前 也可獲正確結(jié)果 25 不同類型的指針混用 main inti 3 p1 floata 1 5 p2 p1 p2 p1 printf d d n p1 p2 企圖使p2也指向i 但p2是指向?qū)嵭妥兞康闹羔?不能指向整型變量 指向不同類型的指針間的賦值必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換 如 p2 float p1 作用是先將p1的值轉(zhuǎn)換成指向?qū)嵭偷闹羔?然后再賦給p2 這種情況在C程序中是常見的 例如 用malloc函數(shù)開辟內(nèi)存單元 函數(shù)返回的是指向被分配內(nèi)存空間的void 類型的指針 而人們希望開辟的是 存放一個(gè)結(jié)構(gòu)體變量值的存儲(chǔ)單元 要求得到指向該結(jié)構(gòu)體變量的指針 可以進(jìn)行如下的類型轉(zhuǎn)換 structstudent intnum charname 20 floatscore structstudentstudent1 p p structstudent malloc LEN p是指向structstudent結(jié)構(gòu)體類型數(shù)據(jù)的指針 將malloc函數(shù)返回的void 類型指針轉(zhuǎn)換成指向structstudent類型變量的指針 26 沒(méi)有注意函數(shù)參數(shù)的求值順序 例如有以下語(yǔ)句 i 3 printf d d d n i i i 許多人認(rèn)為輸出必然是3 4 5實(shí)際不盡然 在TurboC和其他一些C系統(tǒng)中輸出是5 5 4 因?yàn)檫@些系統(tǒng)是采取自右至左的順序求函數(shù)參數(shù)的值 先求出最右面一個(gè)參數(shù) i 的值為4 再求出第2個(gè)參數(shù) i 的值為5 最后求出最左面的參數(shù) i 的值5 C標(biāo)準(zhǔn)沒(méi)有具體規(guī)定函數(shù)參數(shù)求值的順序是自左而右還是自右而左 但每個(gè)C編譯程序都有自己的順序 在有些情況下 從左到右求解和從右到左求解的結(jié)果是相同的 例如fun1 a b b c c a fun1是一個(gè)函數(shù)名 3個(gè)實(shí)參表達(dá)式a b b c c a 在一般情況下 自左至右地求這3個(gè)表達(dá)式的值和自右至左地求它們的值是一樣的 但在前面舉的例子 是不相同的 因此 建議最好不用會(huì)引起二義性的用法 如果在上例中 希望輸出 3 4 5 時(shí) 可以改用i 3 j i 1 k j 1 printf d d d n i j k 27 混淆數(shù)組名與指針變量的區(qū)別 main inti a 5 for i 0 i 5 i scanf d a 企圖通過(guò)a的改變使指針下移 每次指向欲輸入數(shù)據(jù)的數(shù)組元素 它的錯(cuò)誤在于不了解數(shù)組名代表數(shù)組首地址 它的值是不能改變的 用a 是錯(cuò)誤的 應(yīng)當(dāng)用指針變量來(lái)指向各數(shù)組元素 即 inti a 5 p p a for i 0 i 5 i scanf d p 或inta 5 p for p a p a 5 p scanf d p 28 混淆結(jié)構(gòu)體類型與結(jié)構(gòu)體變量的區(qū)別 對(duì)一個(gè)結(jié)構(gòu)體類型賦值 structworker longintnum charname 20 charsex intage worker num 187045 strcpy worker name ZhangFun worker sex M worker age 18 這是錯(cuò)誤的 只能對(duì)變量賦值而不能對(duì)類型賦值 上面只定義了structworker類型而未定義變量 應(yīng)改為structworker longintnum charname 20 charsex intage structworkerworker 1 worker 1 num 187045 strcpy worker 1 name ZhangFun worker 1 sex M worker 1 age 18 今定義了結(jié)構(gòu)體變量worker 1 并對(duì)其中的各成員賦值 29 使用文件時(shí)忘記打開 或打開方式與使用情況不匹配 例如 對(duì)文件的讀寫 用只讀方式打開 卻企圖向 該文件輸出數(shù)據(jù) 例如 if fp fopen test r NULL printf cannotopenthisfile n exit 0 ch fgetc fp while ch ch ch 4 fputc ch fp ch fget fp 對(duì)以 r 方式 只讀方式 打開的文件 進(jìn)行既讀又寫的操作 顯然是不行的 此外 有的程序常忘記關(guān)閉文件 雖然系統(tǒng)會(huì)自動(dòng)關(guān)閉所用文件 但可能會(huì)丟失數(shù)據(jù) 因此必須在用完文件后關(guān)閉它 以上只是列舉了一些初學(xué)者常出現(xiàn)的錯(cuò)誤 這些錯(cuò)誤大多是對(duì)于C語(yǔ)法不熟悉之故 對(duì)C語(yǔ)言使用多了 比較熟練了 犯這些錯(cuò)誤自然就會(huì)減少了 在深入使用C語(yǔ)言后 還會(huì)出現(xiàn)其他一些更深入 更隱蔽的錯(cuò)誤 程序出錯(cuò)有三種情況 語(yǔ)法錯(cuò)誤 指違背了C語(yǔ)法的規(guī)定 對(duì)這類錯(cuò)誤 編譯程序一般能給出 出錯(cuò)信息 并且告訴你在哪一行出錯(cuò) 只要細(xì)心 是可以很快發(fā)現(xiàn)并排除的 邏輯錯(cuò)誤 程序并無(wú)違背語(yǔ)法規(guī)則 但程序執(zhí)行結(jié)果與原意不符 這是由于程序設(shè)計(jì)人員設(shè)計(jì)的算法有錯(cuò)或編寫程序有錯(cuò) 通知給系統(tǒng)的指令與解題的原意不相同 即出現(xiàn)了邏輯上的混亂 例如 前面第9條錯(cuò)誤 sum 0 i 1 while i 100 sum sum i i 語(yǔ)法并無(wú)錯(cuò)誤 但while語(yǔ)句通知給系統(tǒng)的信息是當(dāng)i 100時(shí) 執(zhí)行 sum sum i C系統(tǒng)無(wú)法辨別程序中這個(gè)語(yǔ)句是否符合作者的原意 而只能忠實(shí)地執(zhí)行這一指令 這種錯(cuò)誤比語(yǔ)法錯(cuò)誤更難檢查 要求程序員有較豐富的經(jīng)驗(yàn) 運(yùn)行錯(cuò)誤 程序既無(wú)語(yǔ)法錯(cuò)誤 也無(wú)邏輯錯(cuò)誤 但在運(yùn)行時(shí)出現(xiàn)錯(cuò)誤甚至停止運(yùn)行 例如 inta b c scanf d d 輸入a和b的值 輸出b a的值 程序沒(méi)有錯(cuò) 但是如果輸入a的值為0 就會(huì)出現(xiàn)錯(cuò)誤 因此程序應(yīng)能適應(yīng)不同的數(shù)據(jù) 或者說(shuō)能經(jīng)受各種數(shù)據(jù)的 考驗(yàn) 具有 健壯性 寫完一個(gè)程序只能說(shuō)完成任務(wù)的一半 甚至不到一半 調(diào)試程序往往比寫程序更難 更需要精力 時(shí)間和經(jīng)驗(yàn) 常常有這樣的情況 程序花一天就寫完了 而調(diào)試程序二三天也未能完 有時(shí)一個(gè)小小的程序會(huì)出錯(cuò)五六處 而發(fā)現(xiàn)和排除一個(gè)錯(cuò)誤 有時(shí)竟需要半天 甚至更多 希望讀者通過(guò)實(shí)踐掌握調(diào)試程序的方法和技術(shù) 16 2程序調(diào)試所謂程序調(diào)試是指對(duì)程序的查錯(cuò)和排錯(cuò) 調(diào)試程序一般應(yīng)經(jīng)過(guò)以下幾個(gè)步驟 1 先進(jìn)行人工檢查 即靜態(tài)檢查 在寫好一個(gè)程序以后 不要匆匆忙忙上機(jī) 而應(yīng)對(duì)紙面上的程序進(jìn)行人工檢查 這一步是十分重要的 它能發(fā)現(xiàn)程序設(shè)計(jì)人員由于疏忽而造成的多數(shù)錯(cuò)誤 而這一步驟往往容易被人忽視 有人總希望把一切推給計(jì)算機(jī)系統(tǒng)去做 但這樣就會(huì)多占用機(jī)器時(shí)間 而且 作為一個(gè)程序人員應(yīng)當(dāng)養(yǎng)成嚴(yán)謹(jǐn)?shù)目茖W(xué)作風(fēng) 每一步都要嚴(yán)格把關(guān) 不把問(wèn)題留給后面的工序 為了更有效地進(jìn)行人工檢查 所編的程序應(yīng)注意力 求做到以下幾點(diǎn) 應(yīng)當(dāng)采用結(jié)構(gòu)化程序方法編程 以增加可讀性 盡可能多加注釋 以幫助理解每段程序的作用 在編寫復(fù)雜的程序時(shí) 不要將全部語(yǔ)句都寫在main函數(shù)中 而要多利用函數(shù) 用一個(gè)函數(shù)來(lái)實(shí)現(xiàn)一個(gè)單獨(dú)的功能 這樣既易于閱讀也便于調(diào)試 各函數(shù)之間除用參數(shù)傳遞數(shù)據(jù)這一渠道以外 數(shù)據(jù)間盡量少出現(xiàn)耦合關(guān)系 便于分別檢查和處理 2 在人工 靜態(tài) 檢查無(wú)誤后 才可以上機(jī)調(diào)試 通過(guò)上機(jī)發(fā)現(xiàn)錯(cuò)誤稱動(dòng)態(tài)檢查 在編譯時(shí)給出語(yǔ)法錯(cuò)誤的信息 包括哪一行有錯(cuò)以及錯(cuò)誤類型 可以根據(jù)提示的信息具體找出程序中出錯(cuò)之處并改正之 應(yīng)當(dāng)注意的是 有時(shí)提示的出錯(cuò)行并不是真正出錯(cuò) 的行 如果在提示出錯(cuò)的行上找不到錯(cuò)誤的話應(yīng)當(dāng)?shù)缴弦恍性僬?另外 有時(shí)提示出錯(cuò)的類型并非絕對(duì)準(zhǔn)確 由于出錯(cuò)的情況繁多而且各種錯(cuò)誤互有關(guān)聯(lián) 因此要善于分析 找出真正的錯(cuò)誤 而不要只從字面意義上死摳出錯(cuò)信息 鉆牛角尖 如果系統(tǒng)提示的出錯(cuò)信息多 應(yīng)當(dāng)從上到下逐一改正 有時(shí)顯示出一大片出錯(cuò)信息往往使人感到問(wèn)題嚴(yán)重 無(wú)從下手 其實(shí)可能只有一二個(gè)錯(cuò)誤 例如 對(duì)所用的變量未定義 編譯時(shí)就會(huì)對(duì)所有含該變量的語(yǔ)句發(fā)出出錯(cuò)信息 只要加上一個(gè)變量定義 所有錯(cuò)誤都消除了 3 在改正語(yǔ)法錯(cuò)誤 包括 錯(cuò)誤 error 和 警告 warning 后 程序經(jīng)過(guò)連接 link 就得到可 執(zhí)行的目標(biāo)程序 運(yùn)行程序 輸入程序所需數(shù)據(jù)

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論