【C语言】实用调试技巧-创新互联

目录

成都创新互联公司-专业网站定制、快速模板网站建设、高性价比斗门网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式斗门网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖斗门地区。费用合理售后完善,十多年实体公司更值得信赖。

什么是Bug

什么是调试

Debug与Release的区别

如何调试

const的作用


作为准程序员,我们也敲了不少行代码,曾几何时,为了错误绞尽脑汁,为了bug哭天喊地。说到bug,背后有什么有趣的故事,如何规避bug呢??这篇文章让你了解何为调试,如何调试,一起来看下去吧~

什么是Bug

bug,英文意思为昆虫或臭虫,看名字就知道人们对它有多深恶痛绝了。历史上第一个bug是由一只飞蛾引起的(也算是虽死犹生,名流千古了哈哈)。在编程中就是指程序错误。

什么是调试

调试英文名为debugging(或debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的过程。

对freshman来说,一个工程中80%的时间在敲代码,20%的时间在调试;而对高手来说,20%敲代码,80%调试。俗话说得好,一名优秀的程序员就是一名优秀的侦探,与bug斗智斗勇的过程就是调试。

Debug与Release的区别

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地用。

Debug和Release版本下代码结果和反汇编等等都是不一样的。

这里举个小栗子,来看看编译器是怎么区别对待Debug和Release的。

#define _CRT_SECURE_NO_WARNINGS
#includeint main()
{
    int i = 0;
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    for (i = 0; i<= 12; i++)
    {
        arr[i] = 0;
        printf("hello world\n");
    }
    return 0;
}

我们可以看见,如果是 debug 模式去编译,程序的结果是死循环,程序崩溃了; 而如果是 release 模式去编译,程序没有死循环。这便是优化导致的结果。

在Debug环境下,代码详细运行过程如下:

调试时打开监视窗口,如下:

当 i 越界访问到 arr [12] 时,本该和arr [10],arr [11] 一样,将arr [12] 改为0,凑巧的是,i 的地址和arr [12] 的地址是同一空间,arr [12]里放的数组就恰好等于 i 的值,都是12,在arr [12] 被改为0时,i 的值也变为0,然后0<= 12,满足循环条件,每当 i = 12后就会被改为0,这样 i 永远到达不了13,程序也就陷入了死循环。

这确实是巧合,但又确实存在,可这又是为什么呢?这里我们通过画图的方式来解释:

该代码仅在VS2019 X86 的环境下使用,其他情况不一定,不用在此纠结,给出这个例子是想告诉我们调试的重要性,摸不着头脑时调试可以有效解决问题哦~

如何调试

1.环境准备:

将编译器切换到Debug版本下,Release版本不可调试。

2.快捷键:

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

F9 :创建断点和取消断点

F10 :逐过程,不可进入函数

F11 :逐语句,每次都执行一条语句,可以进入函数内部

CTRL + F5 :开始执行不调试

以上就是最常用的快捷键啦,当然还有许多许多,可以看看这个博主的VS中常见的快捷键,总结的很详细哦~

3.查看信息:

注意注意注意,以下查看都是在已经开始调试的条件下才有的,没有调试看不见!!!

①临时变量:调试——窗口——监视——任选其一

如果选了监视底下的自动窗口,编译器会自动识别程序的临时变量并监视,虽然很方便,但不一定是我们想要监视的量,比如进入函数后函数外的临时变量就没办法监视了,有一定的局限性,不建议使用。

②内存:调试——窗口——内存——任选其一

③堆栈:调试——窗口——调用堆栈

调用堆栈可以清晰的反应函数的调用关系以及当前调用所处的位置

④反汇编:法一:鼠标右键——转到反汇编

法二:调试——窗口——反汇编

寄存器:调试——窗口——寄存器

常见的 coding 技巧: 1. 使用 assert; 2. 尽量使用 const; 3. 养成良好的编码风格; 4. 添加必要的注释; 5. 避免编码的陷阱。 const的作用
const *p   and  * const p 1. const如果放在 * 的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。 2. const如果放在 * 的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。
int main()
{
	int a = 10;
	int b = 20;

	int* const p = &a;
	*p = &b;//ok
	p = 20;//err

	const int *p = &a;
	*p = &b;//err
	p = 20;//ok

	return 0;
}

常见错误:编译型错误,链接型错误,运行时错误

面对Bug,我们要做的就是做一个有心人,积累排错经验。代码会越写越熟练,我们找错的能力也会越来越高,Bug不是绊脚石,而是成长的必经之路。相信在若干年后,我们会感谢曾经写过的Bug(强行煽情了属于是,我才不感谢呢(bushi  ),继续和它们斗智斗勇吧!!

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:【C语言】实用调试技巧-创新互联
文章地址:http://ybzwz.com/article/pscjc.html