预处理、动态库、静态库
1. 声明与定义分离
注意:
例:
#include <stdio.h>
int num01 = 10;
int num02 = 20;
void add(int a, int b)
{
int sum = a + b;
printf("%d + %d = %dn", a, b, sum);
}
void mul(int a, int b)
{
int mul = a + b;
printf("%d + %d = %dn", a, b, mul);
}
extern int num01;
extern int num02;
extern void add(int, int);
extern void mul(int, int);
#include <stdio.h>
#include "01_code.h"
int main(int argc, char const *argv[])
{
printf("num01 = %dn", num01);
printf("num02 = %dn", num02);
add(10, 20);
mul(10, 20);
return 0;
}
编译:
2. 预处理
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、预编译
2、编译
3、汇编
4、链接
预编译包含
展开头文件
定义头文件
选择性编译
注意:
预编译的内容以 # 开头
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 宏名 //取消宏定义
注意:
2、无需分号结束
例:
#include <stdio.h>
#define PI 3.14
int main(int argc, char const *argv[])
{
printf("pi = %fn", PI);
#undef PI //取消宏定义
return 0;
}
2.2.2 带参宏
语法:
#define 宏名(形参) 体
注意:
例:
#include <stdio.h>
#define ADD(a, b) a+b
#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=%dn", sum);
int mul = MUL(20, 30);
printf("mul=%dn", mul);
int mul02 = MUL(20+10, 30+10); //20 + 10 * 30 +10
printf("mul=%dn", mul02);
int mul03 = MUL02(20+10, 30+10); //(20 + 10) * (30 + 10)
printf("mul=%dn", mul03);
return 0;
}
2.2.3 小结
2.3 选择性编译
语法:
#include <stdio.h>
int main(int argc, char const *argv[])
{
#ifdef XXX
printf("有定义宏名为XXX的宏n");
#else
printf("没定义宏XXXn");
#endif
return 0;
}
编译时定义宏:
#include <stdio.h>
#include "04_test.h"
#include "04_test.h"
int main(int argc, char const *argv[])
{
#ifndef YYY
printf("1111n");
#else
printf("2222n");
#endif
return 0;
}
头文件:04_test.h
#ifndef TEST
#define TEST
extern int num;
//...
#endif
#ifndef 使用含义:
#include <stdio.h>
int main(int argc, char const *argv[])
{
#if ScORE > 85
printf("An");
#elif ScORE > 70
printf("Bn");
#elif ScORE >= 60
printf("cn");
#else
printf("Dn");
#endif
return 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
步骤:
-
源文件:
myfun.c
#include <stdio.h> void add(int a, int b) { printf("my_sum = %dn", (a+b)); } void mul(int a, int b) { printf("my_mul = %dn", (a*b)); }
-
头文件:
myfun.h
extern void add(int a, int b); extern void mul(int a, int b);
3.3.2 使用
情况1:使用静态库的文件与静态库 在同一文件夹下
命令:
gcc 源文件名 静态库名称 -o 生成的可执行文件名
#include <stdio.h>
#include "myfun.h" //可以不写,但是会报警告
int main(int argc, char const *argv[])
{
add(10, 3);
return 0;
}
编译:
情况2:使用静态库的文件与静态库 不在同一文件夹下
注意:
情况3:静态库文件与对应的头文件 在系统文件夹下
3.4 动态库
3.4.1 制作
命令:
gcc -shared 源文件名 -o 生成的动态库文件名.so
3.4.2 使用
情况1:使用动态库的文件与动态库在同一文件夹下
命令:
gcc 源文件名 动态库名称 -o 生成的可执行文件名
情况2:使用动态库的文件与动态库不在同一文件夹下
命令:
gcc 源文件名 -L 动态库所在路径 -l 动态库名称 -I 头文件所在路径
注意:
情况3:静态库文件与对应的头文件在系统文件夹下
命令:
gcc 源文件名 -l 静态库名 -o 生成的可执行文件名
原文地址:https://blog.csdn.net/zhb_feng/article/details/134741771
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_22936.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!