第八讲:VS实用调试技巧

1.什么是bug

bug本意是“昆⾍”或“⾍⼦”,现在⼀般是指在电脑系统或程序中,隐藏着的⼀些未被发现的缺陷或
问题,简称程序漏洞。

2.什么是调试(debug)

找到问题的过程叫调试,英文叫debug (消灭bug)

调试一个程序,首先是承认出现了问题,然后通过各种手段去定位问题的位置,可能是逐过程的调试,也可能是隔离和屏蔽代码的方式,找到问题所在位置,然后确定错误产生的原因,再修复代码,重新测试

3.debug和release

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

release称为发布版本,往往进行各种优化,使得程序在代码大小的运行速度上都是最优的,不包含调试信息

release版本和debug版本的对比:

release版本文件大小更小

测试人员测试的是release版本

4.VS调试快捷键

程序员怎么调试代码?

环境准备

需要一个支持调试的开发环境,应该把VS设置为Debug

调试快捷键

最常用的快捷键:

F9:创建断电和取消断点

        断点的作用是可以在程序的任意位置设置断点,以暂停程序

        条件断电:i=5是才触发断点

        

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

F10:逐过程,用来处理一个过程,一个过程可以是一次函数调用,或是一条语句,可以进行到函数内部

F11:逐语句,每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部,在函数调用的地方,想进入函数观察细节,就必须使用F10,直接完成函数调用

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

5.监视和内存观察

观察代码的前提条件一定是开始调试后观察

监视

打开监视窗口

在监视窗口观察

内存

如果监视窗口看的不仔细,也可以观察变量在内存中的存储情况

在内存窗口中观察数据: 

打开内存窗口后,要在地址栏输入:arr,&num,&c这类地址,就能观察到该地址的数据

除此之外,在调试的窗口中还有:自动窗口,局部变量,反汇编,寄存器等窗口

6.调试举例1

1!+2!+3!+4!+...10! 的和
//求 1!+2!+3!+4!+...10! 的和
#include<stdio.h>
int main()
{
	int i = 0;
	int j = 0;
	int c = 1;
	int sum = 0;
	for (i = 1; i <= 10; i++)
	{
		int c = 1;
		for (j = 1; j <= i; j++)
		{
			c = c * j;
		}
		sum = sum + c;
	}
	printf("%d", sum);
	return 0;
}


//代码优化
#include<stdio.h>
int main()
{
	int i = 0;
	int c = 1;
	int sum = 0;
	for (i = 1; i <= 10; i++)
	{
		c = c * i;
		sum = sum + c;
	}
	printf("%d", sum);
}

7.调试举例2

在VS2022、X86、Debug 的环境下,编译器不做任何优化的话,下⾯代码执⾏的结果是啥?
#include<stdio.h>
int main()
{
	int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("hehe\n");
	}
	return 0;
}

结果为死循环打印hehe

地址相同

       1. 栈区内存的使用习惯是从高地址向低地址使用的,所以变量i的地址是较大的。arr数组的地址整体是小于i地址的

        2。数组在内存中的存放时,随着下标的增长,地址是由低到高变化的

如果是上面的内存布局,那么随着数组下标的增长,往后越界就有可能覆盖到i,这样就会造成死循环。

为什么i和arr 数组之间恰好空出来2个整型的空间呢?
        这⾥确实是巧合,在不同的编译器下可能中间的空出的空间⼤⼩是不 ⼀样的,代码中这些变量内存的分配 和地址分配是编译器指定的,所以不同的编译器之间就有差异了。所以 这个题⽬是和环境相关的。
注意:
栈区的默认使用习惯就是先使用高地址,再使用低地址的空间,但是这个具体还是要编译器的实现,比如:在VS上切换到X64,这个使用的顺序就是相反的,在Release版本程序中,这个使用的顺序也是反的

8.调试举例3

复杂代码调试

演示:

        在函数内部打断点,快速跳转到函数

        在数组传参,调试进入函数时,如何在监视窗口观察数组内容:数组名,n的形式

一维数组通过形参关键数组的内容

二维数组通过形参关键数组内容

9.编程常见错误归类

编译型错误

编译型错误一般都是语法错误,在编译时就能发现,这类错误一般看错误信息就能找到一些蛛丝马迹,双击错误信息也能初步跳转到代码错误的地方或附近。编译错误随语言的熟练掌握会越来越少

链接型错误

看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在,一般是因为:

        标识符名不存在

        拼写错误

        头文件没包含

        引用的库不存在

LNK为link缩写,链接

运行时错误

运行时错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运行时的问题

  • 32
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值