编译预处理

news/2024/3/29 19:22:45/文章来源:https://blog.csdn.net/cai88453626/article/details/130353241

编译预处理

  • 1、宏定义
    • 1.1、 无参宏定义
    • 1.2、使用宏定义的优点
    • 1.3、宏定义注意点
    • 1.4、带参数的宏(重点)
    • 1.5、条件编译
    • 1.6、宏定义的一些巧妙用法(有用)
    • 1.7、结构体占用字节数的计算原则(考题经常考,要会画图)
    • 1.8、#在宏定义中的作用(不常用)
    • 1.9、##在宏定义中的作用(常用)
    • 起到连接前后字符串的作用
    • 1.10、__VA_ARGS__可变参数在宏中的运用
  • 2、 整理内存管理和编译预处理中的编码规范和面试题。

1、宏定义

1.1、 无参宏定义

1.2、使用宏定义的优点

1、提高程序的可维护性
2、提高程序的可移植性 typedef 自定义类型
3、减少源程序中重复书写字符串的工作量

1.3、宏定义注意点

1、宏名一般用大写字母表示,以示与变量区别。但这并非是规定;
2、宏定义不是C语句,所以不能在行尾加分号。否则,宏展开时,会将分号作为字符串的1个字符,用于替换宏名;
3、在宏展开时,预处理程序仅以按宏定义简单替换宏名,而不作任何检查。如果有错误,只能由编译程序在编译宏展开后的源程序时发现;
4、宏定义命令#define出现在函数的外部,宏名的有效范围时:从宏定义之后,到本文件结束。通常,宏定义命令放在文件开头处;
5、在进行宏定义时,可以引用已定义的宏名;
6、对双引号括起来的字符串内的字符,即使与宏名同名,也不进行宏展开。

1.4、带参数的宏(重点)

#define MUTI(a,b) ((a)(b))
#define MUTI(a,b) a
b 为什么需要对宏表达式里的参数加上括号?
MUTI(10+20,10+20) 10+20*10+20 和本意不符

编码规范:
宏定义需要将参数使用括号括起来。即使定义一个数据,也需要括起来

#define STUNUM (10)
#define ADD(a,b) ((a) + (b))

把每个参数括起来,最外层在括一层。

1.5、条件编译

#ifndef
#define#endif

即使加上了防止头文件重复包含的条件编译判断,也会发生变量重定义的错误!!!
编码规范:
因此:禁止在头文件中定义任何的变量!!!

头文件中可以声明外部使用的全局变量 extern int a;
在源文件中定义变量int a;

1.6、宏定义的一些巧妙用法(有用)

1、防止一个头文件被重复包含

#ifndef
#define#endif

2、重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
typedef unsigned long int UINT32; //Unsigned 32 bit value

3、用下面的宏定义可以直接从指定地址上的取得1个字节2个字节的数值(了解)

#define MEM B(x) (*((INT8*)(x)))
#define MEM W(x) (*((INT16*)(x)))

4、求最大值和最小值

#define MAX(x,y) (((x) > (y)) ? (x):(y))
#define MIN(x,y) (((x) < (y)) ? (x):(y))

5、得到一个field在结构体(struct)中的偏移量(了解)

#define FPOS(type,field) ((INT32)&((type *)0)->field)

注:在计算机中,要访问一个地址空间,必先知道他的地址,然后才能访问他对应的空间;编译器在会将&((type *)0)->field 优化为直接取地址,因为这种表达是:先访问空间,再取空间的地址,从地址0开始取field的地址,就相当于取结构体对应成员的偏移了!

6、使用一些宏跟踪调试
ANSI标准说明了五个预定义的宏名。它们是:
_LINE 哪一个行
_FILE 哪一个文件
_DATE 时间
_TIME
_STDC

printf ("%s : %d : %s",__FILE_,__LINE_,DATE_);

1.7、结构体占用字节数的计算原则(考题经常考,要会画图)

typedef struct Student{INT8 name[32];	//32INT32 score;		//4INT8 c;				//1INT8 d;				//1INT8 e;				//1INT16 f;				//2INT64 g;				//8
}Student_type

在这里插入图片描述占用字节数8*7=56个字节。

编码规范:
定义结构体类型的时候,一定按照从小到大,或者从大到小的顺序定义结构体成员!(能够节省内存空间)

1.8、#在宏定义中的作用(不常用)

#把宏的参数当字符串来输出。(了解)

1.9、##在宏定义中的作用(常用)

起到连接前后字符串的作用

