淮海工学院计算机工程学
实验报告书
评语:
成绩:指导教师:
批阅时间:年月
实验目的与要求
1. 掌握Linux C 开发过程中的基本概念;
2. 掌握如GCC GDB等开发工具的使用。
二、实验内容
1. 将参考代码录入到文件中,编译执行后发现结果与预期不一致,请使用GDE调试,
完成字符串反序输出功能。
三、参考源代码
#include <>
#include <>
#include <>
int reverse_str(char *string);
int main (void) {
char string[] = "Linux C Tools : GCC and GDB"; printf ("The original string is %s \n", string); reverse_str (string);
}
int reverse_str (char *str) {
char *new_str;
int i, size;
size = strlen (str);
if((new_str = (char *) malloc (size + 1)) == NULL) { return -1;
}
for (i = 0; i < size; i++)
new_str[size - i] = str[i];
new_str[size+1] = ' ';
printf("The reversed string is %s\n",new_str); free(new_str);
return 0 ;
}
四、实验步骤
步骤1. 编辑源代码
mkdir test1
cd test1
gedit
(1) 使用gedit 编辑器,建议课外学习vim;
(2) 分析代码中语句功能。
步骤 2. 编译源代码
gcc -o test1 -g
(1) 复习gcc 常用选项;
(2) 帮助学生排查编译时错误。
(3) 分析输出结果步骤3. 调试test1
gdb test1
(1) 回顾调试的基本方法:跟踪语句执行过程,观察执行结果;
(2) 设置断点的三种基本方法:
① b <line_number>
② b <line_number> if condition_expression
③ b <function_name>
(3) 查看中间输出结果:
① p <var>
② set print element 0 p <array_name> 或<pointer>
说明:GDB中查看字符串变量值可通过“ set print element 0 ”命令,一次性显示字符串所有内容。
(4) 分析中间结果,修改28 行语句为new_str[size - i-1] = str[i];
五、实验结果与截图
1. 编写文件并编译
2. 设置断点,进行gdb 测试跟踪变量。
执行到i=27 时size-i=0 ,str[27] 已经超过str 字符串限制,于是new_str[0]= '\0 '。
输出new_str 时,由于超过限制无法输出。
所以修改程序第28行语句为new_str[size - i-1] = str[i];
正确的程序运行结果如下图所示。
六、思考题
1. 分析以下代码,完成指定范围内数值累加功能:
#include <>
/* 函数功能:将low 到high 之间的数值累加求和*/
int add_range(int low, int high) {
int i, sum;
for (i = low; i <= high; i++)
sum = sum + i;
return sum;
}
int main(void) {
int result[2];
result[0] = add_range(1, 10);
result[1] = add_range(1, 100);
printf("result[0]=%d\nresult[1]=%d\n", result[0], result[1]);
return 0;
}
答:进行累加时,局部变量sum的值会被内存保存下来,会导致数值错误,要对其初始化为0。
把int i,sum; 改为int i;int sum = 0;
2.结构化编程经常将相近功能编译成库形式,方便调用。
请查阅资料,使用GCC各一
组功能相关的源文件编译成静态库或动态库?建立库文件的源文件和如下所示:/* */
#include <>
void print1(int arg) {
printf("%d\n", arg);
}
/* */
#include <>
void print2(char* arg) {
printf("%s\n", arg);
}
调用库函数的源文件为如下:
/* */
void print1(int arg);
void print2(char* arg);
int main(int argc, char* argv[]) {
int i = 3;
char* str = "test libary!\n";
print1(i);
print2(str);
return 0 ;
}
生成静态库()并使用的基本步骤
步骤1:编译, 生成, 目标文件
gcc -c
步骤2:生成myprint 静态库文件
ar -r
步骤3:拷贝库文件到/usr/lib 目录下
sudo cp /usr/lib
说明:若不将静态链接库拷贝到/usr/lib 目录下,在调用该库时需通过GCC选项丄指定库文件所在路径
步骤4:调用静态库文件,编译生成可执行二进制文件
gcc -o main -lmyprint
生成动态链接库()并使用的基本步骤
步骤1:编译, 生成, 目标文件
gcc -c -fpic
注意:GCC选项“-fpic ”表示独立编址,运行时可计算出相应的内部地
址。
步骤2:生成myprint 动态链接库
gcc - shared -o
步骤3:拷贝库文件到/usr/lib 目录下
sudo cp /usr/lib
步骤4:调用动态库文件,编译生成可执行二进制文件
gcc -o main
七、实验体会
本次实验是Linux 的第一次实验,换了一个环境,很不适应,没有鼠标操作的情况下,可以通过上下键来选择vim,gcc 等操作,也极为方便了我们的操作,再有就是gdb,语言代码除了符合最基本的语法规范之外还必须符合设计者的逻辑意图,
如果发现生成的可执行文件运行结果不正确,则可以通过相应的调试环境
来跟踪调试,因此需要用到gdb。
比如,用来查看文件,设置断点,运行程序,查看变量,表达式的值等等,其中的step ,next 等很是重要:单步执行:step 、next,step 命令步入函数,而next 命令步过函数。
step up 将一直执行,直至当前函数将控制返回调用它的函数为止。
另外常见的gdb 命令还有file,kill,list,run,quit,make 等。