C语言初阶-实用调试技巧(1)

简介: C语言初阶-实用调试技巧

1.什么是bug?

bug是飞蛾、臭虫的意思,世界上第一台计算机在工作时发现机器不工作了,当时的计算机科学家就在计算机中检查,结果发现一个飞蛾死在晶体管上了,清理后计算机又能继续工作了,工程师就把那只飞蛾贴在工作日志上,从此bug变成了运行异常的代名词。

2.调试是什么?有多重要?

我们说一名优秀的程序员就是一名出色的侦探。

每一次调试都是尝试破案的过程。

2.1调试是什么?

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

2.2调试的基本步骤

1.发现程序错误的存在

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

3.确定错误产生的原因

4.提出纠正错误的解决办法

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

2.3Debug和Release的介绍

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序

Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好的使用。

编译器中可以选择版本:

下面我们来对比一下两个版本:

Debug版本:我们可以进行按F10键一步一步的调试,观察代码运行的过程

但是Realse版本中,按F10调试时,会直接跳过中间的运行过程,直接到运行的结果。

Realse版本是站在用户的角度,用户不需要调试代码,只需要最终的效果,所以一般Realse文件的大小比Debug文件更小,如果打开我们写代码的文件夹就会发现,当我们用不同版本编译后都会产生各自的文件夹,

3.Windows环境调试介绍

3.1调试环境的准备

在环境中选择debug选项,才能使代码正常调试。

3.2学会快捷键

想要学会调试,了解简单的快捷键必不可少。

F10:

逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。

F11:

逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(只是最常用的)。

这两种快捷键差不多,只不过,F10调试时会直接执行完函数,然后跳过,我们看不到函数的执行过程,而F11可以进入到函数内部,一步一步的执行完函数内部的每条语句。

F5:

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

F9:

创建断点和取消断点

短点的重要作用,可以在程序的任意位置设置断点。

这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

F5和F9是配合使用的:

可以对下面代码先按F5调试一下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
test()
{
  printf("hehe\n");
  printf("happy\n");
}
int main()
{
  int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
  int i = 1;
  test();
  return 0;
}

我们可以发现,按F5调试会直接运行出结果,中间不停歇,那如果我们要想在代码的某一步停下来怎么办?

这时候就可以用F9键了,点击想要停下的那一行代码,然后按F9键,会发现这行代码前面出现一个圆形的红色标记,这就是断点的设置,

这时我们再按F5键就会发现,代码运行到断点标记的这一行就停住了,我们可以自行按F11键(或F10键)调试后面的代码。

通过监视窗口也可以看到,程序运行到第12行就停止了。

那如果说我们现在有不想再第12行停下来了,怎么办?

和设置断点的步骤相同,只需再次点击第12行,并且按F9键就会发现断点消失了。

所以F9键的作用不止是设置断点,还有取消断点。

注意:在设置两个断点时,按F5键永远只会在第一个断点停住,如果想在下一个断点处停住,只有取消前面的断点。

其实我们在设置断点之后还可以附加条件,比如下面一段代码:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
test()
{
  printf("hehe\n");
  printf("happy\n");
}
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    arr[i] = i;
  }
  for (i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  test();
  return 0;
}

如果我不想再 i = 0的时候停下,我想在 i = 5的时候停下来,我们可以鼠标右击断点,找到条件,

然后添加条件为 i == 5,

接着再按F5键就会发现,程序运行到i = 5的时候停了下来。

Ctrl+F5:

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

什么意思呢?

就是如果我们已经设置了一堆断点,但是又不想在断点处停下来,这时直接按Ctrl+F5键,就可以直接执行完程序。(这和不设置断点时的F5键的作用一样)。

注意:如果说你的电脑上的F10、F11、F5等这些键按了之后不起作用,用Fn+F10、Fn+F11、Fn+F5就行。

3.3调试的时候查看程序当前信息

3.3.1查看临时变量的值

3.3.2查看内存信息

3.3.3查看调用堆栈

下面我们对这段代码,查看它调用堆栈的信息:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void test3()
{
  printf("haha\n");
}
void test2()
{
  test3();
}
void test1()
{
  test2();
}
int main()
{
  test1();
  return 0;

当我们打开调用堆栈窗口时会发现,每次调用函数时,main函数上面就会出现其他函数,直到调用完,最顶上是test3函数,往下依次是test2、test1、main函数。

而当调用完所有函数后,开始返回,也是最顶上的函数先消失,最后只剩下main函数:

为什么会出现这样的情况呢?

这就需要讲一点数据结构的知识了。

数据结构中有栈和队列,数据在栈中存放时,只能从栈顶入,从栈顶出。而数据在队列时,只能从队尾进,队头出,就类似在食堂排队打饭一样,只能从队尾开始排,排到队头打到饭才能出。

3.3.4查看汇编信息

在调试开始之后,有两种方式转到汇编。

(1)第一种方式:右击鼠标,选择【转到反汇编】:

(2)第二种方式:

目录
相关文章
|
5月前
|
C语言
C语言初阶:如何判断是否为素数并且输出
C语言初阶:如何判断是否为素数并且输出
45 0
|
1月前
|
C语言
C语言调试
C语言调试
18 0
|
3月前
|
C语言 索引
C语言编译环境中的 调试功能及常见错误提示
这篇文章介绍了C语言编译环境中的调试功能,包括快捷键操作、块操作、查找替换等,并详细分析了编译中常见的错误类型及其解决方法,同时提供了常见错误信息的索引供参考。
|
4月前
|
编译器 C语言
【C语言初阶】指针篇—下
【C语言初阶】指针篇—下
|
4月前
|
存储 C语言
【C语言初阶】指针篇—上
【C语言初阶】指针篇—上
|
5月前
|
安全 编译器 程序员
【C语言】:VS实用调试技巧和举例详解
【C语言】:VS实用调试技巧和举例详解
50 1
|
5月前
|
存储 编译器 C语言
C语言学习记录——调试技巧(VS2019环境下)
C语言学习记录——调试技巧(VS2019环境下)
53 2
|
5月前
|
C语言
【初始C语言8】详细讲解初阶结构体的知识
【初始C语言8】详细讲解初阶结构体的知识
|
6月前
|
程序员 C语言 C++
C语言实用的调试技巧
C语言实用的调试技巧
48 3
|
5月前
|
程序员 编译器 C语言
C语言中的assert.h:调试助手与断言详解
C语言中的assert.h:调试助手与断言详解