实用调试技巧——C语言

简介: 当我们在编写程序的时候,我们会遇到种种问题,有时候运行的结果和预期不同,甚至直接编译不通过。这时我们就应该寻找代码中的bug,那bug是什么呢?

当我们在编写程序的时候,我们会遇到种种问题,有时候运行的结果和预期不同,甚至直接编译不通过。这时我们就应该寻找代码中的bug,那bug是什么呢?


bug中文翻译过来就是臭虫,最早的bug是从第一台大型计算机中出现的,当时在计算机中进去一只飞蛾,导致计算机出现问题,科学家们进入到计算机中找到这只虫,并把这次事件公布与众,才有了今天的bug。第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。


所以我们在寻找代码中的bug时不应该意味的看,而是进入到程序里面一步一步进行测试,这样既可以精准的找到错误,也可以节约时间,这就要用到调试技巧了。


调试的意义


调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序 错误的一个过程。


调试的基本步骤:


发现程序错误的存在


以隔离、消除等方式对错误进行定位


确定错误产生的原因


提出纠正错误的解决办法


对程序错误予以改正,重新测试


在这里我们提及一下debug和release两个版本,在程序中一般有两个版本,一个是debug版本(调试版本)另一个时release版本(发布版本),Debug包含调试信息,并且不作任何优化,便于程序员调试程序。 Release往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。当我们在写程序或修改程序时,我们要用debug版本来进行。


4b76098c49d04a47be9da575f430ea27.png


Windows环境调试介绍


当我们想对一个程序进行调试的时候,我们在环境中先选中debug版本,这样代码才能正常运行调试。


我们首先得学会使用快捷键:


7465ca317a914656ae9aa26f2859ef7e.png


最常使用的几个快捷键:


F5 启动调试,经常用来直接跳到下一个断点处。


F9 创建断点和取消断点 断点的重要作用,可以在程序的任意位置设置断点。 这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。


F10 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。 F11 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最 长用的)。


CTRL + F5 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。


首先就是查看临时变量,适用于调试开始阶段,用于观察变量的值。


be731cc168c74a61bbb4fa14630f8eea.png


我们也可以查看相应的内存信息:


af476e104c434a558c08dafd0d911202.png


还可以查看调用堆栈:


42feafebd96d41db9080e86e02f97d6f.png


可以查看汇编代码 :


d4dde501f2464ed5ac4c0a76cc6ded28.png


可以查看寄存器信息:


33799052b8b146a586ee6e8c7d0cdbeb.png


这些调试工具我们都要好好去使用,可以将代码的bug快速找出,熟练掌握调试技巧。


举个例子求阶乘相加的和:


int main()
{
 int i = 0;
 int sum = 0;//保存最终结果
 int n = 0;
 int ret = 1;//保存n的阶乘
 scanf("%d", &n);
 for(i=1; i<=n; i++)
 {
 int j = 0;
 for(j=1; j<=i; j++)
 {
 ret *= j;
 }
 sum += ret;
 }
 printf("%d\n", sum);
 return 0;
}


我们知道1!+2!+3!=9,但是我们在这个程序中却运行的是15,那问题是出在哪呢,我们就用调试来找出其中的问题。


a79f5ba4e7e34d84a26fd6f1a2a488c2.png


当我们在运行到第3次循环时,3!=6,但是在运行到求3!时答案得到12,我们就由此分析是ret在每一次算阶乘时没有清0导致成2!*3!=12,所以我们应该修改程序,使在每一次循环时使ret=1即可。


int main()
{
  int i = 0;
  int sum = 0;//保存最终结果
  int n = 0;
  int ret = 1;//保存n的阶乘
  scanf("%d", &n);
  for (i = 1; i <= n; i++)
  {
    int j = 0;
    ret = 1;
    for (j = 1; j <= i; j++)
    {
      ret *= j;
    }
    sum += ret;
  }
  printf("%d\n", sum);
  return 0;
}


66f45697b2d543219d55a28c1be392cc.png


现在就是正确的程序了!


编程中常见的错误


1. 编译型错误 直接看错误提示信息(双击),解决问题。或者凭借经验就可以搞定。相对来说简单。


2.链接型错误 看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在。一般是标识符名不 存在或者拼写错误。


3.运行时错误 借助调试,逐步定位问题。最难搞。


所以我们一定要用好调试这个技巧,争取做到:代码运行正常 、 bug很少 、 效率高 、可读性高 、 可维护性高 、注释清晰 、文档齐全 。当一个优秀的程序员!

目录
相关文章
|
程序员 C语言
C语言--调试技巧(下)
C语言--调试技巧(下)
|
7月前
|
C语言
C语言使用宏定义实现等级调试输出PRINT_LEVEL
C语言使用宏定义实现等级调试输出PRINT_LEVEL
131 0
|
2月前
|
C语言
C语言调试
C语言调试
19 0
|
4月前
|
C语言 索引
C语言编译环境中的 调试功能及常见错误提示
这篇文章介绍了C语言编译环境中的调试功能,包括快捷键操作、块操作、查找替换等,并详细分析了编译中常见的错误类型及其解决方法,同时提供了常见错误信息的索引供参考。
|
6月前
|
存储 编译器 C语言
C语言学习记录——调试技巧(VS2019环境下)
C语言学习记录——调试技巧(VS2019环境下)
55 2
|
7月前
|
NoSQL Linux Redis
redis源码调试---vscode使用技巧-----C语言跳转到函数定义
redis源码调试---vscode使用技巧-----C语言跳转到函数定义
122 0
|
7月前
|
程序员 C语言 C++
C语言实用的调试技巧
C语言实用的调试技巧
52 3
|
6月前
|
程序员 编译器 C语言
C语言中的assert.h:调试助手与断言详解
C语言中的assert.h:调试助手与断言详解
|
7月前
|
程序员 编译器 测试技术
C语言初阶⑨(调试)(如何写出好的代码)(模拟实现strcpy和strlen)
C语言初阶⑨(调试)(如何写出好的代码)(模拟实现strcpy和strlen)
50 1
|
程序员 C语言
【C语言】如何写出好(易于调试)的代码——assert和const的使用
【C语言】如何写出好(易于调试)的代码——assert和const的使用
53 0