VS调试技巧

目录

一、bug与调试

1.bug的由来

2.调试的定义与基本步骤

二、调试方法详解

1.调试所需要的环境

2.常用快捷键

3.查看调试过程中的数据与过程

三、示例

四、优秀的代码

五、编程的常见错误


一、bug与调试

1.bug的由来

Bug一词的原意是“臭虫”或“虫子”,现在通常被用来表示隐藏在计算机系统中的一些未被发现的缺陷或问题。

据记载,1945年9月9日,编译器发明者格蕾斯·哈珀中尉带领她的小组构造”马克二型”计算机。突然,马克二型死机了。技术人员试了很多办法,最后错误定位在第70号继电器上,发现上面有一只被电死的飞蛾。哈珀中尉将蛾子夹出来,用透明胶布贴到事件记事本中,并注明”第一个发现虫子的实例”。从此,人们把计算机错误戏称为Bug,而将发现Bug并纠正的过程称为”Debug”

2.调试的定义与基本步骤

(1)调试的定义

调试是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。

(2)调试的基本步骤

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

(3)Debug与Release两种模式

  • Debug称为调试版本,它在源代码的基础上不作任何优化,便于程序员调试程序。
  • Release称为发布版本,它往往是对程序进行了各种优化,例如减小程序大小和加快运行速度等,以便用户很好地使用。
  • 这两种状态下的代码运行结果可能会不同。
#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; 
}

这个代码在x86Debug条件下为死循环,而在x86Release条件下不为死循环。

二、调试方法详解

我们先以这个简单的代码为例

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i=0; i<10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

1.调试所需要的环境

x86(三十二位操作系统)或x64(六十四位操作系统)的Debug模式

我们可以点击F5或者点击VS上面的调试窗口点击开始调试

2.常用快捷键

(1)F5

作用:启动调试,经常用来直接跳到下一个断点处。当我们按F5时,程序会运行到你设置的断点处停止,再次按F5会程序继续执行到下一个断点,如果没有断点这个程序会运行至终点

(2)F9

作用:创建断点和取消断点

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

我们将光标移动到你想设置断点的代码上然后点击F9即可设置断点,下图的红色圆点就是断点,以后每次逻辑上走到这条语句下,程序都会暂停运行。

我们还可以对断点进行条件限制,右键点击红色断点,点击条件

在表达式的位置写上自己需要的条件,这样在程序运行的时候就会在满足这个条件的时刻停下来

结果:程序运行到i == 5的时候暂停

我们再以这个代码为例

#include<stdio.h>
int add(int x, int y)
{
	return x + y;
}
int main()
{
	int a = 10;
	int b = 20;
	int c = add(a, b);
	printf("%d", c);
	return 0;
}

(3)F10

作用:逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句,也就是每按一次执行一条语句。

注意:f10不能深入到函数内部,f11可以

点击F10后函数的内部执行过程被省略

(4)F11

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

点击F11可以观察函数内部的执行情况

(5)CTRL + F5

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

注意:这里程序直接执行到底,不考虑断点。

(6)想了解更多VS快捷键,您了这请:

(48条消息) VS中常用的快捷键_MrLisky的博客-CSDN博客_vs快捷键

3.查看调试过程中的数据与过程

下面的几个窗口都可以在这里找到,除此之外反汇编代码的查看也可以在代码处右击鼠标点击转到反汇编。

(1)监视窗口

在调试开始之后,在添加要监视的项中输入变量或表达式,就可以查看它们的值。

在VS中也存在一个自动窗口,这个窗口可以自己在监视窗口中添加和删除局部变量,但是自动窗口不利于程序员掌握整个程序的运行情况,故不常使用。

(2)内存

这个窗口可以告诉我们目前程序运行中,内存中数据的存储情况。其中最前面的淡色字体的十六进制数字表示地址,后面前四列的十六进制数字表示内存中储存的变量的值,四列以后的部分表示编译器对内存数据的解析,可以直接忽略。

储存举例:

对于这样的数据:0x00CFFECC 14 00 00 00

地址:0x00CFFECC

数据:14 00 00 00(数据采用小端储存方式,需要倒过来看)

0 0 0 0 0 0 1 4

0000 0000 0000 0000 0000 0000 0001 0100

其中每一个用空格隔开的数字表示一个字节的数据,而内部的每一个数字又表示四个比特位表示的内容,所以这个变量的值为2的平方加2的四次方等于20.

(3)调用堆栈

可以看到函数的相互调用情况。

(4)汇编代码

可以看到C代码的汇编代码,我们不需要学习汇编语言,但是我们可以了解一些专有名词,ebp,esp等等字符表示寄存器,用于储存少量数据。push表示压栈,mov表示移动,sub表示减等等。通过汇编代码,我们可以大致了解到程序运行过程中内存的使用。

3.练习方式

一定要熟练掌握调试技巧,多花时间在调试代码上,多多使用快捷键,提升效率。总之,多多练习。

三、示例

#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; 
}

这个程序死循环的原因:

在循环进行的过程中,随着i的增大,数组的元素不断被改为0,但存在数组的越界访问,同时元素的地址不断升高。由于程序压栈中优先使用高地址,存储在高地址的变量i也被改变为0,致使无法i大于12

四、优秀的代码

1.优秀的代码应该具备的条件

(1)代码运行正常

(2)bug很少

(3)效率高

(4)可读性高

(5)可维护性高

(6) 注释清晰

(7)文档齐全

2.常见的coding技巧

(1)使用assert

(2) 尽量使用const

(3) 养成良好的编码风格

(4)添加必要的注释

(5)避免编码的陷阱

3.实例

char * strcpy(char * dst, const char * src)
//加上const使需要拷贝的原内容不可通过这个指针修改,保护数据
{
    char * cp = dst;
    assert(dst && src);//断言dst和src不为空指针
 
   while( *cp++ = *src++ )//最后表达式为\0退出循环
        ;                       
    return( dst );返回新数组首元素地址,便于打印
}

4.const的使用

结论:

(1)const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改

变。但是指针变量本身的内容可变。

(2)const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指

针指向的内容,可以通过指针改变。

#include<stdio.h>
int main()
{
    int m = 0;
    int a = 0;
    const int* p1 = &a;
    p = &m;//可以
    *p = 10;//不可以
    int b = 0;
    int* const p2 = &b;
    p2 = &m//不可以
    *p2 = 20;//可以
    int c = 0;
    const int* const p3 = &a;
    p3 = &m//不可以
    *p3 = 20;//不可以
    return 0;
}

五、编程的常见错误

1.编译型错误

主要是语法错误,可以直接观察下方窗口的提示信息,通过经验就可以改正

2.链接型错误

依旧是看错误信息,一般是标识符名不存在或者拼写错误。最简单的例子就是有函数调用,但是忘记定义

3.运行时错误

此时程序可以运行,但是并没有显示我们预期的结果,主要通过调试来改正

  • 14
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值