find / -xdev –mtime $1 –size +$2 –print 验证该脚本执行结果。 答:
从根目录开始查找所有$1小时前修改,大小大于$2块的文件。 8.一个shell脚本,内容如下:
echo –n “which color do you like?” read color case “$color” in [Bb]l??)
echo I feel $color echo The sky is $color;; [Gg]ree*)
echo $color is for trees echo $color is for seasick;; red | orange)
echo $color is very warm!;; *)
echo no such color as $color;; esac
echo “out of case” 验证该脚本执行结果。 答:
9.设计一个shell脚本:求命令行上所有整数和。 答: sum=0
while [ $# != 0 ] do
let sum=sum+$1 shift done
echo “the sum of arguments is $sum”
10.设计一个shell脚本:判断当前工作目录下所有的文件类型,如果是目录显示目录名,如果是文件查看文件内容,如果都不是,显示提示信息。
答:
for file in ./* do
if [ -d “$file” ] then
ls “$file”
elif [ -f “file” ] then
more “$file” else
echo “$fiel is not a directory or a regular file.s” done
第7章 习题答案
1.gcc编译过程一般分为哪几个阶段?各阶段的主要工作是什么?
答:gcc编译过程一般分为预处理、编译、汇编、链接四个阶段,各阶段的主要工作如下: (1)预处理阶段
在该阶段,编译器将上述代码中的stdio.h编译进来。GCC首先调用cpp进行预处理,根据以字符#开头的命令修改原始的C程序。如hello.c中#include
但实际工作中通常不用专门生成这种文件,因为基本上用不到。若非要生成这种文件不可,可以利用下面的示例命令。
$gcc -E hello.c -o hello.i (2)编译阶段
GCC调用cc1检查代码的规范性,是否有语法错误等,以确定代码实际要做的工作,在检查无误后,把代码翻译成汇编语言,生成汇编处理后的汇编代码hello.s。这个阶段对应的GCC命令如下所示。 $gcc -S hello.i -o hello.s
汇编语言是非常有用的,它为不同高级语言不同编译器提供了通用的语言。如:C编译器和Fortran编译器产生的输出文件用的都是一样的汇编语言。 (3)汇编阶段
GCC调用as把编译阶段生成的hello.s文件转成编译后的目标文件hello.o,但hello.c中所引用的其他文件中函数(如printf)的内存位置尚未定义。这个阶段对应的GCC命令如下所示: $gcc -c hello.s -o hello.o (4)链接阶段
GCC调用ld将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。如GCC找到hello.c所调用的函数printf函数库所在位置/user/lib,把函数的实现链接进来,生成最终的可执行文件hello。可以利用下面的示例命令完成。 $gcc hello.o -o hello
如果我们不想生成中间的各类型文件,可用如下命令由源文件直接编译链接成可执行文件。
$gcc hello.c -o hello 2.简述GNU gdb的功能。
答:gdb是Linux系统中一个功能强大的GNU调试程序,它可以调试C和C++程序,使程序开发者在程序运行时观察程序的内部结构和内存的使用情况。gdb提供如下功能: (1)运行程序,设置所有的能影响程序运行的参数和环境; (2)控制程序在指定的条件下停止运行; (3)当程序停止时,可以检查程序的状态; (4)修改程序的错误,并重新运行程序; (5)动态监视程序中变量的值;
(6)可以单步逐行执行代码,观察程序的运行状态; (7)分析崩溃程序产生的core文件。 3.用gdb调试下面的程序。 #include
char my_string[] = \ my_print (my_string); my_print2 (my_string); }
my_print (char *string) {
printf (\}
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 (\}
答:gcc -g -o greeting greeting.c
这个程序执行时显示结果: The string is hello there The string printed backward is
输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的。我们所设想的输出应该是: The string printed backward is ereht olleh。
由于某些原因, my_print2 函数没有正常工作。用gdb 看调试程序, 先键入如下命令:
gdb greeting
-------------------------------------------------------------------------------- 注意: 记得在编译 greeting 程序时把调试选项打开. -------------------------------------------------------------------------------- 用gdb的run命令运行greeting。 (gdb) run
Starting program: /root/greeting 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 将作出如下的响应: