预编译
C语言编译的4个阶段:预编译,编译,汇编,链接
预处理阶段会在源代码中查找预编译指令,其中主要是头文件展开(include),宏替换(define),选择性编译(ifdef)三种指令
预处理命令以符号#开头
优点:
1,扩展了C程序设计的环境
2,简化程序开发过程
3,提高程序的可读性
注意;
1,实际上不是C语言的一部分
2,预编译指令在编译前由预处理程序对源文件的预处理文件进行加工
include
作用:
引入头文件
在预编译阶段,“#include” 指令会将该行代码替换为所引入的头文件中的实际代码内容
语法:
1,#include <要引入的头文件名>
用尖括号包含头文件,在系统指定的路径下找头文件
2,#include "要引入的头文件名"
用双引号包含头文件,先在当前目录下找头文件,找不到,再到系统指定的路径下找
注意:
1,include经常用来包含头文件,也可以包含源文件,也可以在头文件中定义函数,但是不建议包含源文件和定义函数
2,预处理只是对include等预处理操作进行处理并不会进行语法检查,编译阶段才会检查语法是否有误
define:宏
分类:
不带参宏
带参宏
不带参宏
步骤:
1,宏定义
静态定义
#define 宏名称 值
注意:值可有可无
动态定义
在代码编译时加
-D 宏名=值 或 -D 宏名
2,使用宏
宏名称
3,取消宏
#undef 宏名称
注意:
一旦取消宏,该宏名不能再使用
使用范围:
宏定义开始到取消宏
带参宏
步骤:
1,宏定义
#define 宏名称(形参列表) 代码;
2,使用宏
宏名称(实参列表);
3,取消宏
#undef 宏名称
带参宏与带参函数的区别
带参宏被调用多少次就会展开多少次,执行代码时没有函数调用的过程,不需要压栈弹栈,所以带参宏是浪费了空间,因为被展开多次,节省时间
带参函数,代码只有一份,存在代码段,调用的时候去代码段取指令,调用的时候要压栈弹栈,有调用过程,带参函数是浪费了时间,节省了空间
选择性编译
作用:
选择性地对代码进行编译
语法:
判断存在
#ifdef XXX
语句1;
#else
语句2;
#endif
如果定义了宏XXX编译语句1,否则编译语句2
判断不存在
#ifndef XXX
语句1;
#else
语句2;
#endif
如果没定义宏XXX编译语句1,否则编译语句2
判断是否成立
#if XXX
语句1;
#else
语句2;
#endif
如果XXX为真编译语句1,否则编译语句2
头文件模版
#ifndef 自定义宏
#define 自定义宏
引入头文件
声明变量
声明函数
#endif
注意:此时需要在该头文件对应的源文件中引入这个头文件。另外,在使用该源文件中函数的其他源文件中也需要引入这个头文件,这样做可以避免重复声明的问题。
动态库与静态库
程序编译
分类:
静态编译: gcc -static 源文件名 -o 生成的可执行文件名
动态编译: gcc 源文件名 -o 生成的可执行文件名
静态编译与动态编译的区别
静态编译使用静态库,生成的可执行程序大,对库依赖小
动态编译使用动态库,生成的可执行程序小,对库依赖大
静态库:
链接阶段,不管使用静态库中几个函数,都是加载整个静态句
动态库:
第一步:在链接阶段,只是建立和所需要函数的关系
第二步:在运行阶段,才将所需要的函数拷贝到可执行文件中
动态库
制作:
gcc -shared 源文件名 -o lib动态库名.so
注意:
如果制作动态时出现以下问题,需给制作动态库的命令加-fPIC
使用:
使用动态库的源文件与动态库在同一文件下
gcc 源文件名 lib动态库名.so -o 可执行文件名
注意:
如果在执行可执行程序时出现一下问题需要加入
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH使用动态库的源文件与动态库不在同一文件夹下
gcc 源文件名 -o 生成的可执行文件名 -L库文件路径 -l库名 -I头文件所在路径
注意:
-L 是指定库文件的路径
-l 指定找哪个库,指定的只要库文件名 lib 后面 .so 前面的部分-I 指定头文件的路径如果出现以下问题, 需要加入export LD_LIBRARY_PATH=库文件所在路径 :$LD_LIBRARY_PATH动态库文件在系统提供的文件夹系统提供的文件夹/usr/lib 系统提供存储动态库的文件夹/usr/include 系统提供存储头文件的文件夹gcc 源文件名 -l 库文件名 -o 生成的可执行文件夹
静态库
制作:
首先,把将要编译成库文件的源文件编译为二进制文件。使用如下命令:
gcc -c 源文件名 -o 二进制文件名.o
接着,将生成的二进制文件转换为静态库文件,相应的命令是:
ar rc lib库文件名.a 二进制文件名.o
使用:
使用静态库的源文件与动态库在同一文件夹下
gcc -static 源文件名 lib动态库名.a -o 可执行文件名
使用静态库的源文件与动态库不在同一文件夹下
gcc -static 源文件名 -o 生成的可执行文件名 -L库文件路径 -l库名 -I头文件所 在路径
静态库文件在系统提供的文件夹
/usr/lib 系统提供存储动态库的文件夹
/usr/include 系统提供存储头文件的文件夹gcc -static 源文件名 -l 库文件名 -o 生成的可执行文件夹