《2-Linux下的C 编程基础2.ppt》由会员分享,可在线阅读,更多相关《2-Linux下的C 编程基础2.ppt(79页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 嵌入式操作系统广州学院广东科学技术职业学院Linux下的C编程基础解决的问题:如何在Linux系统下开发C语言程序解决问题的具体步骤:l使用vi编辑器编辑源程序l使用gcc编译器编译源程序l使用gdb调试器调试程序l自动化编译(makefile文件和make工具)嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-11.欲进入vim编辑器(从命令行提示符),请输入vim文件名2.光标在屏幕文本中的移动既可以用箭头键,也可以使用hjkl字母键。h(左移)j(下行)k(上行)l(右移)3.欲退出vim编辑器,请输入以下命令放弃所有修改:q!或者输入以下命令保存所有修改:wq 嵌入式操作系统
2、广州学院广东科学技术职业学院vim命令学习-24.在正常模式下删除光标所在位置的字符,请按x5.在正常模式下要在光标所在位置开始插入文本,请按i输入必要文本特别提示按下键会带您回到正常模式或者取消一个不期望或者部分完成的命令 嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-31.欲从当前光标删除至单字/单词末尾,请输入dw2.欲从当前光标删除至当前行末尾,请输入d$3.欲删除整行,请输入dd 嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-44.在正常模式下一个命令的格式是numbercommandobject或者commandnumberobject其意是number-代
3、表的是命令执行的次数command-代表要做的事情,比如d代表删除.object-代表要操作的对象,比如w代表单字/单词,$代表到行末等等。$(totheendofline),etc.嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-4dnw:删除n个单词dne:也可,只是删除到单词尾dnl:向右删除n个字母dnh:向左删除n个字母dnj:向下删除n行dnk:向上删除n行d$:删除当前光标到改行的行尾的字母dd:删除一行 嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-45.欲撤消以前的操作,请输入u(小写的u)欲撤消在一行中所做的改动,请输入U(大写的U)欲撤消以前的撤消命
4、令,恢复以前的操作结果,请输入CTRL-R 嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-5粘贴:p,这是粘贴用x或d删除的文本复制:ynw:复制n个单词yy:复制一行ynl:复制n个字符y$:复制当前光标至行尾处nyy:拷贝n行完了用p粘贴 嵌入式操作系统广州学院广东科学技术职业学院vim命令学习-5:split:分割一个窗口:splitfile.c:为另一个文件file.c分隔窗口:nsplitfile.c:为另一个文件file.c分隔窗口,并指定其行数CTRLW在窗口中切换:close:关闭当前窗口 嵌入式操作系统广州学院广东科学技术职业学院1.源程序的编译在Linux下面,
5、如果要编译一个C语言源程序,我们要使用GNU的gcc编译器.下面我们以一个实例来说明如何使用gcc编译器.假设我们有下面一个非常简单的源程序(hello.c):#includeintmain()printf(WelcometoLinuxProgrammingn);return0;嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院1.源程序的编译要编译这个程序,我们只要在命令行下执行:gcc-ohellohello.cgcc编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.嵌入式操作系统广州学院广东科学技术职业学院1
6、.源程序的编译gcc-ohellohello.c命令行中gcc表示我们是用gcc来编译我们的源程序,-o选项表示我们要求编译器给我们输出的可执行文件名为hello而hello.c是我们的源程序文件.gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了.嵌入式操作系统广州学院广东科学技术职业学院1.gcc编译器选项-o选项,表示我们要求输出的可执行文件名.-c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件.-g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息.嵌入式操作系统广州学院广东科学技术职业学院1.gcc编译器选项知道了这三个选项,我们就可以编译我们
7、自己所写的简单的源程序了如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明.嵌入式操作系统广州学院广东科学技术职业学院2.多源文件的编译方法如果有多个源文件,基本上有两种编译方法:假设有两个源文件为test.c和testfun.ca.多个文件一起编译用法:#gcctestfun.ctest.c-otest作用:将testfun.c和test.c分别编译后链接成test可执行文件。嵌入式操作系统广州学院广东科学技术职业学院2.多源文件的编译方法b.分别编译各个源文件,之后对编译后输出的目标文件链接。用法:#gcc-ctestfun.c/将testfun.c编译成
8、testfun.o#gcc-ctest.c/将test.c编译成test.o#gcc-otestfun.otest.o-otest/将testfun.o和test.o链接成test 嵌入式操作系统广州学院广东科学技术职业学院2.多源文件的编译方法以上两种方法相比较,第一中方法编译时需要所有文件重新编译而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。嵌入式操作系统广州学院广东科学技术职业学院补充:如何利用gcc编辑”C+”GCC是个功能很强大,但精通的掌握它也许需要几个月的时间。例如:编写my_class.cpp和my_class.h包含你自己创建的一个类。写一个test.cpp
9、,里面包含main函数并且调用my_class。1、g+-cmy_class.cpp2、g+-o testtest.cppmy_class.o实际上对于C+程序员,只要记住g+命令,记住-c和-o两个参数,就可以开始用gcc了。嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写假设我们有下面这样的一个程序,源代码如下:/*main.c*/#includemytool1.h#includemytool2.hintmain(intargc,char*argv)mytool1_print(hello);mytool2_print(hello);嵌入式操作系统广州学院广东科学技术职业
10、学院3.Makefile的编写/*mytool1.c*/#includemytool1.hvoidmytool1_print(char*print_str)printf(Thisismytool1print%sn,print_str);/*mytool1.h*/#ifndef_MYTOOL_1_H#define_MYTOOL_1_Hvoidmytool1_print(char*print_str);#endif/*mytool2.h*/#ifndef_MYTOOL_2_H#define_MYTOOL_2_Hvoidmytool2_print(char*print_str);#endif/*my
11、tool2.c*/#includemytool2.hvoidmytool2_print(char*print_str)printf(Thisismytool2print%sn,print_str);嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写当然由于这个程序是很短的我们可以这样来编译gcc-cmain.cgcc-cmytool1.cgcc-cmytool2.cgcc-omainmain.omytool1.omytool2.o这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c),那么我们还
12、要重新输入上面的命令,非常的麻烦!嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.-Makefile.嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写.在我们执行make之前,我们要先编写一个非常重要的文件.-Makefile.对于上面的
13、那个程序来说,可能的一个Makefile的文件是:#注释行,这是上面那个程序的Makefile文件main:main.omytool1.omytool2.ogcc-omainmain.omytool1.omytool2.omain.o:main.cmytool1.hmytool2.hgcc-cmain.cmytool1.o:mytool1.cmytool1.hgcc-cmytool1.cmytool2.o:mytool2.cmytool2.hgcc-cmytool2.c 嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写有了这个Ma
14、kefile文件,不管我们什么时候修改了源程序当中的什么文件,我们只要执行make命令我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件不予理睬,节省了大量编译时间。嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写下面我们学习Makefile是如何编写的.在Makefile中#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:target:componentsTABrule/第一行表示的是依赖关系./第二行是规则.嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写比如说我们上面的那个Makefile文件的第
15、二行main:main.omytool1.omytool2.o表示我们的目标(target)main的依赖对象(components)是main.omytool1.omytool2.o当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行gcc-omainmain.omytool1.omytool2.o注意规则一行中的TAB表示那里是一个TAB键 嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的编写 嵌入式操作系统广州学院广东科学技术职业学院3.Makefile的常用变量Makefile有三个非常有用的变量:$
16、,$,$。其意义为:$:目标文件$:所有的依赖文件$:第一个依赖文件如果使用上面三个变量,上面那个Makefile文件可简化为:嵌入式操作系统广州学院广东科学技术职业学院#注释行,注释行,这是原来程序的这是原来程序的Makefile文件文件main:main.omytool1.omytool2.ogcc-omainmain.omytool1.omytool2.omain.o:main.cmytool1.hmytool2.hgcc-cmain.cmytool1.o:mytool1.cmytool1.hgcc-cmytool1.cmytool2.o:mytool2.cmytool2.hgcc-cm
17、ytool2.c#这是简化后的这是简化后的Makefilemain:main.omytool1.omytool2.ogcc-o$main.o:main.cmytool1.hmytool2.hgcc-c$mytool1.o:mytool1.cmytool1.hgcc-c$mytool2.o:mytool2.cmytool2.hgcc-c$:目标文件:目标文件$:所有的依赖文件:所有的依赖文件$:第一个依赖文件:第一个依赖文件 嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院4.Makefile的缺省规则.c.o:g
18、cc-c$这个规则表示所有的所有的.o文件都是依文件都是依赖于相于相应的的.c文件的文件的,例如mytool.o依赖于mytool.c。这样上面那个Makefile还可以简化为:嵌入式操作系统广州学院广东科学技术职业学院#这是简化后的这是简化后的Makefilemain:main.omytool1.omytool2.ogcc-o$main.o:main.cmytool1.hmytool2.hgcc-c$mytool1.o:mytool1.cmytool1.hgcc-c$mytool2.o:mytool2.cmytool2.hgcc-c$#这是再一次简化后的这是再一次简化后的Makefilema
19、in:main.omytool1.omytool2.ogcc-o$.c.o:gcc-c$:目标文件:目标文件$:所有的依赖文件:所有的依赖文件$:第一个依赖文件:第一个依赖文件#注释行,注释行,这是原来程序的这是原来程序的Makefile文件文件main:main.omytool1.omytool2.ogcc-omainmain.omytool1.omytool2.omain.o:main.cmytool1.hmytool2.hgcc-cmain.cmytool1.o:mytool1.cmytool1.hgcc-cmytool1.cmytool2.o:mytool2.cmytool2.hgcc
20、-cmytool2.c.c.o:gcc-c$#这个规则表示这个规则表示所有的所有的.o文件都是依赖于相应的文件都是依赖于相应的.c文件的文件的 嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院4.程序的调试我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.最常用的调试软件是gdb.GDB(GNUsymbolicdebugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。记得要在编译的时候加入-g选项.嵌入式操作系统广州学院广东科学技术职业学院GD
21、B概述GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX/Linux平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。嵌入式操作系统广州学院广东科学技术职业学院GDB概述一般来说,GDB主要帮忙你完成下面四个方面的功能:1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)3、当程序被停住时,可以检查此时你的程序中所发生的事。4、动态的改变
22、你程序的执行环境。嵌入式操作系统广州学院广东科学技术职业学院一个调试示例/源程序:tst.c1#include23intfunc(intn)45intsum=0,i;6for(i=0;in;i+)78sum+=i;910returnsum;11121314main()1516inti;17longresult=0;18for(i=1;icc-ghello.c-ohellog+-ghello.cpp-ohello如果没有如果没有-g,将看不见程序的函数名、变量名,所,将看不见程序的函数名、变量名,所代替的全是运行时的代替的全是运行时的内存地址内存地址。当你用当你用-g把调试信息加入之后,并成功编
23、译目标代把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用码以后,让我们来看看如何用gdb来调试程序。来调试程序。嵌入式操作系统广州学院广东科学技术职业学院启动启动GDB的方法有以下几种:的方法有以下几种:1、gdbprogram也就是你的也就是你的执行文件执行文件,一般在当然目,一般在当然目录下。录下。2、gdbcore用用gdb同时调试一个运行程序和同时调试一个运行程序和core文件,文件,core是程序非法执行后是程序非法执行后coredump后产生的文件。后产生的文件。3、gdb如果你的程序是一个服务程序,那么你可以指如果你的程序是一个服务程序,那么你可以指定这个服务程序运
24、行时的进程定这个服务程序运行时的进程ID。gdb会自动会自动attach上去,并调试他。上去,并调试他。program应该在应该在PATH环境变量中搜索得到。环境变量中搜索得到。嵌入式操作系统广州学院广东科学技术职业学院gdb基本命令gdb支持很多的命令使你能实现不同的功能.这些命令从简单的文件装入到允许检查所调用的堆栈内容的复杂命令,下表列出了在用gdb调试时会用到的一些命令.想了解gdb的详细使用请参考gdb的指南页.嵌入式操作系统广州学院广东科学技术职业学院gdb基本命令 嵌入式操作系统广州学院广东科学技术职业学院小技巧GDB启动后第一次list显示的是main函数的上下文6行可以用l行
25、号,可以显示选定行的上下6行list可以指定打开位置的:list1,15也可以指定要打开的文件:listmain.c:10 嵌入式操作系统广州学院广东科学技术职业学院使用使用GDB调试:调试:gdbtst-启动启动GDB(gdb)l-l命令相当于命令相当于list,从第一行开始例出原码。,从第一行开始例出原码。1#include23intfunc(intn)45intsum=0,i;6for(i=0;in;i+)78sum+=i;910returnsum;(gdb)-直接回车表示,重复上一次命令直接回车表示,重复上一次命令11121314main()1516inti;17longresult=
26、0;18for(i=1;i=100;i+)1920result+=i;嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院(gdb)break16-设置断点,在源程序第设置断点,在源程序第16行处行处。Breakpoint1at0 x8048496:filetst.c,line16.(gdb)breakfunc-设置断点,在函数设置断点,在函数func()入口入口处处。Breakpoint2at0 x8048456:filetst.c,line5.(gdb)infobreak-查看断点信息。查看断点信息。NumTypeDispEnbAddressWhat1br
27、eakpointkeepy0 x08048496inmainattst.c:162breakpointkeepy0 x08048456infuncattst.c:5(gdb)r-运行程序,运行程序,run命令简写命令简写Startingprogram:/home/hchen/test/tstBreakpoint1,main()attst.c:17-在断点处停住。在断点处停住。17longresult=0;(gdb)n-单条语句执行,单条语句执行,next命令简写。命令简写。18for(i=1;i=100;i+)嵌入式操作系统广州学院广东科学技术职业学院(gdb)n20result+=i;(gd
28、b)n18for(i=1;i=100;i+)(gdb)n20result+=i;(gdb)c-继续运行程序,继续运行程序,continue命令简写。命令简写。Continuing.result1-100=5050-程序输出。程序输出。Breakpoint2,func(n=250)attst.c:55intsum=0,i;(gdb)n6for(i=1;i=n;i+)(gdb)pi-打印变量打印变量i的值,的值,print命令简写。命令简写。$1=134513808 嵌入式操作系统广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院(gdb)n8sum+=i;(gdb)n6fo
29、r(i=1;i=n;i+)(gdb)psum$2=1(gdb)n8sum+=i;(gdb)pi$3=2(gdb)n6for(i=1;i=n;i+)(gdb)psum$4=3(gdb)bt-查看函数堆栈。查看函数堆栈。#0func(n=250)attst.c:5#10 x080484e4inmain()attst.c:24#20 x400409edin_libc_start_main()from/lib/libc.so.6 嵌入式操作系统广州学院广东科学技术职业学院(gdb)finish-退出函数。退出函数。Runtillexitfrom#0func(n=250)attst.c:50 x0804
30、84e4inmain()attst.c:2424printf(result1-250=%dn,func(250);Valuereturnedis$6=31375(gdb)c-继续运行。继续运行。Continuing.result1-250=31375-程序输出。程序输出。Programexitedwithcode027.-程序退出,调试结束。程序退出,调试结束。(gdb)q 嵌入式操作系统广州学院广东科学技术职业学院GDB的命令概貌的命令概貌启动启动gdb后,就你被带入后,就你被带入gdb的调试环的调试环境中,就可以使用境中,就可以使用gdb的命令开始调试的命令开始调试程序了,程序了,gdb的
31、命令可以的命令可以使用使用help命令命令来查看来查看 嵌入式操作系统广州学院广东科学技术职业学院gdb中,输入命令时,可以不用打全命令,只用打命令的前几个字中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命令的前几个字符应该要标志着一个唯一的命符就可以了,当然,命令的前几个字符应该要标志着一个唯一的命令,在令,在Linux下,下,你可以敲击两次你可以敲击两次TAB键来补齐命令的全称键来补齐命令的全称,如果,如果有重复的,那么有重复的,那么gdb会把其例出来。会把其例出来。示例一:在进入函数示例一:在进入函数func时,设置一个断点。可以时,设置一个断点。可以敲入敲入b
32、reakfunc,或是直接就是,或是直接就是bfunc(gdb)bfuncBreakpoint1at0 x8048458:filehello.c,line10.示例二:敲入示例二:敲入b按两次按两次TAB键,你会看到所有键,你会看到所有b打头的命令:打头的命令:(gdb)bbacktracebreakbt(gdb)嵌入式操作系统广州学院广东科学技术职业学院示例三:只记得函数的前缀,可以这样:示例三:只记得函数的前缀,可以这样:(gdb)bmake_(再按下一次(再按下一次TAB键,你会看到键,你会看到:)make_a_section_from_filemake_environmake_abs_
33、sectionmake_function_typemake_blockvectormake_pointer_typemake_cleanupmake_reference_typemake_commandmake_symbol_completion_list(gdb)bmake_GDB把所有把所有make开头的函数全部例出来给你查看。开头的函数全部例出来给你查看。要退出要退出gdb时,只用发时,只用发quit或命令简称或命令简称q就行了。就行了。嵌入式操作系统广州学院广东科学技术职业学院GDB中运行中运行Linux的的shell程序程序在在gdb环境中,你可以执行环境中,你可以执行Linux的的
34、shell的命令,使用的命令,使用gdb的的shell命令来完成:命令来完成:shell调用调用Linux的的shell来执行来执行,环境变量,环境变量SHELL中定义的中定义的Linux的的shell将会被用来执行将会被用来执行如果如果SHELL没有定义,那就使用没有定义,那就使用Linux的标准的标准shell:/bin/sh。(在(在Windows中使用中使用C或或cmd.exe)还有一个还有一个gdb命令是命令是make:make可以在可以在gdb中执行中执行make命令来重新命令来重新build自己的程序。这个命令等自己的程序。这个命令等价于价于“shellmake”。嵌入式操作系统
35、广州学院广东科学技术职业学院 嵌入式操作系统广州学院广东科学技术职业学院gdb应用举例下面一个实例教你一步步的用gdb调试程序.被调试的程序相当的简单,但它展示了gdb的典型应用.下面列出了将被调试的程序.这个程序被称为greeting,它显示一个简单的问候,再用反序将它列出.嵌入式操作系统广州学院广东科学技术职业学院案例讲解:gdb调试程序用一个实例教你一步步的用gdb调试程序.被调试的程序相当的简单,但它展示了gdb的典型应用.下面列出了将被调试的程序.这个程序被称为greeting,它显示一个简单的问候,再用反序将它列出.嵌入式操作系统广州学院广东科学技术职业学院#includemain
36、()charmy_string=hellothere;my_print(my_string);my_print2(my_string);voidmy_print(char*string)printf(Thestringis%sn,string);voidmy_print2(char*string)char*string2;intsize,i;size=strlen(string);string2=(char*)malloc(size+1);for(i=0;isize;i+)string2size-i=stringi;string2size+1=0;printf(Thestringbackwar
37、dis%sn,string2);嵌入式操作系统广州学院广东科学技术职业学院运行结果用下面的命令编译它:gcc-otesttest.c这个程序执行时显示如下结果:ThestringishellothereThestringprintedbackwardis输出的第一行是正确的但第二行打印出的东西并不是我们所期望的.我们所设想的输出应该是:Thestringprintedbackwardiserehtolleh 嵌入式操作系统广州学院广东科学技术职业学院for(i=0;isize;i+)string2size-i=stringi;hellothere0size=11stringstring2012
38、345678910 嵌入式操作系统广州学院广东科学技术职业学院调试由于某些原因,my_print2函数没有正常工作.让我们用gdb看看问题究竟出在哪儿,先键入如下命令:gdbgreeting注意:记得在编译greeting程序时把调试选项打开.嵌入式操作系统广州学院广东科学技术职业学院调试如果你在输入命令时忘了把要调试的程序作为参数传给gdb,你可以在gdb提示符下用file命令来载入它:(gdb)filegreeting这个命令将载入greeting可执行文件就象你在gdb命令行里装入它一样.这时你能用gdb的run命令来运行greeting了.当它在gdb里被运行后结果大约会象这样:嵌入式
39、操作系统广州学院广东科学技术职业学院调试(gdb)runStartingprogram:/root/greetingThestringishellothereThestringprintedbackwardisProgramexitedwithcode041 嵌入式操作系统广州学院广东科学技术职业学院调试这个输出和在gdb外面运行的结果一样.问题是,为什么反序打印没有工作?为了找出症结所在,我们可以在my_print2函数的for语句后设一个断点,具体的做法是在gdb提示符下键入list命令三次,列出源代码:(gdb)list(gdb)list(gdb)list技巧技巧:在在gdbgdb提示符
40、下按回车提示符下按回车健将重复上一个命令健将重复上一个命令.嵌入式操作系统广州学院广东科学技术职业学院调试第一次键入第一次键入list命令的输出如下命令的输出如下:1#include23main()45charmy_string=hellothere;67my_print(my_string);8my_print2(my_string);910 嵌入式操作系统广州学院广东科学技术职业学院调试如果按下回车如果按下回车,gdb将再执行一次将再执行一次list命令命令,给出下列输出给出下列输出:11my_print(char*string)1213printf(Thestringis%sn,stri
41、ng);141516my_print2(char*string)1718char*string2;19intsize,i;20 嵌入式操作系统广州学院广东科学技术职业学院调试再按一次回车将列出再按一次回车将列出greeting程序的剩余部分程序的剩余部分:21size=strlen(string);22string2=(char*)malloc(size+1);23for(i=0;isize;i+)24string2size-i=stringi;25string2size+1=0;26printf(Thestringprintedbackwardis%sn,string2);27 嵌入式操作系
42、统广州学院广东科学技术职业学院调试根据列出的源程序,你能看到要设断点的地方在第24行,在gdb命令行提示符下键入如下命令设置断点:(gdb)break24gdb将作出如下的响应:Breakpoint1at0 x139:filegreeting.c,line24(gdb)嵌入式操作系统广州学院广东科学技术职业学院调试现在再键入run命令,将产生如下的输出:Startingprogram:/root/greetingThestringishellothereBreakpoint1,my_print2(string=0 xbfffdc4hellothere)atgreeting.c:2424stri
43、ng2size-i=stringi 嵌入式操作系统广州学院广东科学技术职业学院调试你能通过设置一个观察你能通过设置一个观察string2size-i变量的值变量的值的观察点来看出错误是怎样产生的的观察点来看出错误是怎样产生的,做法是键入做法是键入:(gdb)watchstring2size-igdb将作出如下回应将作出如下回应:Watchpoint2:string2size-i 嵌入式操作系统广州学院广东科学技术职业学院调试现在可以用现在可以用next命令来一步步的执行命令来一步步的执行for循环了循环了:(gdb)next经过第一次循环后经过第一次循环后,gdb告诉我们告诉我们string2
44、size-i的值是的值是h.gdb用如下的显示来告诉你这个信息用如下的显示来告诉你这个信息:Watchpoint2,string2size-iOldvalue=0000Newvalue=104hmy_print2(string=0 xbfffdc4hellothere)atgreeting.c:2323for(i=0;isize;i+)嵌入式操作系统广州学院广东科学技术职业学院调试这个值正是期望的.后来的数次循环的结果都是正确的.当i=10时,表达式string2size-i的值等于e,size-i的值等于1,最后一个字符已经拷到新串里了.嵌入式操作系统广州学院广东科学技术职业学院调试如果你再
45、把循环执行下去,你会看到已经没有值分配给string20了,而它是新串的第一个字符,因为malloc函数在分配内存时把它们初始化为空(null)字符.所以string2的第一个字符是空字符.这解释了为什么在打印string2时没有任何输出了.嵌入式操作系统广州学院广东科学技术职业学院调试为了使代码正常工作有很多种修改办法为了使代码正常工作有很多种修改办法.一一种是另设一个比串的实际大小小种是另设一个比串的实际大小小1的变量的变量.这是这种解决办法的代码这是这种解决办法的代码:size=strlen(string);size2=size-1;string2=(char*)malloc(size+1);for(i=0;isize;i+)string2size2-i=stringi;string2size=0;嵌入式操作系统广州学院广东科学技术职业学院结论VC=vi+gcc+gdb+makefile