第四章 UNIX下的C语言开发环境

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

UnixProgramming第四章UNIX下的C语言开发环境1.gcc与gdb•1.1UNIX和C语言–C是一种在UNIX操作系统的早期就被广泛使用的通用编程语言,它最早是由贝尔实验室的DennisRitchie为了UNIX的辅助开发而写的。–C是所有版本的UNIX上的系统语言。–几乎任何一种计算机上都有至少一种能用的C编译器;并且它的语法和函数库在不同的平台上都是统一的。–80年代末期美国国家标准协会(AmericanNationalStandardsInstitute)发布了一个被称为ANSIC的C语言标准,这保证了在不同平台上的C的一致性。21.gcc与gdb•1.2GNUC编译器–GNUC编译器(gcc)是一个全功能的ANSIC兼容编译器,它是所有UNIX系统可用的C编译器。–gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。31.gcc与gdb•gcc编译过程:–预处理,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。–编译,就是把C/C++代码“翻译”成汇编代码。–汇编,将第二步输出的汇编代码翻译成符合一定格式的机器代码,生成以.o为后缀的目标文件。–链接,将上步生成的目标文件和系统库的目标文件和库文件链接起来,最终生成了可以在特定平台运行的可执行文件。41.UNIX下的C语言开发环境•gcc遵循的文件类型规定–.c为后缀的文件,C语言源代码文件;–.a为后缀的文件,是由目标文件构成的档案库文件;–.C,.cc或.cxx为后缀的文件,是C++源代码文件;–.h为后缀的文件,是程序所包含的头文件;–.i为后缀的文件,是已经预处理过的C源代码文件;–.ii为后缀的文件,是已经预处理过的C++源代码文件;–.m为后缀的文件,是Objective-C源代码文件;–.o为后缀的文件,是编译后的目标文件;–.s为后缀的文件,是汇编语言源代码文件;–.S为后缀的文件,是经过预编译的汇编语言源代码文件。5头文件•头文件是用来提供常量的定义和系统和函数调用的声明,这些头文件通常放在/usr/include和其子目录中。根据不同的Linux版本,头文件可能放在/usr/include/sys和/usr/include/linux.#includestdio.h库函数•库函数是一些预先编译好的函数的集合,这些函数可以有很好的重用性。通常来讲,它们包含有相关的函数集合来完成一项常用任务。典型的库函数有屏幕处理函数(curses和ncurses库)和数据库访问函数(dbm库)。•标准系统函数通常存放在/lib和/usr/lib中。C编译器需要被告知搜索哪个库,否则缺省情况下只搜索标准库。传统静态库.a•Examplesare/usr/lib/libc.aand/usr/X11/lib/libX11.aforthestandardClibraryandtheX11library共享库.so•OnatypicalLinuxsystem,thesharedversionofthestandardmathlibraryis/usr/lib/libm.so静态库•与windows的区别1.gcc与gdb•1.3gcc的使用–gcc最基本的用法:gcc[options][filenames]options就是编译器所需要的参数;filenames给出相关的文件名称;/*helloworld.c*/#includestdio.hintmain(intargc,char**argv){printf(“Hello,World!\n”);return0;}例:$gcchelloworld.c$./helloworld$Hello,World!91.gcc与gdb•1.4gcc选项-Wall:允许所有有用的警告;-o:定义输出文件;-c:只编译生成.o目标文件,不链接;-I:设置头文件的搜索路径;-L:设置库文件的搜索路径;-O:O1,O2,O3,O4,O5优化级别;-g:gdb调试用,在可执行程序中包含标准调试信息;-w:关闭所有警告;-E:完成预处理/预编译停止;101.gcc与gdb-Wall:允许所有有用的警告(建议总是使用该选项)/*bad.c*/#includestdio.hintmain(intargc,char**argv){printf(“Twoplustwois%f\n”,4);return0;}例1:$gccbad.c–obad例2:$gcc–Wallbad.c–obad111.gcc与gdb-o:定义输出文件例:编译多个源文件$gcc-Wallmain.chello.c-ohelloworld/*hello.h*/voidhello(constchar*name);/*hello.c*/#includestdio.h#includehello.hvoidhello(constchar*name){printf(Hello,%s!\n,name);}/*main.c*/#includehello.hintmain(intargc,char**argv){hello(world);return0;}121.gcc与gdb-c:只编译生成.o目标文件,不链接例:编译多个源文件$gcc-Wall-cmain.c$gcc-Wall-chello.c$gccmain.ohello.o-ohelloworld/*hello.h*/voidhello(constchar*name);/*hello.c*/#includestdio.h#includehello.hvoidhello(constchar*name){printf(Hello,%s!\n,name);}/*main.c*/#includehello.hintmain(intargc,char**argv){hello(world);return0;}包含函数定义的对象文件应当出现在调用这些函数的任何文件之后131.gcc与gdb重新编译和重新链接例:编译多个源文件$gcc-Wall-cmain.c$gccmain.ohello.o-ohelloworld/*hello.h*/voidhello(constchar*name);/*hello.c*/#includestdio.h#includehello.hvoidhello(constchar*name){printf(Hello,%s!\n,name);}/*main.c*/#includehello.hintmain(intargc,char**argv){hello(“Everyone);return0;}World-Everyone141.gcc与gdb-l:链接外部库文件•库是已经编译好并能被链接入程序的对象文件的集合。库中提供一些最常用的系统函数,比如象C的数学库中求平方根函数sqrt。•库通常被存储在扩展名为“.a”或“.so”的特殊归档文件中。•C标准库自身存放在“/usr/libc.a”中,包含ANSI/ISOC标准指定的各个函数,是默认自动加载的库。/*sqrt.c*/#includestdio.h#includemath.hintmain(intargc,char**argv){doubler=sqrt(3.0);printf((Thesquarerootof3.0is%f\n,r);return0;}例:$gcc-Wallsqrt.c-osqrtccbR6Ojm.o:Infunction‘main’:ccbR6Ojm.o(.text+0x19):undefinedreferenceto‘sqrt’151.gcc与gdb-l:链接外部库文件•函数sqrt()并不定义在源程序中或默认的C库“libc.a”中。•为了使得编译器能把sqrt()函数链接到主程序“sqrt.c”,需要提供“libm.a”库。例:$gcc-Wallsqrt.c/usr/lib/libm.a-osqrt/usr/lib/libm.a-lm$gcc-Wallsqrt.c-lm-osqrt编译器选项“-lNAME”试图链接标准库目录下的文件名为“libNAME.a”中的对象文件161.gcc与gdb-L:设置库文件的搜索路径•如果链接时用到的库不在gcc用到的标准库目录中,就会报这样的错。/usr/local/lib//usr/lib/例:$gcc-Wall-L/tmp/libsqrt.c-lm-osqrt-L/tmp/lib171.gcc与gdb-I:设置头文件的搜索路径•如果头文件不在gcc用到的标准include文件路径中,就会报这样的错。/usr/local/include//usr/include/例:$gcc-Wall-I/tmp/includesqrt.c-lm-osqrt-I/tmp/include181.gcc与gdb库的链接次序•原则:包含函数定义的库应该出现在任何使用到该函数的源文件和对象文件之后例1:$gcc-Wall-lmsqrt.c-osqrt(incorrect)$gcc-Wallsqrt.c-lm-osqrt(correct)例2:$gcc-Wallsqrt.c-lglpk-lm-osqrt•程序“sqrt.c”用到了GNULinearProgramming库“libglpk.a”,而该库又依次用到数学库“libm.a”,那么应当这么编译:191.gcc与gdb-O:O0,O1,O2,O3,O4,O5,Os优化级别例:$gcc-Wall-O3sqrt.c-lm-osqrt•O1~O5选项,数字越大优化级别越高;•Os选项选择缩减可执行文件大小的优化。它的目的是为内存和磁盘空间受限的系统生成尽可能小的可执行文件;•绝大部分目的而言,调试时用“-O0”,开发和部署时用“-O2”就足够了。201.gcc与gdb•通常,可执行文件并不包含原来程序中源代码的任何引用信息,比如象变量名或行号----可执行文件只是编译器生成的作为机器码的指令序列。•gcc提供了“-g”调试选项来在对象文件和可执行文件中存储另外的调试信息。这些调试信息可以使得在追踪错误时能从特定的机器码指令对应到源代码文件中的行。-g:存储调试信息211.gcc与gdb•1.5gdb调试和分析选项–gdb基本命令•file装入想要调试的可执行文件;•kill终止正在调试的程序;•list列出产生执行文件的源代码的一部分;•next执行一行源代码但不进入函数内部;•step执行一行源代码而且进入函数内部;•run执行当前被调试的程序;•quit终止gdb;•watch使你能监视一个变量的值而不管它何时被改变;•break在代码里设置断点,这将使程序执行到这里时被挂起;•make使你能不退出gdb就可以重新产生可执行文件;•shell使你能不离开gdb就执行UNIXshell命令.221.gcc与gdb•gdb调试举例/*gdbtest.c*/#includestdio.hintsum(intm);intmain(intargc,char**argv){inti,n=0;sum(50);for(i=1;i=50;i++){n+=i;}printf(“Thesumof1-50is%d\n”,n);}intsum(intm){inti,n=0;for(i=1;i=m;i++){n+=i;}printf(“Thesumof1-%dis%d\n”,m,n);}例:$gcc-Wall-ggdbtest.c-ogdbtest231.gcc与gdb1.启动gdb开始调试例1:$gdbgdbtest例2:$gdb(gdb)filegdbtest241.gcc与gdb2.在gdb中查看源代码例:(gdb)listlist也可以缩写为l251.gcc与gdb3.在gdb中设置断点例1:(gdb)break9break也可以

1 / 50
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功