学习需要方法和策略,更需要灵活和创新
预处理
1.预编译
展开头文件
定义宏
选择性编译
注意:
预编译的内容以#开头
2.编译
3.汇编
4.链接
include
作用:展开头文件
语法
#include <> 用尖括号包含头文件,在系统指定的路径下找头文件
#include " " 用双引号包含的头文件,先在当前目录下找头文件,找不到再到系统指定的 路径下寻找
注意:
1.include 经常用来包含头文件,可以包含.c文件,但是不建议包含.c文件。因为include包含的文件会在预编译被展开,如果一个.c被包含多次,展开多次,会导致函数重复定义,所以不建议包含.c文件
2.预处理只是对include 等预处理操作进行处理并不会进行语法检查。这个阶段即使有语法错误也不会报错,第二个阶段即预编译阶段才会进行语法检查
宏:define
作用:在预处理处理类似于变量或函数的东西
语法
#define 宏名 值
注意:
1.如果定义该类型的宏(不带参的宏),值可以省略不写
2.无需分号结束
3.在宏定义后,取消定义前可以使用
4.只能在当前文件中使用
宏名建议全大写
#incldue <stdio.h>
#define PI 3.14
#define x
int main()
{
printf("PI=%f\n",PI);
#undef PI //取消宏定义
return 0;
}
#define 宏名(形参) 体
如:
#define add(a,b) (a)*(b);
add(1+1,5+5)
1+1 * 5+5 ❌
(1+1) * (5+5) ✔
#undef 宏名 取消宏定义
注意:
1.形参没有数据类型
带宏参与带参函数的区别
宏:在预编译时对其进行替换,如果一个文件中多次使用宏,将意味着替换多次,调用一次就会生成一次,此时就会占用的内存就会增加
产生于预编译时期
占用内存多
速度快
函数:在程序运行时会在代码区存储一份,每次调用函数都需要在代码区寻找,将其放入栈内存中(压栈),当函数执行完毕时,从栈中移出
产生于程序运行时
占用内存少
总结
宏就是在预编译时期进行替换
不带参宏替换的就是一个值
带参宏替换的就是一段代码
选择性编译
作用:选择代码是否被编译
语法
xxx表示宏名
库
概念
库也叫代码库,可以把一些目标文件合并在一起方便使用
分类
静态库
动态库
静态库与动态库的区别
注意:
程序中引入的文件在动态库与静态库同时存在两份
静态编译程序引入静态库中的该文件
动态编译程序引入动态库中的该文件
编译命令
动态编译
gcc 源文件名 -o 生成的可执行文件名
静态编译
gcc -static 源文件名 -o 生成的可执行文件名
静态库
制作
gcc -c 源文件名.c -o 生成的二进制文件名.o
ar rc lib静态库名称.a 生成的二进制文件名.o
注意:静态库起名时必须以lib开头以.a结尾
使用
情况1:使用静态库的文件与静态库在同一文件夹下
命令:
gcc 源文件名 静态库名称 -o 生成的可执行文件名
情况2:使用静态库的文件与静态库不在同一文件夹下
注意:
为了让静态库文件与其对应的头文件和使用静态库文件不在同一文件夹下
创建include与libs文件夹
includes文件用于存储头文件
libs文件夹存储静态库文件
mkdir includes
mkdir libs
mv myfun.h includes/
mv libmyfun.a libs/
-L 引用的静态库所在的路径
-l(小写L) 静态库名,不要lib与.a
-I(大写i) 头文件所在路径
命令:
gcc 源文件名 -L 静态库所在的路径 -l 静态库名 -I头文件所在路径 -o 生成的可执行文件名
情况3:静态库文件与对应的头文件在系统文件夹下
系统库路径:
/usr/include 存储头文件
/usr/lib 或 /lib 存储库文件
注意:
为了让静态库文件与其对应的头文件在系统文件夹下,需要移动
sudo mv includes/myfun.h /usr/include
sudo mv libs/libmyfun.a /usr/lib
命令:
gcc 源文件名 -l 静态库名 -o 生成的可执行文件名
动态库
制作
命令
gcc -shared 源文件名 -o 生成的动态库文件名.so
- 表示选项
使用
情况1:使用动态库的文件与动态库在同一文件夹下
命令:
gcc 源文件名 动态库名称 -o 生成的可执行文件名
情况2:使用动态库的文件与动态库不在同一文件夹下
命令:
gcc 源文件名 -L 动态库所在路径 -l 动态库名称 -I 头文件所在路径 -D 宏
注意:
动态库名需要取前面的lib与后面的.so
情况3:静态库文件与对应的头文件在系统文件夹下
gcc 源文件名 -l 静态库名 -o 生成的可执行文件名
注意:
运行中出现动态库找不到问题,需要将动态库所在目录导入用户环境变量
export LD_LIBRARY_PATH=库文件所在路径:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH