还在漫无目的凭感觉拼运气调easyX课设?让科学的调试方法带你飞吧!

easyX作为一个第三方图形库,出现问题时问题的原因往往不容易找出来。比如一个图形不移动的时候,可能是链表出了问题,也可能是图像输出部分参数有错误,如果漫无目的的一次次看源代码,可能要很久才能找出原因;又因为第三方图形库往往不能方便的分步调试,这时候一个合理的调试方法就变得非常重要。

不同的程序中,所需要的调试方法各不相同,一个合理的调试方法应该可以帮助找到问题的发生点,最好能独立于程序的运行输出调试结果,可以保留程序出错的轨迹。

虽说easyX不能直接使用调试工具进行调试,但easyX本身在设计的时候给我们留下了很多可以使用的调试手段。下面就来结合昨天晚上的实例说一说这些调试方法的具体应用,希望可以给做课设的同学们打开一些思路。

最简单的断点调试

断点调试设置最简单,不需要添加任何语句,可以结合IDE的功能做一些简单的判断,比如当程序无法正正常执行但又不报错时,可以通过断点观察变量的值,或者观察程序是否陷入死循环无法执行到某一行。

image

如上图所示,当我拿到程序之后,程序不报错,但是不能正常运行,代码结构看起来问题又不大,因为是别人的代码,从头看代码缕清思路又不现实,所以我做的第一步就是在程序运行的主循环中各个函数设置断点。

当我将断点设置在getMOVE函数中时,断点无法触发,说明程序无法执行到getMOVE这一行,在之前的函数中陷入了死循环。

而当我将断点设置到fishmove中时,断点触发,说明死循环位于fishmove函数中,接下来我就可以有针对性的解决这个函数中的死循环问题,解决之后更便于从整体考虑问题。

使用命令行调试

使用命令行调试是使用easyX调试程序的最好的方法。比起观察图像的变化,使用命令行调试可以像写普通程序一样,使用printf直接输出其中的变量以变量的值,更直观且更精确,而且很多图像无法反映出来的数据,只能通过命令行进行输出。

如何使用命令行输出

在初始化绘图环境的时候,使用如下语句进行初始化:

initgraph(640, 480, SHOWCONSOLE);

即在坐标后加参数SHOWCONSOLE,即可在显示图形界面的时候保留命令行窗口,接下来就可以使用printf等语句进行调试。

下面举几个使用命令行调试的例子,供大家打开思路,来源均来自于昨天调试的代码:

判断链表是否操作正常

链表让很多同学头疼,尤其是在图形界面下原因难以判断的时候更是如此,当其他部分还存在问题时,只通过图形界面根本无法判断链表是否正常工作,这个时候就可以使用命令行来独立观察链表工作情况。

昨天我调试的代码中,图像显示不正常,我要测试一下函数是否正常遍历了链表中的所有元素。

于是我在appear函数遍历链表的循环体中,设置了标记变量,并设置了相应的输出语句,代码如下:

image

运行结果如下:

image

在初始化的时候,代码初始化了十五个对象,这里函数共输出了15次,考虑到边界处理等因素带来的输出错误,数量基本没有错误,说明链表被正常遍历。

同样的方式我还用来测试了移动所有电脑控制的鱼的fishmove函数:

image
image

fishmove函数运行的次数和appear函数输出的次数一样,说明在遍历链表的操作上,二者没有错误。

注意点

因为我们在命令行输出内容是为了方便调试,因此我们要能通过输出的内容判断出该内容来自于哪个一函数的哪一部分。因此有一些注意点:

一定要换行。一条信息占一行才能让你更清晰的看清楚每一条信息内容。

要标记函数名。比如inappear, in fishmove等,不要自己猜测该变量来自于哪一个函数。

测试循环的时候要注意输出循环数量

如果输出变量,要记得写上变量名,比如ptinf(“data=%d\n”,%d),方便观察。

判断某一个条件是否执行

这一点也比较常见。当你写了一个按键操作的代码段,但你的操作并没有对程序产生影响,这是你如何判断该操作是否被程序捕捉?这个时候用命令行也可以解决。

