EDA365电子论坛网

标题: MATLAB程序调试基本方法分享 [打印本页]

作者: House    时间: 2020-4-16 10:06
标题: MATLAB程序调试基本方法分享
MATLAB程序调试基本方法分享
! m  w' n5 K. e) S# }前言
+ J2 J! w0 Q* _, n6 X# V7 c    本文主要是对MATLAB程序调试中的一般方法进行总结,也是自己学习的记录。全文大致分为三个段落:1 m) G  U2 T: P  k/ F

9 W# @3 _2 A( o. ]+ S  1)代码内调试;
. Z& @7 A. V* D6 a9 A
0 E* [9 B1 C9 u6 @5 _8 y1 c( p  2)断点调试方法;
4 U5 K. @* V1 |& ]
$ w, a. s" h3 Z# i  3)指令调试方法;
% k/ t8 B. |9 G2 U3 W, B
3 k+ w  h, r$ z) o1 A0 n* |本文主要为个人学习总结,并借鉴了前人的经验,相应链接在最后一并附上。
! p9 x# N, I. H+ z, C4 R* _( _* \4 l

- [, |3 Z) A: ]7 \5 x0 B; E1 [
' v& q% n- w0 L* _一、代码内调试- k2 K1 ^2 @1 z. G! x
    A-打印变量
% u; ~) B3 l% k% v3 x0 ]5 {% g: @1 q2 N: M- }/ _

/ g: T$ _5 W2 _, z  b上面的代码,如果希望检查a是否正常:去掉末尾的分号;,即可在Command Window查看到对应的输出信息,特别是当变量出现在function时,如果不输出,则在Workspace中无法直接查看,此时该操作较方便。2 u# D! t$ k. I0 P
    B-局部执行  F7 M( j9 A2 D: a& v
4 ^. Y" T6 S, J: ~, `- u0 Q
; T- E2 U/ y& o1 y' ~; Y4 E" D4 m+ L! O
如果希望对某一部分代码,进行调试,则完全没有必要每次都从头运行,这时局部执行较方便。仍是这段代码,如果希望仅仅执行高亮部分,则箭头选中并按F9,此时程序仅仅运行高亮部分,可利用这个方法调试局部代码。
" }7 |; s% o2 O, n; {, |0 w2 \    C-配合绘图(该操作可以配合以下各类方法使用); y8 P( V( O! {- z/ {7 x# X0 |
图形比数据更易于观察,在调试过程中打开Workspace中的变量(快捷键:Crtl + D),然后选择plot,即可根据需求对数据进行绘图,便于观察特性:6 e& n/ f' `, V, z! P& `
, ]. n2 o; `) j: u3 l. d1 R% V
例如选择需要观察的数据,分别选择bar以及surf指令,即可绘制对应图形:
0 b) U$ B- q& L
; }) ~7 `9 J0 g. Y9 w! Z2 C
是不是也算方便?

1 d0 O3 A: P4 s8 C9 S% f% s
3 t8 i5 i3 ~% k1 P+ q5 C1 u0 O3 a, k
) U9 g2 |, G* d! v6 y: @' v, z
二、断点调试方法

5 m) t# o4 C* D% V+ Y
调试代码最经典的就是利用设置断点的方法,此处给出对应快捷键:

2 R: k' |$ Q3 {' g7 _

3 g; ]# ], W2 G1 S& A# {
5 @+ Z. q! j& ~& I6 i5 _: o
三、指令调试方法
/ {- _2 S) Z, }
    A-keyboard + (return)
4 O. O9 h: {. P1 T6 g% d

经常碰到一些情况,如:矩阵相乘A*B时(假设A已知,B需要运算得出),矩阵B的size难以确定,是用A*B还是A'*B难以确定,可不可以先计算B,运算完之后观察B的特性,再确定用A还是A‘?keyboard可以解决这个问题。

  keyboard顾名思义,就是键盘的意思,即:把控制权交给键盘。执行程序的过程中,把控制权交给键盘,如何再重新返回程序呢?因此:

keyboard 与 return

通常联合使用。如执行:

6 w4 e; t8 s3 c" O8 `0 @/ R$ {
+ I2 r2 q0 }$ }) ?" o

但难以确定G还是G’,利用keyboard则可以修改为:

$ z. v  m; P2 L* i
1 X0 h5 o6 a) v. Q3 `

) H% p' X. w2 b$ n3 }

在进入K>> 之后,此时已经可以观察F、G的size,因此在Command Windows输入:

( p0 f6 _: k! b# D
& w( ~6 H) G* q- I8 C. C9 O

即可保证程序顺利执行。

    B- try + (catch) + end

我们知道,matlab的代码是按行执行的,如果碰到错误行,则程序中断。try..catch可以使得可能出错的代码不影响后面代码的继续执行,也可以检查,排查,解决程序的一些错误,增强代码的鲁棒性和可靠性。

try...end用于尝试运行一段也许可能出错的代码,比如:
* t0 \! s: h3 m& L  U. ^. ]

+ M0 K) [" E( |5 R+ ~这段代码里面,a = m*n运行会出错,不满足矩阵乘法的原则。所以,a = m*n和disp(a)不执行,但后面的disp(m)亦然会执行。
! S/ f, B5 v& D! K

try...catch...end用于检查错误,如

9 G6 F/ `0 t# A: }5 k

