ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:23.83KB ,
资源ID:4279602      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4279602.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C语言程序调试.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C语言程序调试.docx

1、C语言程序调试一:深入了解 编译、链接、组建(Look into Compile、Linking、Build)(1) Compile(2) Linking(3) Build二:断点 (Break Point)(1) 普通断点 (Nomal Break Point)(2) 条件断点 (Condition Break Point)(3) 数据断点 (Data Break Point)三:断点之后能做些什么?(What can I do after Break Point)(1)variables(2)watch(3)stack(4)memory四:断言 (Assert)五:printf()六:Lo

2、g七:Trace八:虚拟内存简介(Virtual Memory Intro )九:常见的段错误 (Common Segmentation Fault)(1)堆区内存错误 (Heap Memory Errors)1,未初始化的内存仿问 (Uninitialized Memory Access)2,无效的内存仿问 (Invalid Memory Access)3,内存泄露 (Memory leaks)4,未分配内存 (Missing allocation)(2)栈区内存错误 (Stack Memory Errors)1,未初始化的内存仿问 (Uninitialized Memory Access)

3、2,无效的内存仿问 (Invalid Memory Access)3,数组越界 (Writing off the end of the array)4,栈溢出 (Stack Overflows)十:轻松解决 内存泄漏 (Hunting Memory Leaks)结束语:怎样尽可能的避免错误*/下面就开始祥细讲解,/一:深入了解 Compile、Linking、Build(1)Compile - 编译当您点击 编译按钮时,编译器将会把你的源代码文件 (.c文件)转换为目标文件(.obj文件) ,目标文件包含的是源代码文件翻译后的机器语言。这些是不能被直接运行的,还需要 链接器将此中间代码与其他代

4、码相结合来生成可执行文件。请转看 Linking,Compile时,编译器通常会给你2种类型的提示:warnings 和 errorswarnings别小看 warnings ,它有可能会导致相当严重且极其隐蔽的 bug,尤其是在 指针管理内存 这一块,/常见的warning有以下几种类型1,使用了未经初始化的变量,或者定义变量了却没有使用。解析: 未经初始化的变量会 存一个随机值,绝大多数的时候这个值都不是你想要的,你用它,编译器能不给你warning吗,?2,使用了一些看上去非常愚蠢的语句,编译器都看不下去了例如, if (blueguy = 0) printf(blueguy = 0!)

5、; if(blueguy & greengirl | hemy) ;3, 使用了未定义的语句 (注意,vc6.0是不会给这样的语句一个warning的)例如, j = i+ + i+; /我自己都不知道自己想表达什么意思 , 呵呵 x = x0 ? x+ : x-;4,类型不匹配例如, char * blueguy = (int*) greengirl;本意是按单字节仿问内存的,结果却按四字节仿问内存, 你感到崩溃,我感到崩溃,编译器也感到崩溃,估计编译器会真的崩溃了 ,/5, 函数原型明明写着有返回值的,结果函数体内却没有 return一个值, 反之亦然。例如,int main(void)或

