当前位置:网站首页>C语言详解系列——关于调试那些事

C语言详解系列——关于调试那些事

2022-08-10 20:00:00 悲伤猪小猪

一道笔试题

在之前的学习当中,我们总是提到调试,在我们想知道代码究竟怎么运行时,我们就需要用到调试,当我们的代码出现了bug,通过观察我们找不到哪里出现了问题,这时我们也需要使用到调试,例如下面这道笔试题,我们就出现了问题

#include <stdio.h>
int main()
{
    
    int i = 0;
    int arr[10] = {
    0};
    for(i=0; i<=12; i++)
   {
    
        arr[i] = 0;
        printf("hehe\n");
   }
   
    return 0; 
}

我们通过观察一看,数组元素有10个,但是遍历数组时,我们越界访问了,所以当i = 10的时候,数组越界访问,程序应该崩溃才对,但是真的是这样嘛?我们让代码跑起来
在这里插入图片描述
我们运行起来我们发现,代码并没有崩溃,而是死循环打印hehe了,这是为什么呢?这令我们百思不得其解,这时候调试的作用就体现出来了。

调试那些事

如何调试

调试的基本步骤如下

1.发现程序错误的存在
2.以隔离、消除等方式对错误进行定位
3。确定错误产生的原因
4.提出纠正错误的解决办法
5.对程序错误予以改正,重新测试

注意在我们的编译器中有两个版本

1.Debug 通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序
2.Release 称为发布版本,它往往时进行了个各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

几个调试的快捷键

f5
启动调试,经常用来直接跳到下一个断点处。
f9
创建断电和取消断点
断点的重要作用,可以在程序的任意位置设置断点。
这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。
f10
逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者一条语句。
f11
逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最长用的)。
ctrl + f5
开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。

我们在调试的过程中还可以观察内存信息,查看临时变量的值,查看调用的堆栈,查看汇编信息,查看寄存器信息等。

在调式中寻找答案

好了,我们了解了调试的基本信息,下面让我们通过调试找到刚才笔试题中的问题。

#include <stdio.h>
int main()
{
    
    int i = 0;
    int arr[10] = {
    0};
    for(i=0; i<=12; i++)
   {
    
        arr[i] = 0;
        printf("hehe\n");
   }
   
    return 0; 
}

在这里插入图片描述
我们通过调试可以查看变量iarr[i]的地址,当我们再次执行程序,i = 12
在这里插入图片描述
我们可以通过调试看见,变量i的地址与arr[i]的地址相同,我们执行arr[i] = 0;时将i也赋值成0了,所以程序才会死循环执行。

在这里插入图片描述
这就是调试在我们写程序当中的作用。

原理讲解

好了我们知道是哪里出现了问题,那么为什么会出现这样的问题呢。原因是变量iarr[10]都是在栈区开辟内存空间的,而栈区空间的使用规则是,先使用高地址在使用低地址,数组元素访问时由低地址到高地址开始调用,所以当数组越界访问时,有机会访问到i的空间地址,将变量修改为0,所以会造成死循环。
在这里插入图片描述

原网站

版权声明
本文为[悲伤猪小猪]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_64182409/article/details/126254084

随机推荐