3 m7 Q, r6 s9 G, q

这里面,当程序碰到 a = m*n;错误后,就会跳转到catch里面的语句,继续执行,有点类似于if...else...end。

    C-dbstop

在程序执行前输入:


) h% ]# \) J! D
0 g+ v( B- s- v; Y$ J9 i# `3 ?

 如果运行出现错误,matlab会自动停在出错的那行,并且保存所有相关变量。真心好用。

  在.m文件中,插入dbstop in file指令,如下面这段程序,我们在其中加入了dbstop in VMD,其中VMD是一个function:


; u. U3 j) d( t: l

! |; o+ H8 b* b

效果如下:

, ~' H/ @  R2 C/ W9 l! F

即设置断点并运行至VMD程序内部,此时通过F10/F11/Shift F11等断点操作中的快捷键,即可进行调试,Command Windows输入dbquit即可退出。

比如有myprogram.m, 如下:

# W+ i" y  Y) M7 B( e1 j9 i* _
# D7 K6 }/ d7 g5 W3 W. Z# Y

设置一个断点在 n >= 4时(对应程序位置为第6行),然后再运行程序:


6 q( A" m! f, F8 M- h9 Q+ F5 n5 y
; b8 R/ K# I9 E0 f  k" V

  这时有:

2 r) j! C" K2 Z8 E

, P( t$ D) a. h. l, p. h

可见,dbstop比断点设置更加智能,控制起来更为方便。补充一句:


( Q" H# C$ H' W6 R8 {9 u" _" \

) F2 P% {" g/ e, m5 |

此时与F12等价。

所有dbstop,可配合return或者dbstop使用;
7 g8 A0 N7 A8 f' n3 b0 X  return:返回;7 {) w2 X  H9 ^5 b: E$ g  O
  dbstop:停止
8 x/ Q2 c% ^5 k5 j2 _# ]! ~7 _
! b! @1 ^2 _) s2 n% W0 K7 X

调试完成,需要清除所有断点:

在Command Windows输入:

  v2 y) @1 b6 o* u8 \

8 r$ v3 U& n  E  g) e: v# M5 p( G

在Command Windows输入:


. c- `- N" q! l" i- j; M

" }0 L! V) T' l+ D
(1)设置断点:

* dbstop in mfile:在文件名为mfile的M文件第一个可执行语句前设断点;  9 O8 x$ C  C$ G1 y8 J) {) f+ B
* dbstop in mfile at lineno:在mfile的第lineno行设断点;3 X, q$ m$ q, N* K: P. Y4 z- Z8 u
* dbstop in mfile at subfun:当程序执行到子程序subfun时,暂时中止执行,并设断点;
- d, t0 w7 T$ |/ v% }* dbstop if error:遇到错误时,终止M文件运行,并停在错误行(不包括try...catch语句中检测到的的错误,不能在错误后重新开始运行);
7 U; k- l$ H7 h( `4 ~* dbstop if all error:遇到任何类型错误均停止(包括try...catch语句中检测到的的错误);* Y5 l* X: V/ W  ]
* dbstop if warning:程序可恢复运行;+ s& J. l* p% R
* dbstop if caught error:当try...catch检测到运行时间错误是,停止M文件执行,可恢复运行;
, i+ e; H& }% D$ l" E1 j* dbstop if naninf 或 dbstop if infnan

(2)断点清除:

* dbclear all:清除所有M文件中的所有断点;' U( g3 I9 N8 j6 H9 H8 Y
* dbclear all in mfile:清除文件名为mfile的文件中的所有断点;2 h1 P- R+ ~. b8 I$ ~' T
* dbclear in mfile:清除文件名为mfile中第一个可执行语句前的断点;
& X- ^$ ?, N' v, G7 P* dbclear in mfile at lineno:' G! e6 J1 {/ K  D
* dbclear in mfile at subfun:
* E$ J- p6 v* F2 o8 y( {* dbclear if error/warning/naninf/infnan:

(3)恢复运行:

* dbcount:从断点处恢复程序的执行,直到下一个断点或错误后返回Matlab基本工作空间;

(4)执行一行或多行语句:

* dbstep:执行下一个可执行语句;
" e" M" X+ I6 T' R  X4 S* dbstep nlines:执行下nlines行可执行语句;
9 b9 _2 J/ `. N4 O8 g* dbstep in:执行下一行可执行语句,如有子函数,进入;: Q4 G- P1 \. w! f
* dbstep out:执行函数剩余部分,离开函数时停止;
; I) |" z4 z5 M2 g* 注:这四种都返回调试模式,如遇断点,中止;

9 S1 r! `$ i& k% A2 a1 A) d' [

作者: sharkN    时间: 2020-4-16 18:22
楼主分享的MATLAB程序调试基本方法都是些很实用的方法。
作者: YNhhU    时间: 2020-4-20 15:57
很实用啊,楼主好人,谢谢分享。




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2