6、者void main()14 return 0;.等等,等等,等等。/好了,warnings 就简单介绍到这里了,希望您写的程序里 一个 warning也没有errors出现errors时,相对来说比较好解决一些, 通常编译器会给你明确的提示像,syntax errors, unexpected parenthesis , unexpected end of file之类的,常见的errors有以下几种类型(1)语句缺少 ;号例如,for(;)struct bluguy int x;(2)括号不匹配例如,int main(void)if (!blueguyCompile就这样结束了,下面接着看

7、 Linking(2)Linking - 链接vc6.0上是没有 Linking按钮的,或许是 我菜了,/ 没注意到vc6.0的 Build 把 Compile与Linking合在一起了 ,/链接的作用是将目标代码、系统的标准启动代码和库代码结合在一起,生成可执行程序。在你Compile的时候,编译器假定所有的结构体、函数、全局变量都已经在别的文件里声明了,但这个假设并不总是成立的,链接器就是在文件中查看这些结构体、函数以及全局变量是不是已经声明了,/常见的Linker Errors有以下几种,1, undefined function - 不明确的函数 (这可能是函数参数不匹配 或者未包含相

8、应的库 或者函数没有函数原型造成的,/)2,could not find definition for X - 使用的变量未定义,3,multiple definitions - 多重定义(多个文件定义了相同的函数或全局变量)(3)Build - 组建Build没什么好讲的,就是集成了Compile与Linking 的功能。将Compile与Linking 分隔开来 ,可以让你能够单独编译文件,总之是为了方便管理的,/顺便说一下,当您的程序出现了,warning 或者 Errors 的时候,双击一下提示信息就可以定位到那一行,/二:断点(1) 普通断点,图1nomal.jpg (60.42 K

9、B)普通断点是最简单, 也是最常用的,只要在能够下断点的位置下上断点(按下F9,有的行是不能下断点的),上图中,断点下在 blueguy = 0;这条语句上,也就是第9行,以下简称第9行,好,按下 F5, 程序立马就断在 blueguy = 0; 这条语句上。断下来有什么用?请跳转本文列表三:断点之后能做些什么?(2) 条件断点1 - 遇到断点一定次数后断下来还是在图1的第9行下个断点,然后,按下 Ctrl+b, 弹出如下对话框图2condition1.jpg (32.56 KB)单击,atblueguy.c.9 这一行后,弹出如下对话框图3condition2.jpg (39.05 KB)好

10、,现在单击 Condition按钮,弹出如下对话框图4condition3.jpg (50.53 KB)接下来, 在stopping标识的文本框内填上一个你想要填上的数字,这里填的是 6。好,单击 OK按钮 ,再次按下 F5, 程序断在了第9行。此时按下 Ctrl+b 可以看到图5condition4.jpg (34.93 KB)(2) 条件断点2 - 某个变量(普通变量或指针变量)的值发生变化时断下来还是在第9行下上断点, 先按下F5,程序断在了第9行,按下 Ctrl+b弹出如下对话框condition2.jpg (39.05 KB)再按下 Condition按钮,弹出如下对话框condit

11、ion3.jpg (36.24 KB)在Enter the expression to be evaluated标识的文本框下写上你想写入的变量,这里写的是 blueguy, 再按下 F5, 好,程序断在了第9行,并伴有下图提示condition5.jpg (24.97 KB)(3)数据断点 - 某个表达式的值为真时断下来还是在第9行下上断点, 先按下F5,程序断在了第9行,按下 Ctrl+b4condition2.jpg (39.05 KB)单击下Date按钮,弹出如下对话框,data1.jpg (41.11 KB)在Enter the expression to be evaluated标

12、识的文本框下写上你想写的表达式,这里写的是 greengirl = 6好,先按下F9撤消断点,再按下F5, 程序断在了第9行,伴有下图提示:见下楼,data2.jpg (33.24 KB)如果你嫌麻烦的话,你也可以这样下断点if (greengirl = 6) blueguy = 0;不过这样做,调试过后你得记得删除它,否则会给阅读代码选成 视觉障碍,好了,怎样下断点就讲到这里,如果你细心的话,会发现还有个 Message按钮, 那是消息断点,不怎么常用,不在我的讲解之列 ,/三:断点之后能做些什么?先上张大图debug.jpg (146.13 KB)假设程序断在了第9行(1)variable

13、s这个窗口可以查看 自动变量的值,不过他的最大用途在于查看函数的返回值。假设 有这样一个程序段#include int blueguy(void)return 5;int sum(int a, int b)return a+b;int main(void) printf(%d, sum(5, blueguy(); return 0;如果,我想查看 sum() 以及 blueguy()的返回值,如果不使用 variables窗口,我就得 定义两个变量来接收 sum() 以及 blueguy()的返回值,例似这样的语句,int greengirl = blueugy(). 是不是? 很幸运, va

14、riables窗口为我们省去了这个麻烦。现在我们把断点下在 return 0; 按下 F9, 程序断下来。看下面这张图, 很惊喜吧,Autos.jpg (59.43 KB)(2)watch点击调试工具条上的 watch按钮1,现在想查看下greengirl的值,只需把光标放在 greengirl上选中,拖到 watch窗口里就行了2,watch窗口中,在整形变量后面加上,c可以显示该变量对应的ASCII字符,也可以直接敲数字这么显示,比如118,c的对应值是v, v,d就是显示字符v对应的十进制ASCII码值 是118, v,x显示的是对应的十六进制的ASCII码值3, 数组名后加上,N (N

15、表示表示数组元素个数) 可以查看该数组的值, 对于查看大型数组的尾部数据比较方便例如, int blueguy10010 = .;watch窗口中, 输入blueguy99, 10, 可以看到二维数组最后一维的数据。4, watch可以计算简单算式的值,例如: blueguy - greengirl(3)stack点击调试工具条上的 stack按钮假设现在内存崩了,且崩在了第9行,stack 显示了函数的调用关系, 可以逐级向上检查错误(4)memory点击调试工具条上的 memory按钮memory窗口可以查看指针所指的内存区域里的值,使用时,把指针的值放在Address里就可以了,这在查看

16、声音、图片、文件等大型数组的值时相当方便(5)disassembly有时内存崩了,弹出这个反汇编窗口,在这个窗口里可以看到相应的函数,不过用途不大。还有两个不常用的窗口, 不在我的讲解之列断点之后能做些什么?就简单的介绍到这里了,反正这些都是很常用的,具体怎么用不在我的讲解之列四:断言使用断言时,先加上 头文件, 断言是在条件表达式不成立的情况下,终止程序。断言是用来调错的,不要用来作为异常处理语句假设 现在内存崩了,并且程序中有如下代码char *blueguy = malloc(10000);我现在想看看 是不是blueguy分配失败了,可以这样写个 断言char* blueguy = m

17、alloc(blueguy);assert(blueguy);现在假设 blueguy 分配失败,为空,那么编译器就会弹出类似下图的提示框回复4assert.jpg (32.26 KB)这个窗口上面写着 错误在哪一个文件,哪一行 ,此时找到那个文件,按下 ctrl+g,在框内填上行数就可以定位到那一行。/五: printf()现在讲解下深受控制台下编程的朋友钟爱的printf()函数; 但请注意,不要迷恋 printf();因为他的功能并不是那么强大,想查看某个值的时候,断个点就可以,不用花力气去书写 printf()输出语句。不过printf()也有它的优点,想查看变量之外的信息的时候,还是

18、很有用的比如说,我想看下 汉诺塔 递归程序的 函数调用路径可以 定义一个 监视变量 表示递归深度 ,/Example:/声明:本人不保证程序能够正确运行,#include void Hanoi(int n, char a, char b, char c) if ( n = 1 ) while(n-) printf( ); printf(Hanoi(%d, %c, %c, %c)n, n, a, b, c); /cout a b %cn, a, b); return ; while(n-) printf( ); printf(Hanoi(%d, %c, %c, %c)n, n, a, b, c)

19、;/先将n-1个盘子,以b为中转,从a柱移动到c Hanoi( n-1,a,c,b);/将一个盘子从a移动到b /cout a b %cn, a, b);/将c柱上的n-1个盘子,以a为中转,移动到b柱 Hanoi( n-1,c,b,a);int main(void) int N; scanf(%d, &N); Hanoi(N,A,B,C); return 0;当然,printf()还有其他的用途,关键看你怎么用了,不在我的讲解之列六:Log有时候,前面介绍的调试技术(本文已经通过 编程中国ISO9001认证)并不能直观的看到数据的变化,比如 watch窗口太小了,放不下那么多的值.Log是j

