⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000010.htm

📁 水木社区 embeded 版精华区 下载
💻 HTM
📖 第 1 页 / 共 3 页
字号:
&nbsp;&nbsp;char&nbsp;*string2;&nbsp;<br />&nbsp;&nbsp;int&nbsp;size,&nbsp;i;&nbsp;<br />&nbsp;&nbsp;size&nbsp;=&nbsp;strlen&nbsp;(string);&nbsp;<br />&nbsp;&nbsp;string2&nbsp;=&nbsp;(char&nbsp;*)&nbsp;malloc&nbsp;(size&nbsp;+&nbsp;1);&nbsp;<br />&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;size;&nbsp;i++)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;=&nbsp;string[i];&nbsp;<br />&nbsp;&nbsp;string2[size+1]&nbsp;=&nbsp;`\0';&nbsp;<br />&nbsp;&nbsp;printf&nbsp;(&quot;The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;%s\n&quot;,&nbsp;string2);&nbsp;<br />}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;用下面的命令编译它:&nbsp;<br />gcc&nbsp;-o&nbsp;test&nbsp;test.c&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;这个程序执行时显示如下结果:&nbsp;<br />The&nbsp;string&nbsp;is&nbsp;hello&nbsp;there&nbsp;<br />The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;输出的第一行是正确的,&nbsp;但第二行打印出的东西并不是我们所期望的.&nbsp;我们所设想&nbsp;<br />的输出应该是:&nbsp;<br />The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;ereht&nbsp;olleh&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;由于某些原因,&nbsp;my_print2&nbsp;函数没有正常工作.&nbsp;让我们用&nbsp;&nbsp;gdb&nbsp;看看问题究竟出在&nbsp;<br />哪儿,&nbsp;先键入如下命令:&nbsp;<br />gdb&nbsp;greeting&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />注意:&nbsp;记得在编译&nbsp;greeting&nbsp;程序时把调试选项打开.&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;如果你在输入命令时忘了把要调试的程序作为参数传给&nbsp;gdb&nbsp;,&nbsp;你可以在&nbsp;gdb&nbsp;提示&nbsp;<br />符下用&nbsp;file&nbsp;命令来载入它:&nbsp;<br />(gdb)&nbsp;file&nbsp;greeting&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;这个命令将载入&nbsp;greeting&nbsp;可执行文件就象你在&nbsp;gdb&nbsp;命令行里装入它一样.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;这时你能用&nbsp;gdb&nbsp;的&nbsp;run&nbsp;命令来运行&nbsp;greeting&nbsp;了.&nbsp;当它在&nbsp;gdb&nbsp;里被运行后结果大&nbsp;<br />约会象这样:&nbsp;<br />(gdb)&nbsp;run&nbsp;<br />Starting&nbsp;program:&nbsp;/root/greeting&nbsp;<br />The&nbsp;string&nbsp;is&nbsp;hello&nbsp;there&nbsp;<br />The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;<br />Program&nbsp;exited&nbsp;with&nbsp;code&nbsp;041&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;这个输出和在&nbsp;gdb&nbsp;外面运行的结果一样.&nbsp;问题是,&nbsp;为什么反序打印没有工作?&nbsp;为了&nbsp;<br />找出症结所在,&nbsp;我们可以在&nbsp;my_print2&nbsp;函数的&nbsp;for&nbsp;语句后设一个断点,&nbsp;具体的做法是&nbsp;<br />在&nbsp;gdb&nbsp;提示符下键入&nbsp;list&nbsp;命令三次,&nbsp;列出源代码:&nbsp;<br />(gdb)&nbsp;list&nbsp;<br />(gdb)&nbsp;list&nbsp;<br />(gdb)&nbsp;list&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />技巧:&nbsp;&nbsp;在&nbsp;gdb&nbsp;提示符下按回车健将重复上一个命令.&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;第一次键入&nbsp;list&nbsp;命令的输出如下:&nbsp;<br />1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&nbsp;&lt;stdio.h&gt;&nbsp;<br />2&nbsp;<br />3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main&nbsp;()&nbsp;<br />4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;my_string[]&nbsp;=&nbsp;&quot;hello&nbsp;there&quot;;&nbsp;<br />6&nbsp;<br />7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_print&nbsp;(my_string);&nbsp;<br />8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_print2&nbsp;(my_string);&nbsp;<br />9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />10&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;如果按下回车,&nbsp;gdb&nbsp;将再执行一次&nbsp;list&nbsp;命令,&nbsp;给出下列输出:&nbsp;<br />11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_print&nbsp;(char&nbsp;*string)&nbsp;<br />12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(&quot;The&nbsp;string&nbsp;is&nbsp;%s\n&quot;,&nbsp;string);&nbsp;<br />14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />15&nbsp;<br />16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_print2&nbsp;(char&nbsp;*string)&nbsp;<br />17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*string2;&nbsp;<br />19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;size,&nbsp;i;&nbsp;<br />20&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;再按一次回车将列出&nbsp;greeting&nbsp;程序的剩余部分:&nbsp;<br />21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;strlen&nbsp;(string);&nbsp;<br />22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string2&nbsp;=&nbsp;(char&nbsp;*)&nbsp;malloc&nbsp;(size&nbsp;+&nbsp;1);&nbsp;<br />23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;size;&nbsp;i++)&nbsp;<br />24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;=&nbsp;string[i];&nbsp;<br />25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string2[size+1]&nbsp;=&nbsp;`\0';&nbsp;<br />26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(&quot;The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;%s\n&quot;,&nbsp;string2);&nbsp;<br />27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;根据列出的源程序,&nbsp;你能看到要设断点的地方在第24行,&nbsp;在&nbsp;gdb&nbsp;命令行提示符下键&nbsp;<br />入如下命令设置断点:&nbsp;<br />(gdb)&nbsp;break&nbsp;24&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;gdb&nbsp;将作出如下的响应:&nbsp;<br />Breakpoint&nbsp;1&nbsp;at&nbsp;0x139:&nbsp;file&nbsp;greeting.c,&nbsp;line&nbsp;24&nbsp;<br />(gdb)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;现在再键入&nbsp;run&nbsp;命令,&nbsp;将产生如下的输出:&nbsp;<br />Starting&nbsp;program:&nbsp;/root/greeting&nbsp;<br />The&nbsp;string&nbsp;is&nbsp;hello&nbsp;there&nbsp;<br />Breakpoint&nbsp;1,&nbsp;my_print2&nbsp;(string&nbsp;=&nbsp;0xbfffdc4&nbsp;&quot;hello&nbsp;there&quot;)&nbsp;at&nbsp;greeting.c&nbsp;:24&nbsp;<br />&nbsp;<br />24&nbsp;&nbsp;string2[size-i]=string[i]&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;你能通过设置一个观察&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;变量的值的观察点来看出错误是怎样产&nbsp;<br />生的,&nbsp;做法是键入:&nbsp;<br />(gdb)&nbsp;watch&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;gdb&nbsp;将作出如下回应:&nbsp;<br />Watchpoint&nbsp;2:&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;现在可以用&nbsp;next&nbsp;命令来一步步的执行&nbsp;for&nbsp;循环了:&nbsp;<br />(gdb)&nbsp;next&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;经过第一次循环后,&nbsp;&nbsp;gdb&nbsp;告诉我们&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;的值是&nbsp;`h`.&nbsp;gdb&nbsp;用如下&nbsp;<br />的显示来告诉你这个信息:&nbsp;<br />Watchpoint&nbsp;2,&nbsp;string2[size&nbsp;-&nbsp;i]&nbsp;<br />Old&nbsp;value&nbsp;=&nbsp;0&nbsp;`\000'&nbsp;<br />New&nbsp;value&nbsp;=&nbsp;104&nbsp;`h'&nbsp;<br />my_print2(string&nbsp;=&nbsp;0xbfffdc4&nbsp;&quot;hello&nbsp;there&quot;)&nbsp;at&nbsp;greeting.c:23&nbsp;<br />23&nbsp;for&nbsp;(i=0;&nbsp;i&lt;size;&nbsp;i++)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;这个值正是期望的.&nbsp;后来的数次循环的结果都是正确的.&nbsp;当&nbsp;i=10&nbsp;时,&nbsp;表达式&nbsp;str&nbsp;<br />ing2[size&nbsp;-&nbsp;i]&nbsp;的值等于&nbsp;`e`,&nbsp;&nbsp;size&nbsp;-&nbsp;i&nbsp;的值等于&nbsp;1,&nbsp;最后一个字符已经拷到新串里&nbsp;<br />了.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;如果你再把循环执行下去,&nbsp;你会看到已经没有值分配给&nbsp;string2[0]&nbsp;了,&nbsp;&nbsp;而它是新&nbsp;<br />串的第一个字符,&nbsp;因为&nbsp;malloc&nbsp;函数在分配内存时把它们初始化为空(null)字符.&nbsp;所以&nbsp;<br />&nbsp;string2&nbsp;的第一个字符是空字符.&nbsp;这解释了为什么在打印&nbsp;string2&nbsp;时没有任何输出了&nbsp;<br />.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;现在找出了问题出在哪里,&nbsp;修正这个错误是很容易的.&nbsp;你得把代码里写入&nbsp;string2&nbsp;<br />&nbsp;的第一个字符的的偏移量改为&nbsp;size&nbsp;-&nbsp;1&nbsp;而不是&nbsp;size.&nbsp;这是因为&nbsp;string2&nbsp;的大小为&nbsp;&nbsp;<br />12,&nbsp;但起始偏移量是&nbsp;0,&nbsp;串内的字符从偏移量&nbsp;0&nbsp;到&nbsp;偏移量&nbsp;10,&nbsp;偏移量&nbsp;11&nbsp;为空字符保&nbsp;<br />留.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;为了使代码正常工作有很多种修改办法.&nbsp;一种是另设一个比串的实际大小小&nbsp;1&nbsp;的变&nbsp;<br />量.&nbsp;这是这种解决办法的代码:&nbsp;<br />#include&nbsp;&nbsp;&lt;stdio.h&gt;&nbsp;<br />main&nbsp;()&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;char&nbsp;my_string[]&nbsp;=&nbsp;&quot;hello&nbsp;there&quot;;&nbsp;<br />&nbsp;&nbsp;my_print&nbsp;(my_string);&nbsp;<br />&nbsp;&nbsp;my_print2&nbsp;(my_string);&nbsp;<br />}&nbsp;<br />my_print&nbsp;(char&nbsp;*string)&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;printf&nbsp;(&quot;The&nbsp;string&nbsp;is&nbsp;%s\n&quot;,&nbsp;string);&nbsp;<br />}&nbsp;<br />my_print2&nbsp;(char&nbsp;*string)&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;char&nbsp;*string2;&nbsp;<br />&nbsp;&nbsp;int&nbsp;size,&nbsp;size2,&nbsp;i;&nbsp;<br />&nbsp;&nbsp;size&nbsp;=&nbsp;strlen&nbsp;(string);&nbsp;<br />&nbsp;&nbsp;size2&nbsp;=&nbsp;size&nbsp;-1;&nbsp;<br />&nbsp;&nbsp;string2&nbsp;=&nbsp;(char&nbsp;*)&nbsp;malloc&nbsp;(size&nbsp;+&nbsp;1);&nbsp;<br />&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;size;&nbsp;i++)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;string2[size2&nbsp;-&nbsp;i]&nbsp;=&nbsp;string[i];&nbsp;<br />&nbsp;&nbsp;string2[size]&nbsp;=&nbsp;`\0';&nbsp;<br />&nbsp;&nbsp;printf&nbsp;(&quot;The&nbsp;string&nbsp;printed&nbsp;backward&nbsp;is&nbsp;%s\n&quot;,&nbsp;string2);&nbsp;<br />}&nbsp;<br />另外的&nbsp;C&nbsp;编程工具&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;Slackware&nbsp;Linux&nbsp;的发行版中还包括一些我们尚未提到的&nbsp;C&nbsp;开发工具.&nbsp;本节将介绍&nbsp;<br />这些工具和它们的典型用法.&nbsp;<br />xxgdb&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;xxgdb&nbsp;是&nbsp;gdb&nbsp;的一个基于&nbsp;X&nbsp;Window&nbsp;系统的图形界面.&nbsp;&nbsp;xxgdb&nbsp;包括了命令行版的&nbsp;<br />&nbsp;gdb&nbsp;上的所有特性.&nbsp;&nbsp;xxgdb&nbsp;使你能通过按按钮来执行常用的命令.&nbsp;设置了断点的地方&nbsp;<br />也用图形来显示.&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;你能在一个&nbsp;Xterm&nbsp;窗口里键入下面的命令来运行它:&nbsp;<br />xxgdb&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;你能用&nbsp;gdb&nbsp;里任何有效的命令行选项来初始化&nbsp;xxgdb&nbsp;.&nbsp;此外&nbsp;xxgdb&nbsp;也有一些特有&nbsp;<br />的命令行选项,&nbsp;表&nbsp;27.2&nbsp;列出了这些选项.&nbsp;<br />&nbsp;&nbsp;表&nbsp;27.2.&nbsp;&nbsp;xxgdb&nbsp;命令行选项.&nbsp;<br />选&nbsp;&nbsp;项&nbsp;描&nbsp;&nbsp;述&nbsp;<br />db_name&nbsp;指定所用调试器的名字,&nbsp;缺省是&nbsp;gdb.&nbsp;<br />db_prompt&nbsp;指定调试器提示符,&nbsp;缺省为&nbsp;gdb.&nbsp;<br />gdbinit&nbsp;指定初始化&nbsp;gdb&nbsp;的命令文件的文件名,&nbsp;缺省为&nbsp;.gdbinit.&nbsp;<br />nx&nbsp;告诉&nbsp;xxgdb&nbsp;不执行&nbsp;.gdbinit&nbsp;文件.&nbsp;<br />bigicon&nbsp;使用大图标.&nbsp;<br />calls&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你可以在&nbsp;sunsite.unc.edu&nbsp;FTP&nbsp;站点用下面的路径:&nbsp;<br />/pub/Linux/devel/lang/c/calls.tar.Z&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;来取得&nbsp;calls&nbsp;,&nbsp;一些旧版本的&nbsp;Linux&nbsp;CD-ROM&nbsp;发行版里也附带有.&nbsp;因为它是一个有&nbsp;<br />用的工具,&nbsp;我们在这里也介绍一下.&nbsp;如果你觉得有用的话,&nbsp;从&nbsp;BBS,&nbsp;FTP,&nbsp;或另一张CD-&nbsp;<br />ROM&nbsp;上弄一个拷贝.&nbsp;&nbsp;calls&nbsp;调用&nbsp;GCC&nbsp;的预处理器来处理给出的源程序文件,&nbsp;然后输出&nbsp;<br />这些文件的里的函数调用树图.&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />注意:&nbsp;在你的系统上安装&nbsp;calls&nbsp;,&nbsp;以超级用户身份登录后执行下面的步骤:&nbsp;1.&nbsp;解压和&nbsp;<br />&nbsp;untar&nbsp;文件.&nbsp;2.&nbsp;cd&nbsp;进入&nbsp;calls&nbsp;untar&nbsp;后建立的子目录.&nbsp;3.&nbsp;把名叫&nbsp;calls&nbsp;的文件移&nbsp;<br />动到&nbsp;/usr/bin&nbsp;目录.&nbsp;4.&nbsp;把名叫&nbsp;calls.1&nbsp;的文件移动到目录&nbsp;/usr/man/man1&nbsp;.&nbsp;5.&nbsp;删&nbsp;<br />除&nbsp;/tmp/calls&nbsp;目录.&nbsp;这些步骤将把&nbsp;calls&nbsp;程序和它的指南页安装载你的系统上.&nbsp;<br />----------------------------------------------------------------------------&nbsp;<br />----&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;当&nbsp;calls&nbsp;打印出调用跟踪结果时,&nbsp;它在函数后面用中括号给出了函数所在文件的文&nbsp;<br />件名:&nbsp;<br />

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -