在我们写代码的时候常常会出现一些错误(逻辑上的错误),当你不知道这些错误怎么修改的时候就可以尝试进行调试
目录
1.调试的基本步骤
2.Debug和Release的介绍
3.快捷按键与功能详解
3.1 - F10逐语句执行
3.2 - F11逐过程执行
3.3 F5 - 调试 F9 - 设置/取消断点
4.调试过程中查看相关信息
4.1自动窗口
4.2临时变量
4.3监视
4.4内存
4.5反汇编
4.6寄存器
4.7调用堆栈
- 发现程序错误的存在
- 以隔离,消除等方式对错误进行定位
- 确定错误产生的原因
- 提出纠正错误的解决办法
- 对程序错误予以改正,重新测试
Debug为调试版本,包含调试信息,并且不作优化,便于程序员调试程序
Release为发布版本,进行了各种优化,便于用户使用
如何确定是Debug版本还是Release版本
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/c85663eca4bd7c88c319f96aa2.png" width="1200" />
讯享网
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/cb806f919bf0085b94.png" width="1200" />
我们调试是要将环境改成Debug,Release环境下是没办法调试的
- F5 - 开始调试
- ctrl+f5 开始执行(不调试)
- F9 设置断点/取消断点
- F10 逐过程 - 不会进入函数
- F11 逐语句 - 遇到函数会进入函数
- (F5是和F9配合使用的)
这段代码是怎么执行的呢,我们来按F10,逐过程看看代码怎么运行
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/26cf36900d0bf1c4ee0d93dd3c.png" width="603" />
按了一次F10后可以看到开始运行了,现在光标的位置在红圈所在地方,说明代码运行到了这里
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/d22baecc3c0dba.png" width="435" />
再按一次F10,就运行到了下一句,此时我们打开局部变量看看
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/8a25bb89cb66c20ed6a4dc3d11.png" width="864" />
打开之后我们可以看到,运行到这一步之后,就会创建一个变量i,类型是int
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/a0ebd58968cd0504a7fc1209.png" width="1157" />
我们再按一次F10
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/f47debfa1a0e3ba0ae3c9d72.png" width="1033" />
运行到下一步的时候,就把i的值赋为0了,接下来是一个循环,我们来看看循环是怎么运行的
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/ba171af1dbe1d6d4c2.png" width="453" />
满足循环条件i < 10,进入循环,并执行语句printf(“%d”,i),此时会打印出0
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/30db11ca648a0f9a0dcb87c9b.png" width="1027" />
再次按F10的时候,就会回到for语句,继续判断是否满足for循环的条件,满足则进入循环,不满足离开循环.
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/375ba1a582c47c7cd0d.png" width="1200" />
当i已经打印了1-9之后,i会变成10,在判断不满足for循环条件之后,就会离开循环,执行下一句
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/c4ede79c3ee08c8c14645a768c9a2144.png" width="1200" />
执行到return 0 之后,就结束程序了
以上代码我们测试了F10的功能是逐过程执行代码,我们可以一条一条的查看代码,当你的程序出现错误的时候,你就可以逐语句,看看程序运行的过程和你想象的过程是否一样,如果不一样,那到底是哪一部分的代码出现了问题
当我们遇到函数之后,如下面这段代码
当你想看看test函数是怎么运行的时候,F10逐过程就无法满足我们的需求了
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/75e8c9e6a397eaff6ba7ccb935.png" width="271" />
当我们运行到此时位置的时候,我们再按一次F10
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/9da2079ceb315e9f3d78bd0f90b89ef1.png" width="758" />
可以看到此时直接跳到了下一句,并在屏幕上打印了一个hehe,并没有进入test函数的过程,此时我们就可以使用F11来观察在test函数内部运行的情况
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/b4514bea8bf5d71daac28c839.png" width="263" />
我们在刚刚那个位置按下一次F11之后,可以看到,光标出现在了test函数内部,此时再按F11
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/a1ffcfad3bcd67401f9188.png" width="628" />
可以看到此时打印出来了一个hehe,光标停留在了void函数的右大括号处,我们再按一次F11
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/05afc9d537a33e2ea3776e7ab8.png" width="390" />
此时光标来到了return 0处,可以说明test()到return 0 之间还有很多步骤,按F10都没有执行,F11每一条都执行了.F11和F10的区别就在于,F11是逐语句执行,从程序开始到结束的代码每一条都会执行,会进入函数内部,F10是逐过程,不会进入函数内部
当你想测试某一行的代码,但是按F10或者F11要很多次的时候,你可以添加一个断点
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/4b58cf72cef45049f63c97ca6a392a26.png" width="662" />
我们在34行的位置按F9添加一个断点,此时在34行左边出现了一个红色的小圆圈,这个就是断点
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/e1a83fc0bb08bb6.png" width="1180" />
此时我们按F5开始调试,发现屏幕上打印出了hehe还有1-9,我们发现这其实是34行之前的代码打印出来的东西,此时光标停在了35行,还没有打印出10行hehe,也就是当我们设置断点之后,按F5运行,就会移动到下一个断点处,并运行前面所有的代码
当我们进入循环,如果循环有100次,你想找到第50次,断点应该怎么设置
第一步:先设置一个断点
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/31246c0d606d6997acb037cbaa.png" width="517" />
第二步:在断点处右击鼠标,点击条件
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/0094b575dd02aa77ceefff59378d462a.png" width="571" />
第三步:选择条件表达式,并在后面输入i==50(不要写成i=50),意思就是断点设置的条件是满足i==50
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/e0a34bc9add3ef9729fc65342.png" width="1005" />
当我们设置好之后来看看效果,按F5开始调试
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/37d7a724fccde9eeb.png" width="1200" />
我们发现,当i=50的时候果然停下来了
还有一种方法