20、ava/c#中的名词,c 语言是没有提供这个调试功能的,实际上所谓的Log也没什么东西,无非是打开文件,写入数据罢了。我们可以用 c语言 的 fopen() 、fwrite ()等文件操作函数来仿写 Log这里要介绍两个用于调试的重要的宏_FILE_ 表示 文件名_LINE_ 表示调用语句所在的行数Example:/声明:本人不保证程序能够正确运行,void Log(void) char bugInfo200; pFile = fopen (E:blueguyDebug.log, , a+ ); sprintf(bugInfo, File: %s Line: %d: Here is a bug

21、, _FILE_, _LINE_); fwrite (bugInfo, sizeof(bugInfo0) , sizeof(bugInfo) , pFile ); fclose (pFile);/*一套完整的日志接口*/void bgOpenLog(void)4 if(Log = NULL) Log = fopen(log.txt, w);void bgWriteLog(const char* s) fwrite(s, sizeof(char), strlen(s), Log);void bgCloseLog(void) fclose(Log); Log = NULL;不再多说了,继续看下一个

22、调试技术七:Trace假设你现在 在写windows应用程序, 程序出错了,你想用printf()函数来输出信息, 很遗憾的告诉你,可能没有,这个时候,您可以使用 可变参数来仿写 printf()函数Example:/声明:本人不保证程序能够正确运行,Trace(const char* fmt,.) char text256; va_list ap; if (fmt = NULL) return; va_start(ap, fmt); vsprintf(text, fmt, ap); va_end(ap); /在屏幕上画出这个字符串八:虚拟内存简介 (Virtual Memory)每一个跑在你

23、的操作系统的应用程序都有一个唯一的地址空间。这些地址空间看起来是连续的内存块,实事上,它们并不是物理上连续的内存,仅仅是操作系统给应用程序的一个镜像空间-虚拟内存.每个应用程序可利用的虚拟内存一般划分为六个段:环境变量段 - 用于存储环境变量和命令行参数。栈 - 用于存储函数参数,自动变量等。堆 - 用于动态分配内存两个数据段 - 分别用于存储 初始化和未初始化的 静态变量或全局变量文本段 - 用于存放实际的代码九:常见的段错误 (Common Segmentation Fault)(1)堆区内存错误 (Heap Memory Errors)1,未初始化的内存仿问 (Uninitialized

24、 Memory Access)#include #include #include int main(void) char *pStr = (char*) malloc(512); char c = pStr0; / the contents of pStr were not initialized2,无效的内存仿问 (Invalid Memory Access)#include #include #include int main(void) char *pStr = (char*) malloc(25); free(pStr); strcpy(pStr, blueguy)/ Invalid

25、 write to deallocated memory in heap3,内存泄露 (Memory leaks)#include #include #include int main(void) char *pStr = (char*) malloc(512); return;4,未分配内存 (Missing allocation)#include 4#include #include int main(void) char* pStr = (char*) malloc(20); free(pStr); free(pStr); / results in an invalid dealloca

26、tion(2)栈区内存错误 (Stack Memory Errors)1, 无效的内存仿问 (Invalid Memory Access)#include int* blueguy(void);int main(void) int *greengirl = NULL; greengirl = blueguy(); printf(%d, greengirl0); return 0;int* blueguy(void) int a10 = 1,2,3,4,5,6,7,8,9,10; return a;2,未初始化的内存仿问 (Uninitialized Memory Access)#include #include #include int main(void) int a; int b = a * 4; / uninitialized read of variable a3,数组越界 (Writing off the end of the array)/#include #include #include int main(voi

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1