vs实用调试技巧

vs实用调试技巧

什么是bug?

本意昆虫或虫子,现在指电脑里隐藏着的一些未被发现的缺陷或问题,电脑程序里的错误。

什么是调试?

找问题的过程称为调试–debug(消灭bug)
当程序已经存在问题时,去找问题的过程。调试时一个动作。

Debug和Release

  1. Debug通常称为调试版本。包含调试信息,不作任何优化
  2. Release称为发布版本。进行各种优化,使代码在代码大小和运行速度都是最优的,以便用户更好的使用。
  3. 编译生成的可执行文件中,Release版本小,debug版本大。
  4. 程序员在测试程序的时候,使用的是Debug版本。

vs调试快捷键

  1. F9:创建断电和取消断点
    断点:可以在程序的任意位置设置断点,打上断点就可以使程序运行到向要的位置。

条件断点:满足这个条件,才触发断点。(注意)

  1. F5 : 启动调试,直接跳到下一个断点处(Fn + F5).

  2. F10 : 逐过程,通常⽤来处理⼀个过程,⼀个过程可以是⼀次函数调⽤,或者是⼀条语句。(Fn + F10)

    在这里插入图片描述

我们去调试这个代码:
第一步: Fn + F9 , 我们在17行设置断点(红心)。(如上图)

第二步:Fn + F 10 , 逐过程调试。在调试的过程中我们发现:箭头在9 - 13行之间进行变化,在第9行进入程序,在第13行出程序,同时在监视2中我们能够观察到num[i] (i是数字 ,是变量)的值在变化(输入)。

第三步:Fn + F 5 , 箭头直接跳转到我们设置的断点处,也就是第17行。每按一次F5的键,我们在监视2窗口中的i值就会加1(第11行:num[i] = i + 1),只有i 的值在变化,一直加到8。(如下图)
在这里插入图片描述

注意:

  1. 如果我们将第17行的代码改为输入一个数字–》scanf("%d ",&num[ i ]);则需要先输入8个数字,然后从监视2窗口观察 i 值的变化。

  2. 设置两个断点:Fn + F5 -->跳转到第11行(i的值从1逐个增加到8) -->跳转到第18行(i的值从1逐个增加到8)–>调试结束(程序自动退出调试)

    在这里插入图片描述

  3. 条件断点:

    我们用鼠标右键点击11行前面的小红点,并点击条件,设置条件为i == 6 ,则点击Fn + F5时,i 的值会自动显示6。
    在这里插入图片描述

在这里插入图片描述

  1. F11 : 逐语句,这个快捷键可以使我们的执行逻辑进入函数内部,在函数调用的地方,想要进入函数观察细节,必须使用F11,直接完成函数调用。

    调试代码:

    在这里插入图片描述

    调试细节:

    第一步:首先程序从main函数开始(main函数是程序的入口)。接着,程序运行到第38行的时候跳转到了第26行,此时进入函数内部。

    第二步:第29行–>“you are beautiful!” ; 第31行–>25 ; 第40行–>“How are you?”

  2. Ctrl + F5 : 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
    在这里插入图片描述

监视和内存

  • 监视

    1. 开始调试(Fn + F10)–>窗口–>监视
    2. 监视的作用是让你观察到程序是如何一步步的执行的。监视看到的是变量和表达式的值。
  • 内存

#include<stdio.h>
int main()
{
	int arr2[9] = { 0 };
	int num = 15;
	char a = 's';

	int i = 0;
	for (i = 1; i < 9; i++)
	{
		arr2[i] = i;
	}
	return 0;
}
  1. 开始调试(Fn + F10)–>窗口–>内存
  2. 设置4列,因为数组是整型类型的数组
  3. 观察在这里插入图片描述

解析:
(1) 第一部分–>内存对应的地址 ;

(2) 第二部分–>内存对应的值(16进制形式展示) ;此处的"00"表示2个16进制位,一个“0”表示1个16进制位。1个16进制位等于4个2进制位,2个16进制位,表示8个2进制位,就等于一个字节。这一部分的“列”,我们可以自己进行调整,我将它调整为4列,一行有4个字节,则一行就是是1个整型类型所占的内存大小。

(3)第三部分 -->将内存中的值试图进行解析,参考意义不大。
4. 观察arr2的变化:
在这里插入图片描述

  • 自动窗口和内存
#include<stdio.h>
int main()
{
	int arr2[9] = { 0 };
	int num = 15;
	char a = 's';

	int i = 0;
	for (i = 1; i < 9; i++)
	{
		arr2[i] = i;
	}
	return 0;
}
  1. 自动窗口:自主的增加或减少一些值,使用时并不是很方便。

在这里插入图片描述

  1. 局部变量:将程序中运行到的局部变量进行监视。

在这里插入图片描述

调试举例

  1. 调试举例1:
    求1!+2!+3!+4!+. . .10 ! 的 和 :
#include<stdio.h>
int main()
{
	int n = 0;
	int i = 0;
	int ret = 0;
	int sum = 0;
	for (n = 1; n <= 3; n++)// 计算1到3的阶层的和,计算3个数的阶层和
	{
		ret = 1; //每个数字的阶层都是从1开始,是每个数字阶层展开的起点。
		for (int i = 1; i <= n; i++)//分别计算1! ,2! ,3! 
		{
			ret = ret * i;
		}
		sum = sum + ret;//1! + 2! + 3! 
	}
	printf("%d ", sum);
	return 0;
}

优化代码:

#include<stdio.h>
int main()
{
	int i = 0;
	int sum = 0;
	int n = 0;
	int ret = 1;//不可以写成int ret = 0 以及不可以写到循环内部。
	for (n = 1; n <= 3; n++)
	{
		
		ret = ret * n;
		sum = sum + ret;
	}
	printf("%d ", sum);
	return 0;
}
  1. 调试举例2.1:
#include<stdio.h>
int main()
{
	//int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("hehe\n");
	}
	return 0;
}

调试举例2.2:

#include<stdio.h>
int main()
{
	long i;
	long a[16];
	for (i = 0; i <= 17; i++)
	{
		a[i] = 0;
		printf("%d", i);
	}
	return 0;
}

在这里插入图片描述

解释 :
栈区内存的使⽤习惯是从高地址向低地址使⽤的,所以变量i的地址是较大的。arr数组的地址整体是小于i的地址。 数组在内存中的存放是:随着下标的增长,地址是由低到高变化的。那随着数组下标的增长,往后越界就有可能覆盖到 i,这样就可能造成死循环的。
思考:为什么i和arr数组之间恰好空出来2个整型的空间呢?
解释:,在不同的编译器下可能中间的空出的空间大小是不⼀样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以不同的编译器之间就有差异了。所以这个题⽬是和环境相关的。

调试举例3:扫雷(如何在监视窗口观察数组的内容:数组名,n)–>数组调试,形参如何观察到。

#include<stdio.h>
void test1(int arr3[])
{

}
void test2(int arr4[4][3])
{

}


int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8 };
	int arr2[4][3] = { 1,2,3,4,5,6,7,8,9,6,6,6 };

	test1(arr1);
	test2(arr2);

	return 0;
}

在这里插入图片描述

编程常见错误

  1. 编译型错误:一般都是语法型错误,是最简单的错误。
  2. 链接型错误:标识符名不存在 ;拼写错误 ;头文件没包含 ;引用的库不存在。
  3. 运行型错误:运行时错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运行时问题。
  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值