#define CREAT_ADDFUNC(tname)    tname add_##tname(tname a,tname b) \
{ \return a + b; \
} \

CREAT_ADDFUNC(int)   
/* 
int add_int(int a, int b)
{return a + b;
}
*/
CREAT_ADDFUNC(float)
CREAT_ADDFUNC(double)INT32 main(INT32 argc,INT8 *argv[])
{printf("add int %d\n",add_int(10,20));printf("add float %f\n",add_float(10.5,20.6));printf("add float %f\n",add_double(10.5,20.6));return 0;
}

1.10、__VA_ARGS__可变参数在宏中的运用

整体调试屏蔽和打开,看懂即可。

//#define DEBUG
#ifdef DEBUG
#define LOG(format,...)do{  \printf(format,__VA_ARGS__);	\
}while(0)
#else
#define LOG(format,...)
#endifINT32 main(INT32 argc,INT8 *argv[])
{printf("add int %d\n",add_int(10,20));printf("add float %f\n",add_float(10.5,20.6));printf("add float %f\n",add_double(10.5,20.6));return 0;
}

在这里插入图片描述如果调试完成了,发布给客户的时候,不需要调试信息了
,只需要屏蔽一行代码,就可以屏蔽掉所有的信息输出(只要是用OUTPUT_xxx宏的地方)。
//#define USE_LOG

2、 整理内存管理和编译预处理中的编码规范和面试题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_103578.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32设备驱动-BMM150数字地磁传感器驱动

BMM150数字地磁传感器驱动 文章目录 BMM150数字地磁传感器驱动1、BMM150介绍2、硬件准备3、软件准备4、驱动实现1、BMM150介绍 BMM150 是一款低功耗、低噪声的 3 轴数字地磁传感器,用于罗盘应用。 具有 1.56 x 1.56 mm 和 0.60 mm 高度的 12 引脚晶圆级芯片级封装 (WLCSP) 为…

直升机空气动力学基础--004翼型的阻力

来源 1. 空气的粘性 2.阻力的产生 3.形成因素 4.阻力系数曲线

转换json格式的日期为Javascript对象的函数

项目中碰到了用jQuery从后台获取的json格式的日期的字符串&#xff0c;需要将此字符串转换成JavaScript的日期对象。 代码如下: //转换json格式的日期&#xff08;如&#xff1a;{ServerDatetime:"\/Date(1278930470649)\/"}&#xff09;为Javascript的日期对象 fu…

Linux tail 命令

前言 Linux 实时查看日志文件&#xff0c;最主要使用的就是tail命令。 linux tail命令用于显示文件尾部的内容&#xff0c;默认在屏幕上显示指定文件的末尾10行。如果给定的文件不止一个&#xff0c;则在显示的每个文件前面加一个文件名标题。如果没有指定文件或者文件名为“-”…

湿法冶金以及铼提取工艺,湿法冶金工艺特点及工艺流程

湿法冶金是利用浸出剂在一定温度压力下与矿石接触&#xff0c;把矿石中有用的金属溶解后再从溶液中回收有价金属的一种工艺&#xff0c;因为其过程大都是在水溶液中进行&#xff0c;所以又被称为“水法冶金”。 01 湿法冶金工艺特点及工艺流程 湿法冶金作为解决我国金属矿产资…

深度赋能产业数字化转型,蚂蚁集团数字化三件套亮相中国国际金融展

“十四五”规划纲要指出&#xff1a;加快推动数字产业化&#xff0c;推进产业数字化转型&#xff0c;实施“上云用数赋智”行动&#xff0c;推动数据赋能全产业链协同转型。明确提出了通过科技创新&#xff0c;加快产业数字化转型的要求。 4月25日&#xff0c;以“荟萃金融科技…

mybatisPlus·入门·贰

文章目录 1 简单CRUD接口1.1 根据id查询&#xff08;{id传参&#xff09;1.1.1 接口类直接继承IService1.1.2 controller直接调用方法 1.2 根据ids查询1.3 新增1.3.1 接口类直接继承IService1.3.2 controller直接调用方法 1.4 修改状态&#xff08;Query传参&#xff09;1.4.1 …

新版Fluent默认保存的h5文件无法用Tecplot打开的解决办法(亲试有效,评论区是重点)

文章目录 Ansys Fluent简介Fluent 输入/出 文件格式新版Fluent的输出压缩文件&#xff08;.cas.h5文件&#xff09;解决办法 Ansys Fluent简介 Ansys Fluent &#xff0c;是国际上比较流行的商用CFD软件包&#xff0c;在美国的市场占有率为60%&#xff0c;凡是和流体、热传递和…

