linux下C语言使用编译与调试试验.docx
- 文档编号:11718863
- 上传时间:2023-03-31
- 格式:DOCX
- 页数:14
- 大小:242.07KB
linux下C语言使用编译与调试试验.docx
《linux下C语言使用编译与调试试验.docx》由会员分享,可在线阅读,更多相关《linux下C语言使用编译与调试试验.docx(14页珍藏版)》请在冰豆网上搜索。
linux下C语言使用编译与调试试验
实验四:
LINUX下C语言使用、编译与调试实验
一、目的:
1、练习并掌握Linux提供的vi编辑器来编译C程序
2、学会利用gcc、gdb编译、调试C程序
3、学会使用make工具
二、内容
1、编写C语言程序,用gcc编译并观察编译后的结果,运行生成的可执行文件。
2、利用gdb调试程序。
3、学习编写makefile,并进行编译。
三、操作
1、文件编辑器vi
进入vi,直接执行vi编辑程序。
例:
#vitest.c
显示器出现vi的编辑窗口,同时vi会将文件复制一份至缓冲区(buffer)。
vi先对缓冲区的文件进行编辑,保留在磁盘中的文件则不变。
编辑完成后,使用者可决定是否要取代原来旧有的文件。
1)vi的工作模式
(1)输入模式
输入以下命令即可进入vi输入模式:
a
在光标之后加入资料
A
在该行之末加入资料
i
在光标之前加入资料
I
在该行之首加入资料
o
新增一行于该行之下
O
新增一行于该行之上
(2)命令模式
在输入模式下,按ESC可切换到命令模式。
命令模式下,可选用下列指令离开vi:
:
q!
离开vi,并放弃刚在缓冲区内编辑的内容
:
wq
将缓冲区内的资料写入磁盘中,并离开vi
ZZ
同wq
:
x
同wq
:
w
将缓冲区内的资料写入磁盘中,但并不离开vi
:
q
离开vi,若文件被修改过,则要被要求确认是否放弃修改的内容,此指令可与:
w配合使用
(3)命令模式下光标的移动
h
左移一个字符
j
下移一个字符
k
上移一个字符
l
右移一个字符
0(零)
移至该行的行首
$
移至该行的行尾
^
移至该行的第一个字符处
H
移至窗口的第一行
M
移至窗口中间那一行
L
移至窗口的最后一行
G
移至该文件的最后一行
W,w
下一个单词(W忽略符号)
B,b
上一个单词(B忽略符号)
(4)命令模式下的编辑命令
dd
删除当前光标所在行
yy
复制当前光标所在行
p
将复制的内容粘贴在光标所在的位置后
P
将复制的内容粘贴在光标所在的位置前
x
删除当前光标字符
X
删除当前光标之前字符
u
撤消
·
重做
2、GNUC编译器
1)使用gcc
通常后跟一些选项和文件名来使用gcc编译器。
gcc命令的基本用法如下:
gcc[options][filenames]
命令行选项指定的编译过程中的具体操作
2)gcc常用选项
当不用任何选项编译一个程序时,gcc将建立(假定编译成功)一个名为a.out的可执行文件。
选项含义:
-oFILE指定输出文件名,在编译为目标代码时,这一选项不是必须的。
如果FILE没
有指定,默认文件名是a.out.
例如,
#gcctest.c
编译成功后,当前目录下就产生了一个a.out文件。
也可用-o选项来为即将产生的可执行文件指定一个文件名来代替a.out。
例如:
#gcc–ocountcount.c
此时得到的可执行文件就不再是a.out,而是count。
-cGCC仅把源代码编译为目标代码。
默认时GCC建立的目标代码文件有一个.o的
扩展名。
-E对文件进行预处理
-S对文件进行编译,生成汇编代码。
-O对源代码进行基本优化。
这些优化在大多数情况下都会使程序执行得更快。
-g在可执行程序中包含标准调试信息。
-Wall允许发出GCC能提供的所有有用的警告,也可以用-W(warning)来标识指定的
警告。
-lname链接静态库
-Ldir库文件的搜索路径
3)执行文件
格式:
./可执行文件名
例:
#./a.out
#./count
4)例子
mypow.c:
定义mypow()函数
unsignedlonglongmypow(unsignedintx,unsignedinty)
{
unsignedlonglongres=1;
if(y==0)
res=1;
elseif(y==1)
res=x;
else
res=x*mypow(x,y-1);
returnres;
}
powtest.c:
调用mypow()函数
#include
#include
intmain(intargc,char*argv[])
{
unsignedintx,y;
unsignedlonglongres;
if((argc<3)||(sscanf(argv[1],"%u",&x))!
=1||(sscanf(argv[2],"%u",&y))!
=1)
{
printf("Usage:
powbaseexponent\n");
exit
(1);
}
res=mypow(x,y);
printf("%u^%u=%u\n",x,y,res);
return0;
}
编译过程:
#gcc-cmypow.c
#arrcsvlibpow.amypow.o
a-mypow.o
#gcc-opowtestpowtest.c-L.-lpow
#./powtest
Usage:
powbaseexponent
#./powtest210
2^10=1024
3、gdb调试工具
1)调试编译代码
为了使gdb正常工作,必须使你的程序在编译时包含调试信息。
调试信息里包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号。
gdb利用这些信息使源代码和机器码相关联。
在编译时用–g选项打开调试选项。
2)gdb基本命令
命令
描述
file
装入欲调试的可执行文件
kill
终止正在调试的程序
list
列出产生执行文件的源代码部分
next
执行一行源代码但不进入函数内部
step
执行一行源代码并进入函数内部
run
执行当前被调试的程序
quit
终止gdb
watch
监视一个变量的值而不管它何时被改变
break
在代码里设置断点,使程序执行到这里时被挂起
make
不退出gdb就可以重新产生可执行文件
shell
不离开gdb就执行UNIXshell命令
3)调试程序
(1)源程序gdbtest1.c,分析程序的功能,如果出错,要求用gdb进行调试并给出修改方案。
基本步骤:
♦编译:
gcc-g-ogdbtest1gdbtest1.c
♦运行:
./gdbtest1
♦开始调试:
gdbgdbtest1
#include
intadd_range(intlow,inthigh)
{
staticinti,sum;
for(i=low;i<=high;i++)
sum=sum+i;
returnsum;
}
intmain(void)
{
intresult[100];
result[0]=add_range(1,10);
result[1]=add_range(1,100);
printf("result[0]=%d\nresult[1]=%d\n",result[0],result[1]);
return0;
}
(2)源程序greet.c,功能:
按照正序和逆序输出给定的字符串。
要求用gdb进行调试,,分析出错的原因并给出修改方案。
#include
#include
#include
voidmy_print(char*string);
voidmy_print2(char*string);
intmain()
{
charmy_string[]="hellothere";
my_print(my_string);
my_print2(my_string);
return0;
}
voidmy_print(char*string)
{
printf("Thestringis%s\n",string);
}
voidmy_print2(char*string)
{
char*string2;
intsize,i;
size=strlen(string);
string2=(char*)malloc(size+1);
for(i=0;i string2[size-i]=string[i]; string2[size+2]='\0'; printf("Thestringprintedbackwardis%s\n",string2); } 4、make的使用 (1)用vi编辑以下程序,程序清单: main.c function1.h function1.c function2.h function2.c //main.c #include"function1.h" #include"function2.h" intmain(intargc,char**argv) { function1_print("hello"); function2_print("world"); return0; } //function1.h voidfunction1_print(char*str); //function1.c #include"function1.h" voidfunction1_print(char*str) { printf("Thisisfunction1print%s\n",str); } //function2.h voidfunction2_print(char*str); //function2.c #include"function2.h" voidfunction2_print(char*str) { printf("Thisisfunction2print%s\n",str); } 实验要求: (1)画出各个源程序、目标文件以及最终的目标文件之间的依赖关系图。 (2)编辑makefile文件 (3)利用make命令进行上述程序的编译,生成可执行代码并运行。 (4)修改其中一个源文件,重新make,察看编译过程。 (5)通过使用makefile变量和隐含规则,对makefile文件进行简化 四.试验总结 调试程序 (1)源程序gdbtest1.c,分析程序的功能,如果出错,要求用gdb进行调试并给出修改方案。 基本步骤: ♦编译: gcc-g-ogdbtest1gdbtest1.c ♦运行: ./gdbtest1 ♦开始调试: gdbgdbtest1 2)源程序greet.c,功能: 按照正序和逆序输出给定的字符串。 要求用gdb进行调试,,分析出错的原因并给出修改方案。 输出的第一行是正确的,但第二行打印出来的东西不是所期望的。 my_print2没有正常工作,用GDB调试,首先载入greet可执行文件: 用run命名运行greet,欲行结果如下: 运行结果和外面的运行结果一样,同样没有反序输出,用list命令列出源代码: 在24行设置一个断点: 再次输入run命令,结果如下图: 能通过设置一个观察string2[size-1]变量值得观察点来查看错误是怎么产生的,输入如下指令: 用next命令一步步执行for循环,如下图: 这个值正是期望的,后来的数次循环的结果都是正确的。 当i=10时,表达式string2[size-1]的值等于e,size-1的值等于1,最后一个字符已经复制到字符串里了。 如果再把循环执行下去,会看到已经没有值分配给string2[0]了,而它是字符串的第一个字符,因为malloc函数字分配内存时把它们初始化为空(null)字符,所以string2的第一个字符是空字符,这就解释了打印string2时没有任何输出的原因。 改正: 需要把代码里写入string2的第一个字符的偏移量改为size-1,即在第21行后加入如下代码: size2=size-1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 语言 使用 编译 调试 试验