建设官方企业网站,网站建设合同书 简易,国字型布局网站,为什么邮箱突然进不去了总提示正在进入不安全网站预处理、动态库、静态库
1. 声明与定义分离 一个源文件对应一个头文件 注意#xff1a; 头文件名以 .h 作为后缀头文件名要与对应的原文件名 一致 例#xff1a;
源文件#xff1a;01_code.c
#include stdio.h
int num01 10;
int num02 20;
void add(int a, in…预处理、动态库、静态库
1. 声明与定义分离 一个源文件对应一个头文件 注意 头文件名以 .h 作为后缀头文件名要与对应的原文件名 一致 例
源文件01_code.c
#include stdio.h
int num01 10;
int num02 20;
void add(int a, int b)
{int sum a b;printf(%d %d %d\n, a, b, sum);
}void mul(int a, int b)
{int mul a b;printf(%d %d %d\n, a, b, mul);
}头文件01_code.h
extern int num01;
extern int num02;
extern void add(int, int);
extern void mul(int, int);测试文件test.c
#include stdio.h
#include 01_code.hint main(int argc, char const *argv[])
{printf(num01 %d\n, num01);printf(num02 %d\n, num02);add(10, 20);mul(10, 20);return 0;
}编译 命令gcc test.c 01_code.c ./a.out 输出 num01 10
num02 20
10 20 30
10 20 302. 预处理
2.1 c语言编译过程
gcc -E hello.c -o hello.i 1、预处理
gcc -S hello.i –o hello.s 2、编译
gcc -c hello.s -o hello.o 3、汇编
gcc hello.o -o hello_elf 4、链接1、预编译 将 .c 中的头文件展开、宏展开生成的文件是 .i 文件 2、编译 将预处理之后的 .i 文件生成 .s 汇编文件 3、汇编 将 .s 汇编文件 生成 .o 文件 4、链接 将 .o 文件 链接成目标文件即可执行文件 预编译包含
展开头文件
定义头文件
选择性编译注意:预编译的内容以 # 开头2.2 include
作用展开头文件
语法
#include 用尖括号包含的头文件, 在 系统指定的路径下 找头文件 #表示预编译 #include 用 双引号 包含头文件先在当前目录下找 头文件找不到再到系统指定的路径下找 注意 1、include 经常用来包含头文件可以包含 .c 文件但是大家不要包含 .c 因为 include 包含的文件会在预编译被展开如果一个.c 被包含多次展开多次会导致函数重复定义。所以不要包含.c 文件 2、预处理只是对 include 等预处理操作进行处理并 不会进行语法检查这个阶段有语法错误也不会报错第二个阶段即 编译阶段才进行语法检查。 例
#include 01_code.h//等价于 下面, 即在源文件中展开下面代码extern int num01;
extern int num02;
extern void add(int, int);
extern void mul(int, int);2.2 宏define
作用在预处理 处理定义 类似于 变量或函数的东西。即宏是在预编译的时候进行替换 。
2.2.1 不带参宏
语法
#define 宏名 值 //宏定义#undef 宏名 //取消宏定义注意 1、如果定义该类型的宏不带参的宏值可以省略 2、无需分号结束 3、在 宏定义后取消定义前 可以使用 4、只能在 当前文件中 使用 例
#include stdio.h
#define PI 3.14
int main(int argc, char const *argv[])
{printf(pi %f\n, PI);
#undef PI //取消宏定义return 0;
}2.2.2 带参宏
语法
#define 宏名(形参) 体注意 1、形参没有数据类型 2、带参宏与带参函数的区别 宏在预编译时 对其进行 替换如果一个文件中多次使用宏那意味着要替换多次此时就需占用内存所以占据的内存多 产生的预编译时期占内存多速度快 函数在程序运行时在代码区存储一份每次调用该函数都需在代码区寻找将其放入栈内存中(压栈)当函数执行完毕后从栈中移除(弹栈) 产生在运行时占内存少 例
#include stdio.h
#define ADD(a, b) ab
#define MUL(a, b) a*b
#define MUL02(a, b) (a)*(b)
int main(int argc, char const *argv[])
{int sum ADD(20, 30);printf(sum%d\n, sum);int mul MUL(20, 30);printf(mul%d\n, mul);int mul02 MUL(2010, 3010); //20 10 * 30 10printf(mul%d\n, mul02);int mul03 MUL02(2010, 3010); //(20 10) * (30 10)printf(mul%d\n, mul03);return 0;
}2.2.3 小结 宏就是在预编译时期对其进行替换 不带参宏替换的是一个值 带参宏替换的是一段代码 2.3 选择性编译
作用选择代码是否被编译
语法
例1判断存在
优点节省内存只加载需要的部分
#include stdio.hint main(int argc, char const *argv[])
{#ifdef XXXprintf(有定义宏名为XXX的宏\n);#elseprintf(没定义宏XXX\n);#endifreturn 0;
}编译时定义宏 例2判断不存在和头文件配合使用防止多次引用头文件
#include stdio.h
#include 04_test.h
#include 04_test.h
int main(int argc, char const *argv[])
{#ifndef YYYprintf(1111\n);#elseprintf(2222\n);#endifreturn 0;
}头文件04_test.h
#ifndef TEST
#define TEST
extern int num;
//...
#endif#ifndef 使用含义 1、第一次引用头文件没有定义TEST宏然后定义再写头文件内容 2、假如再次引用头文件时第一次已经定义过TEST宏了所以直接结束啥也不干。 源码写法 例3判断是否成立
#include stdio.h
int main(int argc, char const *argv[])
{#if ScORE 85printf(A\n);#elif ScORE 70printf(B\n);#elif ScORE 60printf(c\n);#elseprintf(D\n);#endifreturn 0;
}3. 库
概念库也叫代码库可以把一个些目标文件合并在一起方便使用。
3.1 分类 静态库 动态库 静态库、动态库的区别 注意 程序中引入的文件在动态库与静态库同时存在两份静态编译程序引入静态库中的该文件动态编译程序引入动态库中的该文件 3.2 编译命令
动态编译
gcc 源文件名 -o 生成的可执行文件名静态编译
gcc -static 源文件名 -o 生成的可执行文件名3.3 静态库
3.3.1 制作
gcc -c 源文件名.c -o 生成的二进制文件名.o
ar rc lib静态库名称.a 生成的二进制文件名.o注意静态库起名的时候必须 以 lib 开头 以 .a 结尾 步骤 新建文件夹 06_code 源文件myfun.c #include stdio.hvoid add(int a, int b)
{printf(my_sum %d\n, (ab));
}void mul(int a, int b)
{printf(my_mul %d\n, (a*b));
}头文件myfun.h extern void add(int a, int b);
extern void mul(int a, int b);制作
3.3.2 使用
情况1使用静态库的文件与静态库 在同一文件夹下
命令
gcc 源文件名 静态库名称 -o 生成的可执行文件名测试文件test01.c
#include stdio.h
#include myfun.h //可以不写但是会报警告
int main(int argc, char const *argv[])
{add(10, 3);return 0;
}编译 情况2使用静态库的文件与静态库 不在同一文件夹下 注意: 为了让静态库文件与其对应的头文件和使用静态库文件不在同一文件夹下所以 创建includes与libs文件夹 includes文件用于存储头文件 libs文件夹存储静态库文件 mkdir includes
mkdir libs
mv myfun.h includes/
mv libmyfun.a libs/参数 -L 引用的静态库所在的路径
-l 静态库名, 去掉lib与.a
-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 生成的可执行文件名 3.4 动态库
3.4.1 制作
命令
gcc -shared 源文件名 -o 生成的动态库文件名.so3.4.2 使用
情况1使用动态库的文件与动态库在同一文件夹下 命令: gcc 源文件名 动态库名称 -o 生成的可执行文件名 情况2使用动态库的文件与动态库不在同一文件夹下 命令 gcc 源文件名 -L 动态库所在路径 -l 动态库名称 -I 头文件所在路径注意 动态库名需要去掉前面的 lib 与后面 .so 情况3静态库文件与对应的头文件在系统文件夹下 命令 gcc 源文件名 -l 静态库名 -o 生成的可执行文件名