调试的基本步骤:
1.发现错误的存在
2.以隔离,消除等方式对错误进行定位
3.确定错误产生的原因
4.提出纠正错误的解决方法
5.对程序错误予以改正,重新测试
debug和release
debug:调试版本,保存调试信息,不做任何优化,便于程序员调试
release:发布版本,往往进行了各种优化,是程序在代码大小和运行速度得到最优,以便用户更好地使用
【例子】
如下代码在debug和release下运行结果为:
#include <stdlib.h>
#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++)
{
printf("死循环");
arr[i] = 0;
}
system("pause");
return 0;
}
debug下:
release下:
学习调试:
F5:启动调试----与F9配合使用
F9:创建和取消,切换断点
F10:逐过程,每次处理一个过程
F11:逐语句,每次执行一条语句
shift+F11:跳出
ctrl+F5:开始执行,不调试
shift+F5:停止调试
查看调试信息:
监视,内存,调用堆栈,局部变量,自动窗口,寄存器等
实例一:
代码实现:求1!+2!+3!...+n!;不考虑溢出
int main()
{
int i = 0;
int sum = 0;
int n = 0;
int ret = 1;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
ret *= j;
}
sum += ret;
}
printf("%d", sum);
return 0;
}
输入 3;
得到错误结果:15
按F5调试,发现问题;
打断点127行,并设置条件
断点条件设置为第三次i循环
发现第三次j循环 ret初始值为2
发现j循环第三次结束 ret 不对
发现问题:ret循环后未初始化
改正问题:增加“ret = 1;” 赋值语句
修改后代码:
int main()
{
int i = 0;
int sum = 0;
int n = 0;
int ret = 1;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
int j = 0;
ret = 1;
for (j = 1; j <= i; j++)
{
ret *= j;
}
sum += ret;
}
printf("%d", sum);
return 0;
}
实例二
#include <stdlib.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++)
{
printf("死循环\n");
arr[i] = 0;
}
system("pause");
return 0;
}
运行结果:
开始调试:
按F5,打开监视,输入监视参数;
【debug情况下 栈示意图】
高地址
i的地址 |
a[9] |
. |
. |
. |
. |
. |
. |
a[2] |
a[1] |
a[0] |
低地址
如图,此时,当a[12]被赋值为0时,正好修改的为i地址的值,i也变为0,i自增后,程序陷入死循环
此时,在此vs2013编译环境下,如果修改代码i<=11,也可勉强修改错误;
在release版本下,却能运行,这是因为程序进行自我优化后,会优先定义数组arr,然后定义i,此时在栈中,i的地址比arr地址更低,则可避免死循环。
【如何写出易于调试的代码】
1.代码运行正常
2.bug很少
3.效率高
4.可读性高
5.可维护性高
6.注释清晰
7.文档齐全
常见的coding技巧
1.使用assert(断言
2.尽量使用const
3.养成良好的编码风格
4.添加必要的注释
5.避免代码的陷阱
示例:模拟实现库函数strcpy
//【优化代码】
#include<assert.h>
char* my_strcpy(char* x,const char* y)//const保护原数据
{
char* ret = x;
assert(x != NULL);//断言 如果为真什么都不发生,如果为假报错
assert(y != NULL);
//把y指向的字符串拷贝到x指向的空间,包含‘\0’
while (*x++ = *y++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "AAAAAAAAAAA";
char arr2[] = "123";
my_strcpy(arr1, arr2);
printf("%s\n", my_strcpy(arr1,arr2));
return 0;
}
“const”的使用,增强代码的强壮度
0