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

📄 linux 下 c 语言编程1.html

📁 本文介绍了在 Linux 下能用于 C 应用程序开发和调试的工具. 本文的主旨是介绍如何在 Linux 下使用 C 编译器和其他 C 编程工具, 而非 C 语言编程的教程
💻 HTML
📖 第 1 页 / 共 3 页
字号:

void my_print (char *string)

{

  printf ("The string is %s\n", string);

}



void my_print2 (char *string)

{

  char *string2;

  int size, i;



  size = strlen (string);

  string2 = (char *) malloc (size + 1);

  for (i = 0; i < size; i++)

    string2[size - i] = string[i];

  string2[size+1] = `\0';

  printf ("The string printed backward is %s\n", string2);

}</font></pre>
&nbsp;&nbsp;&nbsp; 用下面的命令编译它: 
<br>&nbsp;
<pre><font color="#0066ff">gcc -o test test.c</font></pre>
&nbsp;&nbsp;&nbsp; 这个程序执行时显示如下结果: 
<pre><font color="#0066ff">The string is hello there

The string printed backward is</font></pre>
&nbsp;&nbsp;&nbsp; 输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的. 
我们所设想的输出应该是:
<pre><font color="#0066ff">The string printed backward is ereht olleh</font></pre>
&nbsp;&nbsp;&nbsp; 由于某些原因, <tt>my_print2</tt> 函数没有正常工作. 让我们用&nbsp; 
<tt>gdb</tt> 看看问题究竟出在哪儿, 先键入如下命令: 
<br>&nbsp;
<pre><font color="#0066ff">gdb greeting</font></pre>

<dl>
<dd>

<hr width="90%"><b>注意:</b> 记得在编译 <tt>greeting</tt> 程序时把调试选项打开.&nbsp; 
<hr width="90%"></dd>
</dl>
&nbsp;&nbsp;&nbsp; 如果你在输入命令时忘了把要调试的程序作为参数传给 <tt>gdb</tt> 
, 你可以在 <tt>gdb</tt> 提示符下用 file 命令来载入它: 
<br>&nbsp;
<pre><font color="#0066ff">(gdb) file greeting</font></pre>
&nbsp;&nbsp;&nbsp; 这个命令将载入 <tt>greeting</tt> 可执行文件就象你在 
<tt>gdb</tt> 命令行里装入它一样. 

<p>&nbsp;&nbsp;&nbsp; 这时你能用 <tt>gdb</tt> 的 run 命令来运行 <tt>greeting</tt> 
了. 当它在 <tt>gdb</tt> 里被运行后结果大约会象这样: 
</p><pre><font color="#0066ff">(gdb) run

Starting program: /root/greeting

The string is hello there

The string printed backward is

Program exited with code 041</font></pre>
&nbsp;&nbsp;&nbsp; 这个输出和在 <tt>gdb</tt> 外面运行的结果一样. 问题是, 
为什么反序打印没有工作? 为了找出症结所在, 我们可以在 <tt>my_print2</tt> 
函数的 <tt>for</tt> 语句后设一个断点, 具体的做法是在 <tt>gdb</tt> 提示符下键入 
<tt>list</tt> 命令三次, 列出源代码: 
<pre><font color="#0066ff">(gdb) list

(gdb) list

(gdb) list</font></pre>

<dl>
<dd>

<hr width="90%"><b>技巧:</b>&nbsp; 在 <tt>gdb</tt> 提示符下按回车健将重复上一个命令.&nbsp; 
<hr width="90%"></dd>
</dl>
&nbsp;&nbsp;&nbsp; 第一次键入 <tt>list</tt> 命令的输出如下: 
<br>&nbsp;
<pre><font color="#0066ff">1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include&nbsp; &lt;stdio.h&gt;

2

3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; main ()

4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {

5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char my_string[] = "hello there";

6

7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_print (my_string);

8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_print2 (my_string);

9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

10</font></pre>
&nbsp;&nbsp;&nbsp; 如果按下回车, <tt>gdb</tt> 将再执行一次 <tt>list</tt> 
命令, 给出下列输出: 
<br>&nbsp;
<pre><font color="#0066ff">11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_print (char *string)

12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {

13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("The string is %s\n", string);

14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

15

16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my_print2 (char *string)

17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {

18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *string2;

19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size, i;

20</font></pre>
&nbsp;&nbsp;&nbsp; 再按一次回车将列出 <tt>greeting</tt> 程序的剩余部分: 
<pre><font color="#0066ff">21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size = strlen (string);

22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string2 = (char *) malloc (size + 1);

23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; size; i++)

24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string2[size - i] = string[i];

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string2[size+1] = `\0';

26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf ("The string printed backward is %s\n", string2);

27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></pre>
&nbsp;&nbsp;&nbsp; 根据列出的源程序, 你能看到要设断点的地方在第24行, 在 
<tt>gdb</tt> 命令行提示符下键入如下命令设置断点: 
<pre><font color="#0066ff">(gdb) break 24</font></pre>
<tt>&nbsp;&nbsp;&nbsp; gdb</tt> 将作出如下的响应: 
<pre><font color="#0066ff">Breakpoint 1 at 0x139: file greeting.c, line 24

(gdb)</font></pre>
&nbsp;
<br>&nbsp;&nbsp;&nbsp; 现在再键入 <tt>run </tt>命令, 将产生如下的输出: 
<br>&nbsp;
<pre><font color="#0066ff">Starting program: /root/greeting

The string is hello there



Breakpoint 1, my_print2 (string = 0xbfffdc4 "hello there") at greeting.c :24

24&nbsp; string2[size-i]=string[i]</font></pre>
&nbsp;&nbsp;&nbsp; 你能通过设置一个观察 <tt>string2[size - i]</tt> 变量的值的观察点来看出错误是怎样产生的, 
做法是键入:
<br>&nbsp;
<pre><font color="#0066ff">(gdb) watch string2[size - i]</font></pre>
<tt>&nbsp;&nbsp;&nbsp; gdb</tt> 将作出如下回应: 
<pre><font color="#0066ff">Watchpoint 2: string2[size - i]</font></pre>
&nbsp;&nbsp;&nbsp; 现在可以用 <tt>next</tt> 命令来一步步的执行 <tt>for</tt> 
循环了: 
<br>&nbsp;
<pre><font color="#0066ff">(gdb) next</font></pre>
&nbsp;&nbsp;&nbsp; 经过第一次循环后,&nbsp; <tt>gdb</tt> 告诉我们 <tt>string2[size 
- i]</tt> 的值是 <tt>`h`.</tt> <tt>gdb</tt> 用如下的显示来告诉你这个信息: 
<br>&nbsp;
<pre><font color="#0066ff">Watchpoint 2, string2[size - i]

Old value = 0 `\000'

New value = 104 `h'

my_print2(string = 0xbfffdc4 "hello there") at greeting.c:23

23 for (i=0; i&lt;size; i++)</font></pre>
&nbsp;&nbsp;&nbsp; 这个值正是期望的. 后来的数次循环的结果都是正确的. 当 
<tt>i=10 </tt>时, 表达式 <tt>string2[size - i]</tt> 的值等于 <tt>`e`</tt>,&nbsp; 
<tt>size - i</tt> 的值等于 1, 最后一个字符已经拷到新串里了. 

<p>&nbsp;&nbsp;&nbsp; 如果你再把循环执行下去, 你会看到已经没有值分配给 
<tt>string2[0] </tt>了,<tt>&nbsp;</tt> 而它是新串的第一个字符, 因为 <tt>malloc</tt> 
函数在分配内存时把它们初始化为空(null)字符. 所以 <tt>string2</tt> 的第一个字符是空字符. 
这解释了为什么在打印 <tt>string2</tt> 时没有任何输出了. 

</p><p>&nbsp;&nbsp;&nbsp; 现在找出了问题出在哪里, 修正这个错误是很容易的. 你得把代码里写入 
<tt>string2</tt> 的第一个字符的的偏移量改为 <tt>size - 1</tt> 而不是 <tt>size</tt>. 
这是因为 <tt>string2</tt> 的大小为 12, 但起始偏移量是 0, 串内的字符从偏移量 
0 到 偏移量 10, 偏移量 11 为空字符保留. 

</p><p>&nbsp;&nbsp;&nbsp; 为了使代码正常工作有很多种修改办法. 一种是另设一个比串的实际大小小 
1 的变量. 这是这种解决办法的代码: 
</p><pre><font color="#0066ff">#include&nbsp; &lt;stdio.h&gt;



main ()


{

&nbsp; char my_string[] = "hello there";



&nbsp; my_print (my_string);

&nbsp; my_print2 (my_string);

}



my_print (char *string)

{

&nbsp; printf ("The string is %s\n", string);

}



my_print2 (char *string)

{

&nbsp; char *string2;

&nbsp; int size, size2, i;



&nbsp; size = strlen (string);

&nbsp; size2 = size -1;

&nbsp; string2 = (char *) malloc (size + 1);

&nbsp; for (i = 0; i &lt; size; i++)

&nbsp;&nbsp;&nbsp; string2[size2 - i] = string[i];

&nbsp; string2[size] = `\0';

&nbsp; printf ("The string printed backward is %s\n", string2);

}</font></pre>

<h3>
<font color="#ff9900">
另外的 C 编程工具</font></h3> 
&nbsp;&nbsp;&nbsp; Slackware Linux 的发行版中还包括一些我们尚未提到的 C 
开发工具. 本节将介绍这些工具和它们的典型用法. 
<h4>
xxgdb</h4>
<tt>&nbsp;&nbsp;&nbsp; xxgdb</tt> 是 <tt>gdb</tt> 的一个基于 X Window 系统的图形界面.&nbsp; 
<tt>xxgdb </tt>包括了命令行版的 <tt>gdb</tt> 上的所有特性.&nbsp; <tt>xxgdb 
</tt>使你能通过按按钮来执行常用的命令. 设置了断点的地方也用图形来显示. 
<br>&nbsp;
<br>&nbsp;&nbsp;&nbsp; 你能在一个 <tt>Xterm</tt> 窗口里键入下面的命令来运行它: 
<pre><font color="#0066ff">xxgdb</font></pre>
&nbsp;&nbsp;&nbsp; 你能用 <tt>gdb</tt> 里任何有效的命令行选项来初始化 <tt>xxgdb</tt> 
. 此外 <tt>xxgdb</tt> 也有一些特有的命令行选项, 表 27.2 列出了这些选项. 
<br>&nbsp; <b><font size="+1">表 27.2.&nbsp; xxgdb 命令行选项.</font></b> &nbsp; 
      &nbsp;<table border="1">
<tbody><tr rowspan="1" align="left">
<td align="left" width="70"><i>选&nbsp; 项</i></td> 

<td align="left"><i>描&nbsp; 述</i></td> 
</tr>

<tr rowspan="1" align="left">
<td align="left" width="70"><tt>db_name</tt></td>

<td align="left">指定所用调试器的名字, 缺省是 <tt>gdb</tt>.</td> 
</tr>

<tr rowspan="1" align="left">
<td align="left" width="70"><tt>db_prompt</tt></td>

<td align="left">指定调试器提示符, 缺省为 <tt>gdb</tt>.</td> 
</tr>

<tr rowspan="1" align="left">
<td align="left" width="70"><tt>gdbinit</tt></td>

<td align="left">
指定初始化 <tt>gdb</tt> 的命令文件的文件名, 缺省为 <tt>.gdbinit</tt>.&nbsp; 
</td>
</tr>

<tr rowspan="1" align="left">
<td align="left" width="70"><tt>nx</tt></td>

<td align="left">告诉 <tt>xxgdb</tt> 不执行 <tt>.gdbinit</tt> 文件.</td> 
</tr>

<tr rowspan="1" align="left">
<td align="left" width="70"><tt>bigicon</tt></td>

<td align="left">使用大图标.</td>
</tr>
</tbody></table>
&nbsp;
<br>&nbsp;
<br>&nbsp;
<h4>
calls</h4>
<tt>&nbsp;&nbsp;&nbsp;&nbsp; </tt>你可以在 <tt>sunsite.unc.edu</tt> FTP 
站点用下面的路径:

<p><tt><font color="#3366ff">/pub/Linux/devel/lang/c/calls.tar.Z</font></tt>

</p><p>&nbsp;&nbsp;&nbsp; 来取得 <tt>calls , </tt>一些旧版本的 Linux CD-ROM 
发行版里也附带有. 因为它是一个有用的工具, 我们在这里也介绍一下. 如果你觉得有用的话, 
从 BBS, FTP, 或另一张CD-ROM 上弄一个拷贝.&nbsp; <tt>calls</tt> 调用 GCC 
的预处理器来处理给出的源程序文件, 然后输出这些文件的里的函数调用树图. 
<br>&nbsp;
</p><dl>
<dd>

⌨️ 快捷键说明

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