|
樓主 |
發表於 2014-7-19 00:50:52
|
顯示全部樓層
本帖最後由 fatzeros 於 2014-7-19 12:54 AM 編輯
四、除錯模式
接下來,大胖要簡單的介紹一下除錯模式,
除錯模式可以幫助我們在長長的程式碼中快速的驗證及找出我們覺得會出錯的部份,
我們先來看一下範例程式的部分:
/*-----------------------------------------------
名稱:demo2
編寫:沈大胖
日期:2014/07/18
修改:
題目: 模擬一個球在一個盒子裡碰撞的情形。我們假設
有一個球在一個寬度為x高度為y的盒子內移動。
這個球有一個初始位置,表示為(x1,y1)。這個
球的移動方向為(dx1,dy1),且移動方向均為45度
角,因此所有的dx和dy均為1或-1。球的移動速度
是一秒鐘在兩個座標移動一單位長。例如(x1,y1)
為(3,4)且(dx1,dy1)為(-1,1),則一秒鐘後球將
移動到(2,5)。
球撞到盒子邊角時會反彈,由於球始絡以45度角
移動,所以很容易計算路徑。假設(x1,y1)為(3,4)
,(dx1,dy1)為(-1,1),模擬十秒那麼球的位置將
會是(3,4)、(2,5)、(1,6)、(0,7)、(1,8)、(2,7)、
(3,6)、(4,5)、(5,4)、(4,3)、(3,2)…等。如果
球撞到到角落,它會以相反的方向彈回來。
輸入依序為x、y、x1、y1、dx1、dy1、t,而t是
需要模擬的秒數。輸出是最後這兩個球的位置。
內容:
參閱:
-----------------------------------------------*/
題目的意思是說模擬一個球在一個寬為5(x)高為8(y)的盒子裡移動,
球的初始位置是(3,4)(x1,y1),球移動的方向為(-1,1)(dx1,dy1),
模擬移動的時間為10(t)秒,假設球移動的方向均為45度,每一秒鐘在座標上移動一個單位長,
球撞到盒子的邊角時會反彈,求算出球移動10秒的路徑為何?
就大胖在紙上鬼畫符後的結果,球移動的路徑應為:
(3,4)、(2,5)、(1,6)、(0,7)、(1,8)、(2,7)、(3,6)、(4,5)、(5,4)、(4,3)、(3,2)
接下來請看大胖寫的程式碼:- /*-----------------------------------------------
- 名稱:demo2
- 編寫:沈大胖
- 日期:2014/07/18
- 修改:
- 題目:模擬一個球在一個盒子裡碰撞的情形。我們假設
- 有一個球在一個寬度為x高度為y的盒子內移動。
- 這個球有一個初始位置,表示為(x1,y1)。這個
- 球的移動方向為(dx1,dy1),且移動方向均為45度
- 角,因此所有的dx和dy均為1或-1。球的移動速度
- 是一秒鐘在兩個座標移動一單位長。例如(x1,y1)
- 為(3,4)且(dx1,dy1)為(-1,1),則一秒鐘後球將
- 移動到(2,5)。
- 球撞到盒子邊角時會反彈,由於球始絡以45度角
- 移動,所以很容易計算路徑。假設(x1,y1)為(3,4)
- ,(dx1,dy1)為(-1,1),模擬十秒那麼球的位置將
- 會是(3,4)、(2,5)、(1,6)、(0,7)、(1,8)、(2,7)、
- (3,6)、(4,5)、(5,4)、(4,3)、(3,2)…等。如果
- 球撞到到角落,它會以相反的方向彈回來。
- 輸入依序為x、y、x1、y1、dx1、dy1、t,而t是
- 需要模擬的秒數。輸出是最後這兩個球的位置。
- 內容:
- 參閱:
- -----------------------------------------------*/
- #include <stdio.h> //導入標準I/O函數
- #include <stdlib.h>
- void main(void)
- {
- int x=5 , y=8 ; //定盒子的寬為5及高為8
- int x1=3 , y1=4 ; //定球的初始位置為(3,4)
- int dx1=-1 , dy1=1 ;//定球的移動方向為(-1,1)
- int t=10 ; //定模擬的時間為10秒
- int RunBall(int *x1 , int *y1 , int *dx1 , int *dy1) ;
- //球移動子函數宣告
- int BallDirection(int x , int y , int *x1 , int *y1 , int *dx1 , int *dy1) ;
- //球移動方向子函數宣告
- for(t = 0 ; t <= 10 ; t++) //設定模擬時間迴圈
- {
- printf("in loop x1,y1 = (%d,%d) \t and t = %d\n" , x1 , y1 , t) ;
- //印出迴圈內球的位置及模擬時間
- printf("dx1,dy1 = (%d,%d) \n" , dx1 , dy1) ; //印出球的方向
- BallDirection(x , y , &x1 , &y1 , &dx1 , &dy1) ; //呼叫球移動方向子函數
- }
- printf("\n程式結束") ;
- }
- int RunBall(int *x1 , int *y1 , int *dx1 , int *dy1)
- { //計算球移動方式
- *x1 = *x1 + *dx1 ;
- *y1 = *y1 + *dy1 ;
- }
- BallDirection(int x , int y , int *x1 , int *y1 , int *dx1 , int *dy1)
- { //計算球動的方向及位置
- if(*x1 == 0)
- {
- *dx1 = -1 ;
- RunBall(x1 , y1 , dx1 , dy1) ;
- }
- else if(*x1 == x)
- {
- *dx1 = -1 ;
- RunBall(x1 , y1 , dx1 , dy1) ;
- }
- else if(*y1 == 0)
- {
- *dy1 = 1 ;
- RunBall(x1 , y1 , dx1 , dy1) ;
- }
- else if(*y1 == y)
- {
- *dy1 = -1 ;
- RunBall(x1 , y1 , dx1 , dy1) ;
- }
- else
- {RunBall(x1 , y1 , dx1 , dy1) ;}
- }
複製代碼 大胖先來分析一下我寫的程式:
首先,在main函數先定出題目所需要的變數及訂出初值,於程式碼的第34至37行,
再來,在第39及第41行先宣告RunBall(球移動子函數)及BallDirection(球移動方向子函數),
這二個子函數就是球移動及判定球移動方向的子程式,也是我認為最有可能出錯的地方,
最後就是在main函數內執行一個for迴圈(第44至第51行),執行依秒數的增加呼叫BallDirection子函數,
來判定球移動及移動方向的主迴圈,
另外在迴圈內增加印出目前各變數值的函數(第46及第48行),也是在程式寫作中除錯的一種好方式,
待程式都正常之後就可以移除了。
我們先把程式編譯後執行一遍得出的結果如下
哇,在第4秒的地方出錯,球不可能會移動到(-1,8)的地方啊!這樣就跑出盒子外了啊!
所以,我在球移動方向的判定上錯了,那麼,我們要怎麼使用Dev C++來除錯呢?
首先,先在編輯區有疑問的程式碼的行號的地方左點一下或按一下快速鍵(F4)新增/移除中斷點,
就會在行號的地方出現一個小小紅底綠勾,這個就是設定中斷點的意思,當程式執行到這裡的時候,IDE就會暫停,
大胖在主函數main的第44行執行for迴圈的地方,
及子函數BallDirection的第66、72、78、84及第89行,
也就是我判定球移動到了邊界時,改變方向的地方設定了中斷點,
當程式在除錯模式時跑到了這裡的時候就會停下來,
我的中斷點都是下在變數有變動的地方,這樣比較方便看出變數變動後差異,
再來就是要「新增監看式」,在「編譯除錯訊區」的除錯區中,按下「新增監看式」,就可以新增想要監看的變數
大胖新增了x1,y1,t,dx1及dy1這幾個我想要監看的變數,可以在「專案管理區」的「除錯」頁裡看到這些被新增的變數,
一開始程式尚未執行,所以變數也尚未給定初值,所以出現「Execute to evaluate」是正常的
接下來,大胖就要進行除錯了,永遠記得在除錯前要先存檔一下,讓IDE可以更新原始碼 ,
再來按下「除錯區」的「除錯」按鍵
這時IDE會重新編譯一次後進入除錯模式,IDE將會停在我們剛才設定的第一個中斷點,
行號的紅底綠勾也變成了藍色的箭頭,
我設定的第一個中斷點是第44行,旁邊的變數也都給定初值了,且第44行尚末被執行
再來,我們可以按下「逐行執行」,執行接下來的程式,直到我們發現變數異常了
大胖發現在t=3的時候,且要再進入下一個迴圈的時候,球的位置(x1,y1)錯了,
所以問題就發生在上一個變數改變的時候,這時我們可以先「中斷執行」,然後再重新除錯一次,
並小心的記下問題發生點,就是以下這裡當x1==0的時候,*dx1的值變更為-1
這時,我們可以再新增一個監看式,把*dx1加入監看,並再按一次「逐行執行」將程式先執行第65行,
然後,我們可以在新增的*dx1上按右鍵並「修改數值」, 將*dx1的數值修改為1
接下來再次「逐行執行」,這次球的位置(x1,y1)就正確了
然後我們就可以斷定原程式的第65行錯了,應該將-1改正為1後,再存檔重新編譯一次,執行後的結果就正確了
以上,就是Dev C++的簡易除錯用法,當然除錯模式還有許多其他的功能,這個就得靠大家自行去發掘了!
當然,大胖也是初學者,如果以上有任何的錯誤及觀念不正確的地方,還望請各位老師不吝指教啊!
謝謝謝謝!
到這裡,就是C語言學習環境的簡易建置及使用,希望大家能看得懂,Dev C++這套IDE還有許多功能還沒使用到,
也希望大家能自行學習玩玩看!
接下來,等大胖休息研究一陣子後,就要進入到MCS-51系列的簡易入門介紹了!
最後附上demo2專案檔:
demo2.zip
(54.52 KB, 下載次數: 14)
|
|