VS调试技巧 + strcpy函数

来源:互联网 发布:杂化材料的功能优化 编辑:程序博客网 时间:2024/06/10 14:06
实用调试技巧
错误:语法错误,链接性错误,运行时错误(跑的结果不是我想的要)
程序执行 = 编译 + 链接

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

步骤:
1.发现程序错误(软件测试人员或自己发现)
2.以隔离,消除等方式对错误进行定位
3.确定错误产生的原因
4.提出纠正错误的解决方法
5.对程序错误予以改正,重新测试

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

Release

Debug版本下,存在调试信息,当转到反汇编时会有大量的汇编代码
Release下,把调试信息都保存起来了,只有保留这个程序所需要的
因为Release下没有汇编代码,所以Release下不能调试

测试人员测试的时Release版本下的程序。因为卖給用户的是这个版本,所以叫发布版本

Windows环境下的调试
VS2008快捷键 F5 启动调试 程序一闪而过,编译完成,但不执行。
F9 断电 先用F9打个断点,再F5程序执行到断点停下来,这就便与代码很长时调试。可以设置多个断点,再次F5就到下一个断点,注意for循环中设置一个断点,这个断点的 下一个断点是下次循环的这个地方
如果for( i = 0; i< 10000; i++)如果你想让他执行到i==5000时停下来,一次一次就很饿麻烦,所以可以右击断点,有个条件,设置 i == 5000
F10 一步一步调试,一句一句执行
F11 进入函数内部

还有这些快捷键

ctrl + F5 让程序不调试直接运行起来

程序调试时,调试 ----窗口------监视 这样可以查看临时变量的值
调试------窗口-----自动窗口 跟监视作用相同,不过会把代码中所产生的变量自动罗列,不能删除
调试----窗口----局部变量 跟自动窗口效果相同,不过只显示上下文的局部变量
调试-----窗口-----内存 可以查看变量在内存中的存在形式
调试---窗口----调用堆栈 当函数嵌套调用时,可以查看函数的调用逻辑,以栈的形式显示。

所以这个说明main函数也是被其它函数调用的。
source insight

查看汇编
调试---鼠标右键转到反汇编

调试 ----窗口 ---寄存器 查看寄存器。


如何写出易于调试的代码
1.效率高
2.可读性高
3.可维护性高
4.可扩展性高
5.注释清晰
6.文档齐全

常见的coding技巧
1.使用assert
2.尽量使用const
3.养成良好的编码风格
4.添加必要的注释
5.多多总结编码的陷阱

strcpy()在复制的时候,不管空间有多大,它只看目标字符串,复制到\0,包括\0
自己写一个strcpy()函数



最后一句因为*src == \0 ,表示最后把\0也拷贝进去
提升B格

但是这个代码时有问题的
如果int *p = NULL; *p = 20; //这种时候就有问题了
我们对指针访问时应该是严谨的所以应该加上判断指针是否为空

但这样的话,每次进入函数都要判断一次,这样效率就很差
所以我们引入assert(); //断言
如果括号里面的表达式为假,它就会报出一个错误,如果括号里为真,就过去了
使用时引入头文件
#include <assert.h>

assert报出的错误会直接提示在什么位置
注意:assert只在Debug中起作用,在Release中会自动优化掉
但并不是所有的指针都不能等于空,它在*时是不能为空的,但有时候可以为空,所以是否要判断指针为空要看情况。比如指向链表的指针为空,就表示这是一个空链表,这时空指针是合法的。
但原来的strcpy是有返回值的,所以也应该加上,为了实现链式访问

因为循环完后,dest的地址已经不是首地址了,所以开始应该保留一份。

假如你在写程序的时候赋值语句写反了,但是它编译过去了,虽然会报错
但是如果我们此时加上const

这是你如果写反了,它就不会编译过去,便于调试。这样就是程序变得健壮。

const 定义的量为常量,当时可以通过指针来更改常量的值,这样的作法就是不安全的
指针可以用const修饰
const int *p; //也可以 int const *p;
这样修饰指针,他就不能通过地址更改常量的值了。

但是这样写也不会报错
int * const p
这样表示指针变量不能改变
比如 p = num1; 那么下面就不能 p = num2;不能改变它的指向

const int num = 10;
int *p = &num; //会报一个警告,因为num,其实是const int 行的地址
你把它赋给了一个 int * 所以是不安全的。

总结:



这是库中的函数

唯一不同的是__cdecl
表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

所以在自定义函数的时候,在需要的时候加上const

编译性错误:
查看错误提示信息(双击),解决问题。或者拼接经验就可以搞定
链接型错误
主要在代码中找到错误信息中的标识符,然后定位问题所在一般是标识符名不存在或拼写错误
运行是错误
借助调试,逐步定位问题,最难搞。

原创粉丝点击