摘要:調(diào)試技術(shù)是計算機語言課程學(xué)習(xí)中修正程序的重要手段,更是監(jiān)測程序執(zhí)行過程的有效途徑。文章以程序設(shè)計中調(diào)試技術(shù)為視角,從程序設(shè)計中常見的錯誤出發(fā),討論了面對過程程序設(shè)計與面向?qū)ο蟪绦蛟O(shè)計中調(diào)試技術(shù)方法,通過調(diào)試程序的過程,讓學(xué)生掌握程序的組織結(jié)構(gòu),明白程序的執(zhí)行路徑及運行機制,從而學(xué)會程序設(shè)計的思維方式,最終提高學(xué)生的編程能力。
關(guān)鍵詞:調(diào)試技術(shù);計算機語言;程序設(shè)計;思維培養(yǎng)
中圖分類號:G642 ? ? 文獻標(biāo)識碼:A
文章編號:1009-3044(2022)13-0178-00
計算機語言經(jīng)歷了機器語言、匯編語言、高級語言幾個階段,高級語言從程序的組織形式又可分為面向過程和面向?qū)ο螅唧w語言種類有幾十種。程序設(shè)計課程不僅是學(xué)習(xí)編程語言的知識,更重要的是邏輯思維的培養(yǎng),學(xué)習(xí)分析問題和解決問題的方法,即程序設(shè)計思維的培養(yǎng)。隨著計算機軟硬件技術(shù)的不斷更新,必然會產(chǎn)生更先進的計算機語言,在這種形勢下需要幫助學(xué)生建立學(xué)習(xí)程序設(shè)計語言的思維模式,把計算機語言的指令語法知識、程序組織結(jié)構(gòu)、調(diào)試程序的技術(shù)等內(nèi)容學(xué)習(xí)形成一套學(xué)習(xí)思維體系,從而在后續(xù)的計算機語言課程學(xué)習(xí)過程中可以“嫁接移植”,幫助學(xué)生快速掌握一門新的計算機語言,以便學(xué)生在快速發(fā)展的計算機領(lǐng)域里可持續(xù)發(fā)展。
調(diào)試技術(shù)是溝通理論課和實驗課的橋梁[1],是學(xué)習(xí)計算機語言課程中重要的環(huán)節(jié)。調(diào)試程序不僅可以改正錯誤使程序正確運行,更重要的是直觀監(jiān)測每條指令的執(zhí)行結(jié)果,掌握程序設(shè)計的組成結(jié)構(gòu)以及程序執(zhí)行路徑。本文以程序設(shè)計中調(diào)試技術(shù)為視角,從程序設(shè)計中常見的錯誤出發(fā),討論了面對過程程序設(shè)計與面向?qū)ο蟪绦蛟O(shè)計中調(diào)試技術(shù)方法,重點通過程序的調(diào)試過程,讓學(xué)生掌握程序的組織架構(gòu),明白程序的執(zhí)行機制原理,從而學(xué)會程序設(shè)計的思維方式,最終提高學(xué)生的編程能力。
1 程序設(shè)計中常見的錯誤
高級編程語言根據(jù)執(zhí)行機制不同可分成兩類:靜態(tài)語言和腳本語言,靜態(tài)語言采用編譯方式將源代碼轉(zhuǎn)換成目標(biāo)代碼再執(zhí)行,腳本語言采用解釋方式將源代碼逐條轉(zhuǎn)換成目標(biāo)代碼再逐條執(zhí)行。例如:C語言、Java語言是靜態(tài)語言,Python語言、JavaScript語言是腳本語言。無論是編譯型語言還是解釋型語言都是將源代碼轉(zhuǎn)換成目標(biāo)代碼再執(zhí)行的過程,在程序設(shè)計中主要有編輯源程序、編譯程序、鏈接執(zhí)行程序三個步驟,具體過程如圖1所示。
(1)編輯源程序:字符是構(gòu)成程序的基本單位,在很多高級語言采用的字符集都是ASCII碼或者Unicode編碼,因此一般任何文本編輯器都可以用編輯源程序,只不過在高效的程序設(shè)計中用的都是集編輯器、編譯器(解釋器)、鏈接執(zhí)行器一體的集成開發(fā)平臺,VC就是C語言程序設(shè)計非常優(yōu)秀一個集成開發(fā)平臺,Eclipse是JAVA語言程序設(shè)計非常實用的平臺。
(2)編譯/解釋源程序:在靜態(tài)語言中把編輯好的源程序一次性地翻譯為目標(biāo)代碼再執(zhí)行,而腳本語言利用解釋程序一邊翻譯一邊執(zhí)行目標(biāo)代碼,類似于同聲傳譯。
(3)鏈接執(zhí)行目標(biāo)代碼程序:首先加載鏈接系統(tǒng)相關(guān)資源,形成完整的目標(biāo)代碼再執(zhí)行,再輸入數(shù)據(jù)即可得到輸出的結(jié)果。
在程序設(shè)計的三個步驟中,編輯程序時若有語法錯誤,編譯就通不過,程序不能進入運行階段;若在加載鏈接相關(guān)資源不正確,則程序運行就會出錯;程序運行后得出不正確的結(jié)果,這時說明程序邏輯語義表達出錯,因此根據(jù)錯誤產(chǎn)生的時機可以抽象分為三類錯誤:語法錯誤、運行錯誤和邏輯錯誤。
1.1 語法錯誤
一門計算機語言是一套人與計算機交流的指令集合,與自然語言相似,有詞匯、語法、句法、語句組織規(guī)則,編寫程序就像寫文章,做項目就像編寫一本書[2]。語法錯誤是指編輯源程序時輸入不符合語法規(guī)則而產(chǎn)生的錯誤,導(dǎo)致程序編譯通不過,程序也不能進入運行階段。通常,編譯器對源程序進行編譯的過程中,會把檢測到的語法錯誤以提示的方式列舉出來,因此語法錯誤又稱為編譯錯誤。初學(xué)者對語法規(guī)則記憶不牢,編寫不熟練,經(jīng)常出現(xiàn)諸如表達式不完整、缺少必要的標(biāo)點符號、標(biāo)識符和關(guān)鍵字拼寫錯誤、數(shù)據(jù)類型不匹配、循環(huán)語句或選擇語句的語法結(jié)構(gòu)錯誤、沒有區(qū)分大小寫等語法錯誤[3]。在集成開發(fā)平臺編譯時,都能非常詳細羅列出錯的位置及原因,給改正程序提供很大便利。
1.2 運行錯誤
運行錯誤發(fā)生在程序編譯成功后,進行加載鏈接外部資源后運行時出現(xiàn)錯誤,導(dǎo)致程序被迫終止。此類錯誤主要是加載鏈接外部資源不成功,例如文件名拼寫錯誤或路徑錯誤導(dǎo)致打不開文件、寫入數(shù)據(jù)的文件磁盤空間不夠、數(shù)據(jù)庫連接錯誤、數(shù)組的越界訪問等。此類錯誤發(fā)生時,集成開發(fā)平臺會根據(jù)錯誤情況給出比較精確的提示信息。在VC編譯C語言程序時,若出現(xiàn)里面函數(shù)的包含文件寫錯或是調(diào)用的函數(shù)名寫錯時,經(jīng)常出現(xiàn)鏈接運行錯誤;在Eclipse集成平臺編寫Java程序時,導(dǎo)入的包寫錯或調(diào)用的類名拼寫錯誤也會在運行時發(fā)生異常提示。
1.3 邏輯錯誤
邏輯錯誤是指程序編譯運行時都沒有出現(xiàn)錯誤,也有運行結(jié)果,但結(jié)果不正確,從某種意義上說,計算機并不認為“有錯”,猶如寫了一篇文章但文不對題,顯然失去了程序功能的意義。邏輯錯誤是程序設(shè)計中最難查找的錯誤,必須了解程序的功能及程序邏輯組織結(jié)構(gòu)才能改正程序錯誤,此種錯誤集成開發(fā)平臺沒有辦法報錯,不在考查程序處理異常范圍之內(nèi),必須了解程序的功能及程序邏輯組織結(jié)構(gòu)才能改正程序。出現(xiàn)這種錯誤通常是對程序功能理解不正確、組織程序的邏輯結(jié)構(gòu)不對,例如:使用了不正確的變量,指令的次序錯誤、循環(huán)的條件不正確程序設(shè)計的算法考慮不周全等,有時邏輯錯誤也會附帶產(chǎn)生運行錯誤。邏輯錯誤在集成開發(fā)平臺中沒有錯誤顯示,出錯位置及原因是排錯的難點,是調(diào)試程序的重中之重。
2 程序設(shè)計課程中程序調(diào)試思維的培養(yǎng)
針對前面程序中錯誤如何進行調(diào)試,以達到程序的功能,通常有兩個步驟:靜態(tài)檢查和動態(tài)檢查。首先,按照程序的邏輯組織結(jié)構(gòu)進行靜態(tài)檢查,即人工檢查,主要檢查語法錯誤及程序邏輯組織結(jié)構(gòu),猶如寫好一篇文章自己先閱讀一遍看是否有錯字或不通順的地方。動態(tài)檢查即利用集成開發(fā)平臺軟件進行編譯運行檢查,若有語法錯誤,則在編譯階段就會提示有錯誤,根據(jù)錯誤提示修改即可,編譯通過了進入鏈接階段,最后通過輸入不同的數(shù)據(jù)驗證程序的正確性。在實際編寫程序過程中,應(yīng)用集成開發(fā)平臺進行動態(tài)檢查、調(diào)試程序是最主要的手段,語法錯誤和運行錯誤都有精確的錯誤位置及提示,尤其是出現(xiàn)邏輯錯誤時,動態(tài)檢查可以利用集成開發(fā)軟件具體到每條指令的執(zhí)行結(jié)果,通過觀察變量的變化,排查程序編寫錯誤的原因。
在前面闡述的三類錯誤中,語法錯誤和鏈接錯誤通過集成開發(fā)平臺可以獲得錯誤的具體位置和原因,只要按照提示信息進行修改即可。邏輯錯誤在計算機看來是“沒有錯誤”的,是程序設(shè)計中最難排查的錯誤。在日常程序設(shè)計課程學(xué)習(xí)時,通常先用靜態(tài)檢查的方法按照程序結(jié)構(gòu)的邏輯語義進行排查,另一種最重要的手段就利用集成開放平臺提供調(diào)試工具進行調(diào)試程序,按照程序的執(zhí)行路徑,通過觀察變量值的變化,排查指令邏輯語義描述的正確性。這兩種方法都需要對程序的組織結(jié)構(gòu)非常清晰,熟悉程序執(zhí)行路徑及執(zhí)行原理才能進行邏輯錯誤的排查。
廣義上講,一個程序可以用兩種方法組織:一是圍繞過程,二是圍繞數(shù)據(jù)。面向過程的程序設(shè)計最典型是C語言程序設(shè)計,面向?qū)ο蟮某绦蛟O(shè)計最具代表是Java程序設(shè)計、Python語言。無論面向過程的程序設(shè)計,還是面向?qū)ο蟮某绦蛟O(shè)計,調(diào)試思維都是一致的,在動態(tài)檢查中基于馮·諾依曼計算機執(zhí)行存儲程序原理,了解程序執(zhí)行的順序過程,在集成開發(fā)平臺中有單步調(diào)試、斷點調(diào)試、跳躍式調(diào)試等調(diào)試方法,其調(diào)試的技巧及思維過程是完全一致的,在調(diào)試程序時還可以利用輸出語句,輸出中間結(jié)果,判斷程序執(zhí)行情況,下面分別以C語言和Java語言講述面向過程程序設(shè)計和面向?qū)ο蟪绦蛟O(shè)計中的調(diào)試思維策略。
2.1 面向過程程序的調(diào)試方法
程序設(shè)計就是把解決問題的過程應(yīng)用計算機語言的指令集表達出來,即是從鍵盤里輸入信息A通過計算機的處理得到想要的結(jié)果信息B的過程[2]。每種語言的源程序都有指令的組織模式,函數(shù)是構(gòu)成C程序最基本的單位,一個C程序由若干源程序文件組成,每個源程序文件由一個或多個函數(shù)及其他相關(guān)內(nèi)容組成,所有的源文件中僅有一個主函數(shù)main[4];圖2即是一個C程序的基本編寫格式。
馮·偌依曼思想計算機工作原理都是存儲程序,程序運行時,所有的源程序編譯鏈接成一個整體調(diào)入內(nèi)存中,一條一條取出來執(zhí)行,C語言程序的執(zhí)行總是從main函數(shù)開始,在main中結(jié)束,其他的函數(shù)只能被main調(diào)用執(zhí)行。若在C程序中出現(xiàn)語法錯誤或是運行錯誤,在VC集成開放平臺中通過編譯鏈接兩個步驟就會在輸出窗口中一行一個錯誤列舉出錯誤的位置和原因,在錯誤行上雙擊,即可跳轉(zhuǎn)到源程序錯誤的位置,再依據(jù)提示信息修改即可。若出現(xiàn)邏輯錯誤,就要啟動debug技術(shù)調(diào)試程序,圖3是VC平臺調(diào)試程序的界面。常用的調(diào)試方法有單步運行、運行光標(biāo)處、設(shè)置斷點或幾種方法綜合等調(diào)試措施,此處不討論調(diào)試技巧,這些在具體教學(xué)時逐一演示示范,也可以錄制調(diào)試程序技巧相關(guān)視頻給學(xué)生學(xué)習(xí),無論哪種調(diào)試方法或幾種方法綜合,都是依據(jù)程序執(zhí)行路徑中變量的值是否按照預(yù)定軌跡變化來判斷程序邏輯語義是否正確,因此,掌握程序的架構(gòu)及運行過程才能學(xué)會程序設(shè)計的思維方式。
2.2 面向?qū)ο蟪绦虻恼{(diào)試方法
面向?qū)ο蟪绦蛟O(shè)計中,把客觀世界看作是由對象組成,對象中具有相同靜態(tài)屬性和動態(tài)屬性特征抽象出來,用統(tǒng)一計算機語言來表示,即面向?qū)ο笾械念怺5]。從計算機語言發(fā)展歷程來看,面向?qū)ο蟮恼Z言是將面向過程中變量的和函數(shù)按相關(guān)性進行歸類,綁定到操作的數(shù)據(jù)(即對象)上,用計算機語言描述就是類。類是面向?qū)ο缶幊陶Z言基本組成單位,一個Java語言的應(yīng)用程序可以由若干源文件組成,每個源文件是由若干類組成,Java程序的所有代碼都存放在類中,類是Java的基本封裝單位[6],但所有源文件的類中有且僅有一個main方法,它是程序的入口和出口,圖4就是一個典型的Java語言源程序的組織結(jié)構(gòu)。
面向?qū)ο笳Z言程序的執(zhí)行原理也是馮·諾依曼思想,在面向?qū)ο蟪绦蛑幸灿谐绦虻娜肟诤统隹?。在Java語言中,main方法即是程序入口和出口,由于面向?qū)ο蟮幕窘M成單元是類,因此Java應(yīng)用程序的執(zhí)行過程首先是找到Main方法所在的類,加載包含main方法的類,并按照程序書寫先后順序執(zhí)行類的靜態(tài)方法,再執(zhí)行main方法。main方法既是程序的入口,也是程序的出口,其他類的變量和方法被main方法引用和調(diào)用。在Eclipse集中開發(fā)平臺中,可以檢測語法錯誤和運行錯誤,語法錯誤在編輯程序時就能實時提示,并在本行首部出現(xiàn)打叉標(biāo)志,同時還會有修改建議,而運行錯誤則是以異常的形式來通知。邏輯錯誤即程序語義錯誤,平臺無法查錯,也只能通過debug調(diào)試程序。在Eclipse平臺中,程序的調(diào)試方法及技巧也與VC平臺一致,有單步、斷點等調(diào)試方法,特別注意的是,面向?qū)ο笳Z言中組成程序的基本單元是類,因此在源程序中按下ctrl+t即可查看整個程序的組織結(jié)構(gòu)關(guān)系,還可以了解程序組成元素,在Eclipse平臺調(diào)試情況如圖5所示。
3 結(jié)束語
本文探討了程序設(shè)計過程中的調(diào)試技術(shù),通過調(diào)試思維反向引領(lǐng)學(xué)生學(xué)習(xí)計算機語言序列課程,培養(yǎng)學(xué)生建立程序設(shè)計的思維模式,快速學(xué)習(xí)新的計算機語言,幫助學(xué)生在計算機行業(yè)可持續(xù)發(fā)展,也為計算機語言序列課程實踐教學(xué)中如何引導(dǎo)組織教學(xué)提供一種思路。
參考文獻:
[1] 王楠,趙占芳.調(diào)試技術(shù)在程序設(shè)計實驗教學(xué)中的應(yīng)用探討[J].教育現(xiàn)代化,2017,4(7):46-47,53.
[2] 付喜梅.關(guān)于計算機語言教學(xué)的探討[J].電腦知識與技術(shù),2018,14(10):121-123,132.
[3] 李莫凡.C++程序中的常見錯誤和解決方法[J].電子技術(shù)與軟件工程,2016(6):252.
[4] 譚浩強.C程序設(shè)計教程[M].北京:清華大學(xué)出版社,2007.
[5] 張海藩,牟永敏.軟件工程導(dǎo)論[M].6版.北京:清華大學(xué)出版社,2013.
[6] 沈澤剛.Java語言程序設(shè)計[M].3版.北京:清華大學(xué)出版社,2018.
【通聯(lián)編輯:唐一東】