一、cc初体验
unix下C程序总是在交叉循环4个步骤:编写程序、编译程序、执行程序、调试程序, 编译程序一般使用cc编译器。
1.编写程序
#include <stdio.h> void main(){ printf("Hello World!"); }
保存为hello.c
2.编译程序
cc -o hello ./hello.c
3.执行程序
./test /*输出 Hello World!*/
4.cc几个常用编译选项
/* cc [选项] 文件... -o <文件> 输出到 <文件> -c 编译、汇编到目标代码,不进行链接 -g 使目标程序可以进行gdb调试 -I 在指定目录中查找头文件 -L 指定动态库查找的路径 -l 一般与-L一起使用,指定具体加载哪个动态库,如-llibsocket.a或-lsocket
-O 优化程序 */
二、使用GDB调试器
在unix上没有C集成的开发环境,更不用说调试工具了,gdb是符号级调试工具。它能控制程序的内部执行,利用断点设置、单步运行等手段,逐步调试程序,为适合gdb的调试,在使用cc编译程序的时候,加上-g选项,不然不能生成相关的调试标志,不能使用gdb进行调试。
1.源程序
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main(){ 5 int i=0; 6 for(; i<10; i++){ 7 printf("%d\n", i); 8 } 9 exit(EXIT_SUCCESS); 10 }
保存为Hello.c;
cc -g -o Hello ./Hello.c
2.如何调试
/* #gdb [选项] [可执行文件] */
3.调试命令
/* l或list 显示程序源代码 b n或break n break 1代表在第一行设置断点, break main 代表在main函数入口处设置断点 clear n 删除第n行的断点,不带参数代表删除全部 info break 查看断点信息 s或step 单步执行代码,可以进入函数内部 n或next 单步执行代码,但不进入函数内部 continue 继续执行代码,知道下一断点或程序结束 watch var 监视变量变化 q或quit 退出gdb调试 */
三、 库文件使用
世界上本没有库,代码封装的多了,也就有库了。库分为静态库和动态链接库两种。静态库一般以.a为后缀名,在程序编译时链接到目标程序中,在程序运行时不需要静态库的支持。动态库一般以.so为后缀名,在编译时不会链接到目标程序中,在程序运行时载入。动态函数库又有显示调用和隐式调用两种。
1.创建自己的静态库
分为三个步骤:编写源代码、生成以.o为后缀的中间目标文件,使用ar生成静态库
(1)编写源代码
/*自定义函数print*/ void print(){ printf("I'am here!"); }
保存为print.c
(2)编译.o中间目标文件
cc -c ./print.c //-c生成中间目标文件print.o
(3)生成静态库
为了编译程序尽可能争取查找库文件,静态库文件要以lib[name].a方式命名,其它命名也可以,不过你要编译的时候要指定全名。
ar -r libprint.a ./print.o //生成静态库文件libprint.a
(4)链接静态库
#include <stdio.h> #include <stdlib.h> int main(){ print(); //调用自定义库中的print函数 exit(EXIT_SUCCESS); }
保存为printTest.c
cc -o printTest -O ./printTest.c -L./ -lprint //链接libprint.a静态库,生成printTest可执行文
执行printTest
./printTest //输出Iam here
2.生成动态库
动态库的生成分为三个步骤: 设计源代码、 生成编译位置无关码型(PIC).o文件、生成动态库
gcc -fpic -c print.c //生成编译位置无关码(PIC)型print.o文件 gcc -shared -o print.so print.o //生成动态库
或一步到位
gcc -fpic -shared -o libprint.so ./ibprint.c