<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/daabea8dec706fd45d10b.png" width="1027" />
我们将断点设置在if语句里面,当i=50的时候才会进入if语句内部,所以我们将断点设置在if语句内部,这样也能很好的找到第50个
要开始调试才能看到窗口里的相关信息
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/64250f366a79dc97339df9d56f03c272.png" width="830" />
可以看到当我们打开窗口是可以看到很多东西,比如我们刚刚说过的局部变量,我们来看看几个比较重要的
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/1a0b97df67cb40603a88c9e54a.png" width="1200" />
当我们的代码运行到第一个for循环的位置时,可以看到自动窗口中存在很多变量,你可能会觉得这个和局部变量很像,但是自动窗口会把上下文中的信息自动加入窗口,不好的地方是会自动删除,不够灵活
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/427f44da9de68de52e0e0d15ef0b465a.png" width="1200" />
可以看到,当我们运行到第二个for循环语句时,自动窗口内的东西只剩下i了,如果我们想观察ch和arr的值时就不太方便
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/950a75215d7757a8e19f2e901be5dd21.png" width="1200" />
可以看到当前范围内创建的变量
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/6facaf55b1bbe977cb7b0a8770.png" width="1200" />
当我们进入test函数中,就无法看到main函数中创建的变量了
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/b1d57ce04dfb47e3b9d83e2de5.png" width="1200" />
监视需要手动输入你要监视的值,但是监视的范围比较大,你可以监视变量的地址,观察变量存储在哪个位置,可以观察数组每一个元素的值
当我们想查看一个数的存储位置时,可以打开内存
比如我们想查看arr数组的位置(arr是数组名,本身就是地址,如果是普通变量要加&)
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/49590f89a6ff62bac15975f47549e9bc.png" width="1200" />
然后按下回车键
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/d39b25d13235b38a2bd92d94aada8263.png" width="1200" />
可以看到此时内存arr的地址
此时内存窗口被分成三个部分,左边一栏显示的是内存单元的地址,中间存放的是内存中的信息,内存中本来放的是二进制的数据,为了方便显示,显示的时候用16进制,右边一栏是把内存中的信息解读一下,参考价值不高
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/faac94d7ff63b830b2e5964.png" width="675" />
查看c语言翻译对应的汇编代码
<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/eabb2be064b1abd7f8f.png" width="1200" />
可以看到寄存器,以及运行时候的变化
栈:和子弹上膛一样,如果没满,可以直接往里面放,如果满了之后,要把后加进去的拿出来才能放进去(先进后出)
队列:和排队一样,出去一个,进来一个,队头走,队尾进来,这种对数据的增加和删除方式叫做队列(先进先出)
讯享网<img alt="" src="https://i-blog.csdnimg.cn/blog_migrate/45208bb97410f0c60f967d1484.png" width="1163" />
当我们运行main函数时会调用test,test会调用test1,test1会调用test2,使用调用堆栈窗口时,可以观察到函数调用逻辑是怎样的,当程序比较复杂时,通过调用堆栈可以清晰的观察到调用逻辑

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/154064.html