当前位置: 首页 > news >正文

C语言 DAY07:预编译,宏,选择性编译,库(静态库,动态库)

声明与定义分离

声明:将声明单独封装成一个以.h为后缀名的头文件

定义:将定义的变量,函数,数组所在的源文件单独封装成一个.c文件。其实就是在源文件基础上将定义过的所有东西的声明分离出去就是了。

注意:1.声明的.h文件名和.c结尾的源文件名要相同、

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

1.预编译

1.程序编译

1.预编译

        展开头文件

        定义宏

        选择性编译

        注意:

                展开头文件必须以#开头 

2.编译

3.汇编

4.链接      

2.include

作用:展开头文件

语法:

        #include<> 尖括号代表的头文件是在系统指定文件中找该库,具体在lib/或者在usr/lib文件中找

        #include""  "" 代表的是自己定义的库,会先在当前目录文件夹下找,如果找不到再在系统指定文件夹中找

注意:
1,include 经常用来包含头文件,可以包含 .c 文件,但是大家不要包含.c ,因为 include 包含的文
件会在预编译被展开,如果一个.c 被包含多次,展开多次,会导致函数重复定义。所以不要包含.c 文件
2,预处理只是对 include 等预处理操作进行处理并不会进行语法检查
这个阶段有语法错误也不会报错,第二个阶段即编译阶段才进行语法检查

3.宏(define)

1.定义不带参的宏

        define pi(宏名)  值

       注意:1.定义不带参的宏,值可以不写

                  2.不带参的宏定义不要后面加分号

                  3.只能在当前文件中使用

                  4.在宏定义后,取消定义前使用

例子:      

        #include <stdio.h>
        #define PI 3.14
        #define X
        int main(int argc, char const *argv[])
        {
        printf("PI=%f\n",PI);
        #undef PI //取消宏定义
        //printf("PI=%f\n",PI);
        return 0;
        }

2.定义带参的宏

        define 宏名(形参) a + b(体) ;

3.注意:

        1.结尾要加分号

        2.括号中可以加形参,后面运算表达式不能省

        3.形参没有数据类型

        4.不止在当前文件中使用,可以在别的文件中使用

4.带参和不带参的宏的区别:

        宏:在预编译时对其进行替换,如果一个文件中多次使用宏,那意味着要替换多次,此时就需占用内存,所以占据的内存多

                产生的预编译时期

                占内存多

                速度快
        
        函数:在程序运行时在代码区存储一份,每次调用该函数都需在代码区寻找,将其放入栈内存中(压栈),当函数执行完毕后,从栈中移除(弹栈)
                产生在运行时
                
                占内存少
5.#undef   宏名          //取消宏定义

6.总结

        宏就是在预编译时期对其进行替换

        不带参宏替换的是一个值

        带参宏替换的是一段代码   

4.选择性编译

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

语法:

2.库

作用:

        也叫代码库,可以将一些目标文件放在一起合并方便使用

分类:

1.静态库

2.动态库

动态库与静态库的区别:

注意:

程序中引入的文件在动态库与静态库同时存在两份

静态编译程序引入静态库中的该文件

动态编译程序引入动态库中的该文件

编辑命令:

静态库:

        gcc  -static  源文件名  - o   生成的可执行文件名

动态库:
        gcc  源文件名  - o   生成的可执行文件名

静态库:

制作:

        gcc -c 源文件名.c -o 生成的二进制文件名.o

        ar rc lib静态库名称.a 生成的二进制文件名.o

        注意:静态库起名的时候必须以 lib 开头以 .a 结尾
使用:
        情况1: 使用静态库的文件与静态库在同一文件夹下
                命令:
                gcc 源文件名 静态库名称 -o 生成的可执行文件名
                
情况 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 生成的可执行文件名

动态库

制作:

        命令:

                gcc -shared 源文件名 -o 生成的动态库文件名.so

使用:

        情况1:使用动态库的文件与动态库在同一文件夹下

                命令:

                        gcc 源文件名 动态库名称 -o 生成的可执行文件名

        情况2:使用静态库的文件与静态库不在同一文件夹下

                命令:

                        gcc 源文件名 -L 动态库所在路径 -l 动态库名称 -I 头文件所在路径
                注意:
                        动态库名需要去掉前面的lib与后面.so

        情况3:静态库文件与对应的头文件在系统文件夹下

                命令:

                        gcc 源文件名 -l 静态库名 -o 生成的可执行文件名

注意:

        运行中出现动态库找不到问题,需要将动态库所在目录导入用户环境变量

        export LD_LIBRARY_PATH=库文件所在路径:$LD_LIBRARY_PATH

        export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

        

http://www.lryc.cn/news/213497.html

相关文章:

  • [EFI]asus strix b760-i 13900F电脑 Hackintosh 黑苹果efi引导文件
  • 力扣383.赎金信
  • CORS的原理以及在Node.js中的使用
  • kotlin实现单例模式
  • 【Java】LinkedList 集合
  • MySQL-Galera-Cluster集群详细介绍
  • JavaScript从入门到精通系列第二十六篇:详解JavaScript中的Math对象
  • u盘直接拔出文件丢失怎么找回?u盘文件恢复办法分享!
  • rust学习-LinkedList
  • 搭上直播快车,文旅迎来了更大爆发期?
  • 【智能座舱系列】- 深度解密小米Hyper OS,华为HarmonyOS区别
  • kafka-consumer-groups.sh
  • 数据仓库-拉链表
  • 【Docker】一些可以直接用的Docker环境
  • Unity2D中瓦片地图的创建与绘制教程
  • 现代的简洁,诠释轻奢的精致!福州中宅装饰,福州装修
  • 运用ChatGPT辅助新手学习躺赢者PRO飞控二次开发示例(2023年10月28日)
  • 【Java】HashCode方法重写注意事项
  • 039-第三代软件开发-PDF阅读器
  • 计算机毕业设计选题推荐-跑腿平台微信小程序/安卓APP-项目实战
  • RocketMQ生产者消息发送出去了,消费者一直接收不到怎么办?(Rocket MQ订阅关系一致性)
  • 使用Golang开发硬件驱动
  • 设计模式(19)命令模式
  • QModelIndex 与QStandardItem相互转换
  • Linux - 进程地址空间
  • 系统架构设计师-第16章-嵌入式系统架构设计理论与实践-软考学习笔记
  • pod进阶
  • 系列四十七、Spring的事务传播行为案例演示(七)#NOT_SUPPORTED
  • 54.RabbitMQ快速实战以及核心概念详解
  • Qt TreeView 设置节点不可编辑