1 用gdb调试下面的程序:
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
main ()
{
char my_string[] = "hello there";
my_print (my_string);
my_print2 (my_string);
}
my_print (char *string)
{
printf ("The string is %s\n", string);
}
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);
}
答:gcc -g -o test04 test04.c
这个程序执行时显示结果: The string is hello there
The string printed backward is
输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的。我们所设想的输出应该是: The string printed backward is ereht olleh。
由于某些原因, my_print2 函数没有正常工作。用gdb 看调试程序, 先键入如下命令:
gdb test04
--------------------------------------------------------------------------------
注意: 记得在编译 test04 程序时把调试选项打开.
--------------------------------------------------------------------------------
用gdb的run命令运行test04。
(gdb) run
Starting program: /root/test04
The string is hello there
The string printed backward is
Program exited with code 040
这个输出和在 gdb 外面运行的结果一样。 问题是,为什么反序打印没有工作? 为了找出症结所在, 在 my_print2 函数的 for 语句后设一个断点, 具体的做法是在 gdb 提示符下键入 list 命令三次, 列出源代码:
(gdb) list
(gdb) list
(gdb) list
第一次键入 list 命令的输出如下:
如果按下回车, gdb 将再执行一次 list 命令, 给出下列输出:
再按一次回车将列出 greeting 程序的剩余部分:
根据列出的源程序, 你能看到要设断点的地方在第21行, 在 gdb 命令行提示符下键入如下命令设置断点:
(gdb) break 21
gdb 将作出如下的响应:
现在再键入 run 命令, 将产生如下的输出:
你能通过设置一个观察 string2[size - i] 变量的值的观察点来看出错误是怎样产生的, 做法是:
现在可以用 next 命令来一步步的执行 for 循环了:
(gdb) next
经过第一次循环后, gdb 告诉我们 string2[size - i] 的值是 `h`. gdb 用如下的显示来告诉你这个信息:
这个值正是期望的,后来的数次循环的结果都是正确的。当 i=10 时,表达式 string2[size - i]的值等于 `e`, size - i 的值等于 1,最后一个字符已经拷到新串里了。
如果你再把循环执行下去, 你会看到已经没有值分配给 string2[0] 了, 而它是新串的第一个字符, 因为 malloc 函数在分配内存时把它们初始化为空(null)字符, 所以 string2 的第一个字符是空字符,这解释了为什么在打印 string2 时没有任何输出了。
现在找出了问题出在哪里, 修正这个错误是很容易的. 你得把代码里写入 string2 的第一个字符的的偏移量改为 size - 1 而不是 size. 这是因为 string2 的大小为 12, 但起始偏移量是 0, 串内的字符从偏移量 0 到 偏移量 10, 偏移量 11 为空字符保留。
为了使代码正常工作有很多种修改办法。 一种是另设一个比串的实际大小小 1 的变量。 这是这种解决办法的代码:
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
main()
{
char my_string[]="hello there";
my_print(my_string);
my_print2(my_string);
}
my_print(char *string)
{
printf("The string is %s\n",string);
}
my_print2(char *string)
{
char *string2;
int size,size2,i;
size=strlen(string);
size2=size-1;
string2=(char*)malloc(size + 1);
for (i=0;i<size;i++)
string2[size2-i]=string[i];
string2[size+1]='\0';
printf("The string printed backward is %s\n",string2);
2 设某个程序由四个C语言源文件组成,分别是a.c、b.c、c.c、d.c,其中b.c和d.c都使用了defs.h中的声明,最后生成的可执行文件名为pgm。为该程序编写相应的makefile文件。
答:
pgm : a.o b.o c.o d.o
gcc a.o b.o c.o d.o -o pgm
a.o : a.c
gcc -c a.c -o a.o
b.o : b.c defs.h
gcc -c b.c -o b.o
c.o :c.c
gcc -c c.c -o c.o
d.o : d.c defs.h
gcc -c d.c -o d.o
3 根据要求编写Makefile文件,有5个文件分别是main.c、visit.h、study.h、visit.c、study.c
具体代码如下:
如果上述文件在同一目录,请编写Makefile文件,用于生成可执行程序 test。