预处理动态库、静态

1. 声明定义分离

一个源文件对应一个头文件

注意:

例:

源文件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 = %dn", a, b, sum);
}

void mul(int a, int b)
{
    int mul = a + b;
    printf("%d + %d = %dn", 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&gt;
#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 <&gt; 

括号包含的头文件, 在 系统指定路径头文件

#:表示预编译

#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&gt;
#define PI 3.14
int main(int argc, char const *argv[])
{
    printf("pi = %fn", PI);
#undef PI  //取消定义
    return 0;
}
2.2.2 带参宏

语法

#define  宏名(形参)  体

注意:

1、形参没有数据类型

2、带参宏带参函数区别

例:

#include <stdio.h&gt;
#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 选择性编译

作用:选择代码是否被编译

语法
在这里插入图片描述

例1:判断存在

优点:节省内存,只加载需要部分

#include <stdio.h&gt;

int main(int argc, char const *argv[])
{
    #ifdef  XXX
        printf("有定义宏名为XXX的宏n");
    #else
        printf("没定义宏XXXn");
    #endif

    return 0;
}

在这里插入图片描述
在这里插入图片描述

编译时定义宏:

在这里插入图片描述

例2:判断存在,和头文件配合使用,防止多次引用头文件

#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 使用含义:

1、一次引用头文件,没有定义TEST宏然后定义,再写头文件内容;

2、假如再次引用头文件时,第一次已经定义过TEST宏了,所以直接结束,啥也不干。

源码写法

在这里插入图片描述

例3:判断是否成立

#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

注意:静态库起名时候必须 lib 开头.a 结尾

步骤

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:使用静态库的文件与静态库 不在同一文件夹下

注意:

情况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进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注