NetXpert XG2帮您解决“布线安装与维护”难题

在传输大量数据时&#xff0c;光纤变得越来越重要&#xff0c;而铜缆在未来也将继续发挥重要作用&#xff0c;因此我们不仅要比较两种类型布线的优缺点&#xff0c;还要探究光纤传输中的错误来源。 测试光缆传输损耗的准确性对于故障排除至关重要&#xff0c;特别是在光纤情况下…

后台-husky提交代码规范使用

husky是一个git hook工具&#xff0c;可以帮助我们触发git提交的各个阶段&#xff1a;pre-commit、commit-msg、pre-push 1.如何使用husky呢&#xff1f; npx husky-init && npm installWindows安装不成功试试npx husky-init && npm install 2.git commit规范…

Java学习笔记-01

目录 jdk安装及环境配置 java前置知识 编写一个HelloWorld 常量 数据类型 变量 类型转换 算数运算符 一元运算符( --) 关系运算符 逻辑运算符(与或非&#xff0c;逻辑异或) 三元(三目)运算符 Scanner类的简单使用 jdk安装及环境配置 看到的一篇文章&#xff0c;…

【C++STL】set

前言 前面的CSTL的博客&#xff0c;我们介绍了string&#xff0c;vector&#xff0c;list&#xff0c;deque&#xff0c;priority_queue还有stack和queue。 这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。 而从本节开…

(二)ElasticSearch 辅助工具 Kibana 介绍与安装

1、什么是 kibana &#xff1f; Kibana 是一个针对Elasticsearch的开源分析及可视化平台&#xff0c;用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana&#xff0c;可以通过各种图表进行高级数据分析及展示。 Kibana让海量数据更容易理解。它操作简单&#xff…

0401概述-最短路径-加权有向图-数据结构和算法(Java)

文章目录 1 最短路径2 最短路径的性质3 加权有向图的数据结构3.1 加权有向边3.2 加权有向图 4 最短路径4.1 最短路径API4.2 最短路径的数据结构4.3 边的松弛4.4 顶点的松弛 结语 1 最短路径 如图1-1所示&#xff0c;一幅加权有向图和其中的一条最短路径&#xff1a; 定义&…

加强人工智能共性技术研发与产业化协同发展

央视网消息&#xff1a;“以5G为代表的新一代信息技术与制造业、交通、旅游等实体经济重要领域深度融合。”4月20日下午&#xff0c;国新办举行一季度工业和信息化发展情况新闻发布会&#xff0c;相关部门负责人在答问时表示&#xff0c;将用好融合应用这把金钥匙&#xff0c;开…

基于matlab仿真相控天线阵列在波束成形MIMO-OFDM系统中的使用

一、前言 本例显示了相控阵在采用波束成形的MIMO-OFDM通信系统中的使用。它使用通信工具箱和相控阵系统工具箱中的组件&#xff0c;对组成发射器和前端接收器组件的辐射元件进行建模&#xff0c;用于MIMO-OFDM通信系统。使用用户指定的参数&#xff0c;您可以根据不同空间位置和…

JAVA Future类详解及Thread线程是如何运行Future类的

一、Future基本介绍 Future(java.util.concurrent Interface Future<V>)表示异步计算的结果。Future接口提供了检查计算是否完成、检查计算是否被取消、等待计算完成并获取计算结果等方法。 在并发编程中&#xff0c;我们经常用到非阻塞的模型&#xff0c;但继承thread类…

202303-1 田地丈量

代码 #include<iostream> #include<vector> #include<string> #include<cmath> #include<algorithm> #include<stack> using namespace std; int n, a, b;int main() {cin >> n >> a >> b;int x1, y1, x2, y2;int x, y;…

网络基础之网络传输基本流程

网络基础 此小节介绍网络基础概念 首先要明确的是 网络是层状结构&#xff01;分层->OP->解耦 网络发展&#xff1a;最早的时候&#xff0c;每台计算机之间是相互独立的。后续发展到网络互联&#xff0c;就是将多台计算机连接在一起&#xff0c;完成数据共享。 协议&…

19.Java文件操作---I/O流

Java文件操作—I/O流 流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中&#xff0c;管道是一条不间断的字节流&#xff0c;用来实现程序或进程间的通信&#xff0c;或读写外围设备、外部文件等。一个流&#xff0c;必有源端和目的端&#xff0c;它们可以是计算机内存的某…