在昨天的程序中,我看到了一个我没用过的获取按键消息的函数GetAsyncKeyState(如下图所示):

image

此时,我无法通过按键控制鱼的移动。虽说我可以很轻松的查到函数的功能,但我无法确定函数的触发方式在游戏中能否实现。

这时,可以通过命令行来判断按键是否能正常操作:

image

如果按下W的时候,命令行可以输出in getMOVE GetAsyncKeyStateW,则说明该条件语句可以执行,问题不出在这里。运行一下之后结果如下:

image

如上图所示,命令行窗口输出了该语句,说明按下W的时候,条件语句正常执行,问题是在别的地方。

测试变量是否被修改

同样的道理,我们需要测试某些变量的时候,我们也可以直接在命令行输出。比如测试坐标是否被修改。

当我们遍历修改链表中的元素的时候,我们只需要测试其中某一个元素的坐标是否被修改即可判断程序是否正常执行。因此我们可以只在计数到某个固定的值的时候,输出该元素的坐标值,如下图所示:

image

运行的时候如下图所示:

image
image

从284到302,说明坐标值被修改。

总之,善用命令行让你方便地独立调试课设中某一部分的内容,对某些中间变量等进行输出,可以让你快速找到程序中的问题。

使用ifdef切换调试模式

使用ifdef/endif语句,可以让编译器在编译程序的时候,根据是否定义某一段宏,来决定是否编译该段语句。

image

上图中,当宏定义中使用#defineDEBUGMODE定义了DEBUGMODE之后,其中的语句可以运行;如果取消对DEBUGMODE的定义,比如将宏定义注释掉:

image

可以发现上面的语句变为灰色:

image

此时再编译,该段语句不会执行。

合理使用该功能,比如将所有的测试语句全部至于ifdef/endif之中,有两个好处:

可以通过是否注释掉定义的宏(如DEBUGMODE)来关闭/开启所有的测试语句;

当你的测试语句非常多的时候,可以通过设置多个不同的宏定义,开启/关闭不同的测试程序,避免过多的测试语句造成干扰。比如定义MOVEMODE,JUDGEMODE等,根据不同的情况开启不同的测试语句。

关于图片读取

这一点和测试无关。

easyX在读取图片文件的时候会消耗大量的时间,当你的程序运行非常缓慢的时候,很可能就是因为你进行了重复文件读取操作。

当你在函数中使用了读取函数功能时,可以使用下面的方式使该函数在程序运行的时候无论调用多少次,都只进行一次文件读取操作,提高程序的执行效率:

image

将储存图片的指针(FISH)设置为static静态变量,并设置一个静态标记变量(loadFlag),读取一次文件之后,修改标记变量,下一次便不再进行读取操作。

关于调试的内容就到这里

希望这些内容可以帮助做课设的同学们更快更好地完成自己的课设

如果有需要补充或者有其他疑问的可以后台联系我或者在下面留言

之前我还写过一篇输出透明图片的解决方案,欢迎点击查看:

C语言课设中调用EasyX库输出透明图片的方案(含图片处理方法&实现代码)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容

  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 16,500评论 0 26
  • 导读:“搞体育不是职业运动员做的事吗?我家孩子又不是要成为运动员,为什么要练体育?”一个行业的不成熟,从家长的认知...
    绘客ART阅读 589评论 0 2
  • 记得在大话西游当中,最让人印象深刻的一个场景,是紫霞充满爱的眼神,至于在戏外,有人也会传闻说朱茵是喜欢周星驰的,因...
    刻意练习社区阅读 710评论 1 1
  • 云旧雨旧顾旧楼,煮酒独坐一醉休, 难回首,明月旧,人不留。 青竹一片风还旧,红叶一地沾心愁, 难回首,情易瘦,岁无...
    君兮阅读 448评论 14 12
  • 时间,带不走真正的朋友 岁月,留不住虚幻的拥有 时光转换 体会到缘分善变 平淡无语, 感受了人情冷暖 有心的人,不...
    深漂创业者阅读 340评论 0 0