|
┃ 寫塊 ┃ Ctrl+KW ━━━╋━━━━━━━━━╋━━━━━━━━━━━━━ ┃ 異常結(jié)束操作 ┃ Ctrl+U或Ctrl+Break ┃ 制表 ┃ Ctrl+L或Tab 其 ┃ 自動(dòng)縮進(jìn) ┃ Ctrl+OI ┃ 定界符配對(duì) ┃ Ctrl+Q[或Ctrl+Q] 它 ┃ 查找 ┃ Ctrl+QF ┃ 查找并替換 ┃ Ctrl+QA ┃ 查找標(biāo)記 ┃ Ctrl+QN ┃ 退出編輯 ┃ Ctrl+KQ ━━━┻━━━━━━━━━┻━━━━━━━━━━━━━
Turbo C 程序的調(diào)試
一個(gè)程序設(shè)計(jì)好了以后, 通常會(huì)有一些錯(cuò)誤, 查找和修改程序中的錯(cuò)誤是令人頭痛的事。Turbo C集成開發(fā)環(huán)境提供了一調(diào)試裝 置, 使得這一個(gè)工作容易了許多, 程序調(diào)試達(dá)到了編譯和運(yùn)行級(jí)。
一、TC消息窗口
使用TC最好的理由之一是它允許用戶修改語法錯(cuò)誤(編譯時(shí)) 和評(píng)估編譯器給出的警告。TC將編譯器和連接器發(fā)出的消息收集到 一緩沖區(qū)中, 然后在消息窗口中顯示, 這樣在訪問源代碼的同時(shí), 還能一下看到這些消息。 現(xiàn)將上面的HELLO.C制造一點(diǎn)語法錯(cuò)誤, 將第一行包含語句的#去掉, 再去掉第五行printf語句中的后引號(hào)。現(xiàn)在程序看上去 是這樣的:
include <stdio.h> main() { printf("Hello, world\n); }
按CTRL+F9重新編譯之。編譯窗口將顯示有多少錯(cuò)誤和警告: 應(yīng)為兩個(gè)錯(cuò)誤, 0個(gè)警告。 當(dāng)看見編譯窗口中的Press anykey提示時(shí), 按空格鍵, 消息窗口立刻被激活, 亮條出現(xiàn)在第一個(gè)錯(cuò)誤或警告上, 這時(shí)編輯窗口中 也會(huì)有一亮條 --- 它標(biāo)志著編譯器給出的錯(cuò)誤或警告在源代碼中的相應(yīng)位置。 這時(shí)可用光標(biāo)鍵將消息窗口中的亮條上下移動(dòng), 注意到編輯窗口中的亮條也隨著跟蹤源代碼中錯(cuò)誤發(fā)生的位置。如果將亮條置于 "compile"上, 則編輯器顯示文件的最后位置。 如果消息窗口太長看不見, 可用左、右光標(biāo)水平滾動(dòng)消息, 為了一次能夠多看點(diǎn)信息, 可按F5放大消息窗口。放大后, 編輯窗 口不可見了, 因此不進(jìn)行錯(cuò)誤跟蹤。現(xiàn)在, 保持分屏模式。 為了改正錯(cuò)誤, 將消息窗口中的亮條置于第一個(gè)錯(cuò)誤消息上, 回車, 光標(biāo)移到編輯窗口中錯(cuò)誤產(chǎn)生處, 注意, 編輯器狀態(tài)給出 所選消息( 這在放大模式下是有用的)改正之。(將第一行拿走的#重新寫上)。 當(dāng)不只一個(gè)錯(cuò)誤時(shí), 可用兩種方法來修改下一錯(cuò)誤。 第一種方法和前面一樣, 按F6回到消息窗口選擇想修改的下一條消息。 第二種方法不用回到消息窗口, 只要按Alt+F8, 編譯器就會(huì)將光標(biāo)移至消息窗口中列的下一個(gè)錯(cuò)誤。按Alt+F7可移至前一個(gè)錯(cuò) 誤。 這兩種方法各有長短, 視情況而定。有時(shí)源代碼中一個(gè)愚蠢的錯(cuò)誤把編譯弄糊涂了, 產(chǎn)生好多消息, 這時(shí)選擇修改第一條消息就 使得其余的一些錯(cuò)誤消息沒有什么意義了, 這種情況發(fā)生時(shí), 使用方法一會(huì)方便些, 一修改完第一個(gè)錯(cuò)誤之后回到消息窗口, 再滾動(dòng) 到下一個(gè)有意義的消息上, 選擇之。在別的情況下, 按Alt+F8會(huì)方便得多。 記住, Alt+F7和Alt+F8是熱鍵, TC中無論何時(shí)均起作用。因此在消息窗口中按Alt+F8得到的不是當(dāng)前亮行消息, 而是下一個(gè)消息 (按Enter選擇當(dāng)前消息)。但如果沒別的編譯消息, Alt+F8就不起作用了。 注: 可以如此法選擇連接消息, 但它們不跟蹤源文件。在修改語法錯(cuò)誤的過程當(dāng)中, 經(jīng)常需要增加、刪除正文, 編輯器是記住 的,依然能正確定位錯(cuò)誤位置。沒有必要記住行號(hào)和增加、刪除的正文行。
二、Turbo C集成調(diào)試器
一旦修改好語法錯(cuò)誤之后程序編譯就沒什么問題了, 但還是可能不按要求運(yùn)行, 因?yàn)榭赡苡羞壿嬪e(cuò)誤(運(yùn)行錯(cuò)誤)。這種錯(cuò)誤跟蹤 就無助于發(fā)現(xiàn)錯(cuò)誤位置了。 TC有一個(gè)集成調(diào)試器可以跟蹤運(yùn)行錯(cuò)誤。通過調(diào)試器可以運(yùn)行, 在斷點(diǎn)處暫停, 檢查變量的值, 甚至可 以改變之, 以看程序會(huì)有什么反應(yīng)。 Turbo C集成調(diào)試器是源程序級(jí)的調(diào)試器, 即用同你編寫程序一樣的" 語言" 來控制調(diào)試器。例如, 為了顯示數(shù)組中的一個(gè)元素 的值, 可告訴調(diào)試器顯示這樣的表達(dá)式的值:
Ctrl+F4 Debug/Eavluate 計(jì)算表達(dá)式, 允許修改變量的值。 Debug/Find Function 查找函數(shù)定義, 顯示在編輯窗口中。僅在調(diào)試時(shí)才有效。
Ctrl+F3 Debug/Call Stack 顯示調(diào)用棧, 可顯示任何函數(shù)的當(dāng)前執(zhí)行位置, 其方法是在調(diào)用棧中選擇相應(yīng)的函數(shù)名。 僅在調(diào)試時(shí)有效。 Debug/Source Debugging 控制是否允許調(diào)試: 置為On時(shí), 集成調(diào)試器和單獨(dú)調(diào)試器均可用; 置為Standalone時(shí), 只能 用單獨(dú)調(diào)試器調(diào)試, 雖然還能在TC中運(yùn)行; 置為None時(shí), 在.EXE文件不置調(diào)試信息,兩種調(diào)試 均不能調(diào)試。
Ctrl+F4 Break/Watch/Add Watch 增加一監(jiān)視表達(dá)式。 Break/Watch/Delete Watch 刪除一監(jiān)視表達(dá)式。 Break/Watch/Edit 編輯一監(jiān)視表達(dá)式。 Break/Watch/Remove All 刪除所有監(jiān)視表達(dá)式。 Watches
Ctrl+F8 Break/Watch/Toggle 設(shè)置或清除光標(biāo)所在行的斷點(diǎn)。 Breakpoint Break/Watch/Clear 刪除程序中所有斷點(diǎn)。 Breakpoint Break/Watch/Next 顯示下一斷點(diǎn) Breakpoint
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 表3. 調(diào)試器菜單命令及其熱鍵 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 熱鍵 菜單命令 功能 ─────────────────────────────────── F5 在整屏和分屏之間放大縮小活動(dòng)窗口。 Alt+F5 將顯示轉(zhuǎn)到用戶屏, 擊任意鍵返回。 F6 在編輯窗口與監(jiān)視窗口或消息窗口間 切換。 Alt+F6 若編輯窗口是活動(dòng)的, 轉(zhuǎn)到最近一次 裝入編輯器的文件; 若下面窗口是活 動(dòng)的, 則在監(jiān)視窗口和消息窗口間切換。 Ctrl+F9 Run/Run 調(diào)試運(yùn)行或不調(diào)試運(yùn)行程序, 必要時(shí) 編譯、連接源文件, 若編譯、 連接時(shí) Debug/Source Debuging和O/C/C/OBJ Debug Information為On, 則運(yùn)行程序 到斷點(diǎn)或程序末尾。 Project/Remove Messages 刪除消息窗口中的內(nèi)容。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
判斷程序是否出錯(cuò)或者為什么出錯(cuò)是編程中最有挑戰(zhàn)意義的一方面。這里建義你進(jìn)行預(yù)防性設(shè)計(jì), 具體做法為: (1). 將代碼寫清楚點(diǎn), 應(yīng)作適當(dāng)縮進(jìn), 使用文字說明和描述性的變量名。 (2). 代碼應(yīng)簡單, 把精力放在簡單語句中的復(fù)雜表達(dá)式, 而不是一些復(fù)雜語句。Turbo C的代碼優(yōu)化機(jī)制將大大提高代碼的 效率, 而且調(diào)試、閱讀、 修改起來容易。 (3). 盡量用目的簡單、好定義的函數(shù)構(gòu)建程序。 這會(huì)便于編制調(diào)試程序和分析結(jié)果, 而且閱讀、修改起來也要容易一些。 (4). 應(yīng)盡量減少各個(gè)函數(shù)要求的數(shù)據(jù)和改變數(shù)據(jù)的元素個(gè)數(shù)。這也會(huì)便于編制測試程序和分析結(jié)果; 同樣便于閱讀、 修改程 序。并且還限制了出錯(cuò)函數(shù)可能造成的巨大混亂的牽涉面, 便得能在一個(gè)調(diào)試節(jié)中多運(yùn)行函數(shù)幾次。 (5). 要留心編寫程序中的公共函數(shù), 或者說在其它程序中可再用的函數(shù)。編寫、調(diào)試一個(gè)一般性的函數(shù)通常要比編寫、調(diào)試兩 個(gè)或更多的特殊函數(shù)要容易。
Turbo C編譯、連接和運(yùn)行時(shí)的常見錯(cuò)誤
一、編譯時(shí)的常見錯(cuò)誤
1. 數(shù)據(jù)類型錯(cuò)誤。此類錯(cuò)誤是初學(xué)者編程時(shí)的常見現(xiàn)象, 下面是一些要引起注意的錯(cuò)誤: (1) 所有變量和常量必須要加以說明。 (2) 變量只能賦給相同類型的數(shù)據(jù)。 (3) 對(duì)scanf()語句, 用戶可能輸入錯(cuò)誤類型的數(shù)據(jù)項(xiàng), 這將導(dǎo)致運(yùn)行時(shí)出錯(cuò), 并報(bào)出錯(cuò)信息。為避免這樣的錯(cuò)誤出現(xiàn), 你就提 示用戶輸入正確類型的數(shù)據(jù)。 (4) 在執(zhí)行算術(shù)運(yùn)算時(shí)要注意: a. 根據(jù)語法規(guī)則書寫雙精度數(shù)字。要寫0.5, 而不是寫.5; 要寫1.0, 而不是1。盡管C語言會(huì)自動(dòng)地把整型轉(zhuǎn)換成雙精度 型, 但書寫雙精度型是個(gè)好習(xí)慣。讓C語言為你做強(qiáng)行轉(zhuǎn)換這是一種效率不高的程序設(shè)計(jì)風(fēng)格。 這有可能導(dǎo)致轉(zhuǎn)換產(chǎn) 生錯(cuò)誤。 b. 不要用0除。這是一個(gè)災(zāi)難性的錯(cuò)誤, 它會(huì)導(dǎo)致程序失敗, 不管C語言的什么版本, 都是如此, 執(zhí)行除法運(yùn)算要特別 小心。 c. 確保所有的雙精度數(shù)(包括那些程序輸入用的雙精度數(shù)) 是在實(shí)數(shù)范圍之內(nèi)。 d. 所有整數(shù)必須在整數(shù)允許的范圍內(nèi)。這適用于所有計(jì)算結(jié)果, 包括中間結(jié)果。
2. 將函數(shù)后面的";"忘掉。此時(shí)錯(cuò)誤提示色棒將停在該語句下的一行, 并顯示: Statement missing ; in function <函數(shù)名>
3. 給宏指令如#include, #define等語句尾加了";"號(hào)。
4. "{"和"}"、"("和")"、"/*"和"*/"不匹配。 引時(shí)色棒將位于錯(cuò)誤所在的行, 并提示出有關(guān)丟掉括號(hào)的信息。
5. 沒有用#include指令說明頭文件, 錯(cuò)誤信息提示有關(guān)該函數(shù)所使用的參數(shù)未定義。
6. 使用了Turbo C保留關(guān)鍵字作為標(biāo)識(shí)符, 此時(shí)將提示定義了太多數(shù)據(jù)類型。
7. 將定義變量語句放在了執(zhí)行語句后面。此時(shí)會(huì)提示語法錯(cuò)誤。
8. 使用了未定義的變量, 此時(shí)屏幕顯示: Undefined symbol '<變量名>' in function <函數(shù)名>
9. 警告錯(cuò)誤太多。忽略這些警告錯(cuò)誤并不影響程序的執(zhí)行和結(jié)果。編譯時(shí)當(dāng)警告錯(cuò)誤數(shù)目大于某一規(guī)定值時(shí)(缺省為100)便退出 編譯器, 這時(shí)應(yīng)改變集成開發(fā)環(huán)境Options/Compiler/Errors中的有關(guān)警告錯(cuò)誤檢查開關(guān)為off。
10. 將關(guān)系符"=="誤用作賦值號(hào)"="。此時(shí)屏幕顯示: Lvalue required in function <函數(shù)名>
二、連接時(shí)的常見錯(cuò)誤
1. 將Turbo C庫函數(shù)名寫錯(cuò)。這種情況下在連接時(shí)將會(huì)認(rèn)為此函數(shù)是用戶自定義函數(shù)。此時(shí)屏幕顯示: Undefined symbol '<函數(shù)名>' in <程序名>
2. 多個(gè)文件連接時(shí), 沒有在"Project/Project name中指定項(xiàng)目文件(.PRJ 文件), 此時(shí)出現(xiàn)找不到函數(shù)的錯(cuò)誤。
3. 子函數(shù)在說明和定義時(shí)類型不一致。
4. 程序調(diào)用的子函數(shù)沒有定義。
三、運(yùn)行時(shí)的常見錯(cuò)誤
1. 路徑名錯(cuò)誤。在MS-DOS中, 斜杠(\)表示一個(gè)目錄名; 而在Turbo C 中斜杠是個(gè)某個(gè)字符串的一個(gè)轉(zhuǎn)義字符, 這樣, 在用 Turbo C 字符串給出一個(gè)路徑名時(shí)應(yīng)考慮"\"的轉(zhuǎn)義的作用。例如, 有這樣一條語句: file=fopen("c:\new\tbc.dat", "rb"); 目的是打開C盤中NEW目錄中的TBC.DAT文件, 但做不到。這里"\"后面緊接的分別是"n"及"t", "\n"及"\t"將被分別編譯為換行及 tab字符, DOS將認(rèn)為它是不正確的文件名而拒絕接受, 因?yàn)槲募胁荒芎蛽Q行或tab字符。正確的寫法應(yīng)為: file=fopen("c:\\new\\tbc.dat", "rb");
2. 格式化輸入輸出時(shí), 規(guī)定的類型與變量本身的類型不一致。例如: float l; printf("%c", l);
3. scanf()函數(shù)中將變量地址寫成變量。例如: int l; scanf("%d", l);
4. 循環(huán)語句中, 循環(huán)控制變量在每次循環(huán)未進(jìn)行修改, 使循環(huán)成為無限循環(huán)。
5. switch語句中沒有使用break語句。
6. 將賦值號(hào)"="誤用作關(guān)系符"=="。
7. 多層條件語句的if和else不配對(duì)。
8. 用動(dòng)態(tài)內(nèi)存分配函數(shù) malloc()或 calloc()分配的內(nèi)存區(qū)使用完之后, 未用free()函數(shù)釋放, 會(huì)導(dǎo)致函數(shù)前幾次調(diào)用正常, 而后面調(diào)用時(shí)發(fā)生死機(jī)現(xiàn)象, 不能返回操作系統(tǒng)。其原因是因?yàn)闆]用空間可供分配, 而占用了操作系統(tǒng)在內(nèi)存中的某些空間。
9. 使用了動(dòng)態(tài)分配內(nèi)存不成功的指針, 造成系統(tǒng)破壞。
10. 在對(duì)文件操作時(shí), 沒有在使用完及時(shí)關(guān)閉打開的文件。
|