C语言之宏详解(超级详细!)

目录

一、用宏前须知-#define相关知识

        大致结构:

         对预定义符号的补充:

二、用#define定义宏

        什么是宏?

        #define的替换规则:

三、常用的宏定义

1、宏定义常量

2、定义一个宏语句

3、宏定义函数

        宏与函数的对比:

4、#和## 分别字符串化和将两个符号连接成一个符号 

#字符串化

 ##将两个符号连接成一个符号

四、与宏相关的作用符号

1、换行符 '\'

2、取消宏定义#undef 

五、命名约定


一、用宏前须知-#define相关知识

        大致结构:

#define    name    stuff自定义名    内容

        栗子:

#define OP 256
#define YU "youarewelcome"
#define S(r) (r*r)
#define REG register          //为 register这个关键字,创建一个简短的名字
#define PRINT printf("file:%s line:%d\n", __FILE__, __LINE__)//__FILE__,__LINE__这是个啥?别急后面有补充!#include<stdio.h>
int main()
{printf("%d \n", OP);printf("%s \n",YU);printf("%d \n", S(6));PRINT;return 0;
}

         


         对预定义符号的补充:

__FILE__      //进行编译的源文件 
__LINE__     //文件当前的行号 
__DATE__    //文件被编译的日期 
__TIME__    //文件被编译的时间 
__STDC__    //如果编译器遵循ANSI C,其值为1,否则未定义

二、用#define定义宏

        什么是宏?

        宏可以看作为一些命令的集合。它是一种预处理器指令,在预编译阶段将宏名替换为后面的替换体。

        而#define可以用来定义宏:

        #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。

        宏的声明方式:

  #define name( parament-list ) stuff
//其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中

        栗子:

        实现一个开平方的宏        

#define SQ(x) x*xprintf("%d \n", SQ(7));

        他的实际执行结构为7*7->即为49

        还是用这个我们刚刚定义的宏

        我们执行下面这段代码:       

int a=6;printf("%d \n", SQ(6+1));

        他的实际执行结构为6+1*6+1->即为13

        这说明了什么?这印证了上面所说的宏是把参数替换到文本中,也就是宏直接吧6+1替换掉了x直接带入了后面的表达式当中了!

        对此,根据我们原来的用意。这时我们可以用括号来解决这个问题:

#define SQ(x) (x)*(x)

        这给了我们一个提醒:我们在用宏时最好多用括号,以此来避免不必要的错误!

再看个栗子:

#define DOUBLE(x) (x) + (x) 
int a = 5; 
printf("%d\n" ,10 * DOUBLE(a));

        在这个例子中我们对这个宏使用了括号,乍一看这个例子输出的值像是100

        但是实际呢?上图!

      

来看看实际它怎么执行的,它执行替换操作实际上为:

printf ("%d\n",10 * (5) + (5));

        因此我们说定义宏要多用括号!

#define DOUBLE( x)   ( ( x ) + ( x ) )

        改成这样就能实现想要的效果啦!


        #define的替换规则:

        在程序中扩展#define 定义符号和宏时,需要涉及几个步骤:
1. 在调用宏时,首先对参数进行检查,看看是否包含任何由 #define 定义的符号。如果是,它们首先被替换。
2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
3. 最后,再次对结果文件进行扫描,看看它是否包含任何由 #define 定义的符号。如果是,就重复上 述处理过程。
        注意:
1. 宏参数和 #define 定义中可以出现其他 #define 定义的符号。但是对于宏,不能出现递归。
2. 当预处理器搜索 #define 定义的符号的时候,字符串常量的内容并不被搜索。

三、常用的宏定义

1、宏定义常量

         定义诸如:字符串、整形数、浮点型数等等的常量.

        栗子:

#define AO 114514
#define NTR "我可太喜欢了"
#define KK 3.14
#include<stdio.h>
int main()
{printf("%d %s %f", AO, NTR, KK);return 0;
}

       


2、定义一个宏语句

        栗子:

#include<stdio.h>
#define PFINT printf("hello world!\n");
int main()
{PFINT///预处理时会被替换为 printf("hello world!\n");return 0;
}

3、宏定义函数

        宏可以接受参数,类似于真正的函数一样。具体的接受参数方法与函数差不多,只不过不用指定函数类型,这也是宏定义函数的一个优势!比如:当我定义了一个函数有时要传整形,有时要传浮点型,函数可能要根据类型来多定义几个,而宏只需要一个就行了!

        栗子1:

#define MAX(a, b) ((a)>(b)?(a):(b))
#include<stdio.h>int main()
{printf("%d", MAX(114, 514));return 0;
}

       

        栗子2:

#define MALLOC(num, type)\ 
(type *)malloc(num * sizeof(type)) //这和\是干啥的?详见地四大点\的作用
... 
//使用 
MALLOC(10, int);//类型作为参数 
//预处理器替换之后: 
(int *)malloc(10 * sizeof(int)); 

        这个例子中,函数是做不到跟宏相同的效果的,所以说为啥有了函数我们还要定义宏呢?这个就是一个很明显的例子。


        宏与函数的对比:


4、#和## 分别字符串化将两个符号连接成一个符号 

#字符串化

        这个很好理解看看例子就会了!

        栗子:

#define STR(exp) printf("%s\n",#exp);
#include<stdio.h>
int main()
{STR(for fun)return 0;
}

      


 ##将两个符号连接成一个符号

        ##可以把位于它两边的符号合成一个符号。 它允许宏定义从分离的文本片段创建标识符。

        栗子:

#include<stdio.h>
#define ADD_TO(num, value) num##valueint main()
{int a = ADD_TO(114, 514);printf("%d \n", a);return 0;
}

       


四、与宏相关的作用符号

1、换行符 '\'

        在每行末尾(除了最后一行)加上"\",代表换行的意思。这个目的是为了不让代码冗余,如果代码都挤在一段,代码就不美观,可读性不好。

        栗子:

#include<stdio.h>
#define PFINT printf("hello world!\n");\printf("goodbye world!\n");
#define NUM 1,\2,\3
int main()
{PFINTint x[] = { NUM };//->int x[] = { 1,2,3 };printf("%d %d %d \n", x[0], x[1], x[2]);return 0;
}

       


2、取消宏定义#undef 

        这条指令用于移除一个宏定义。        

#define SORT 1000
#undef SORT

        在#undef之后SORT就相当于没有定义,失效了。再使用则会报错!


五、命名约定

        细心的朋友可能发现了!我在定义宏时用的都是大写的字母来作为它自定义的名字!

        这是因为这有一个默认的命名约定:

        一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。

        那我们平时的一个习惯是:

        把宏名全部大写

        函数名不要全部大写                                     


       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux 驱动】IMX6ULL eLCDIF驱动

1. eLCDIF设备树 lcdif: lcdif021c8000 {compatible "fsl,imx6ul-lcdif", "fsl,imx28-lcdif"; //属性reg <0x021c8000 0x4000>; //起始地址 地址大小interrupts <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; …

[路由器]IP-MAC的绑定与取消

背景&#xff1a;当公司的网络不想与外部人员进行共享&#xff0c;可以在路由器页面配置IP-MAC的绑定&#xff0c;让公司内部人员的手机和电脑的mac&#xff0c;才能接入到公司。第一步&#xff1a;在ARP防护中&#xff0c;启动IP-MAC绑定选项&#xff0c;必须启动仅允许IP-MAC…

Modbus转BACnet/IP网关快速对接Modbus协议设备与BA系统

摘要 在智能建筑和工业自动化领域&#xff0c;Modbus和BACnet/IP协议的集成应用越来越普遍。BA&#xff08;Building Automation&#xff0c;楼宇自动化&#xff09;系统作为现代建筑的核心&#xff0c;需要高效地处理来自不同协议的设备数据&#xff0c;负责监控和管理建筑内…

双边性:构建神经网络的新方法

正如承诺的那样&#xff0c;这是最近我遇到的最有趣的想法之一的第二部分。如果你错过了&#xff0c;请务必观看本系列的第一部分 - 神经科学家对改进神经网络的看法 - 我们讨论了双边性的生物学基础以及我们大脑的不对称性质如何带来更高的性能。 在这篇文章中&#xff0c;我…

吴恩达深度学习笔记1 Neural Networks and Deep Learning

参考视频&#xff1a;(超爽中英!) 2024公认最好的【吴恩达深度学习】教程&#xff01;附课件代码 Professionalization of Deep Learning_哔哩哔哩_bilibili Neural Networks and Deep Learning 1. 深度学习引言(Introduction to Deep Learning) 2. 神 经 网 络 的 编 程 基 础…

【RT摩拳擦掌】RT600 4路音频同步输入1路TDM输出方案

【RT摩拳擦掌】RT600 4路音频同步输入1路TDM输出方案 一&#xff0c; 文章简介二&#xff0c;硬件平台构建2.1 音频源板2.2 音频收发板2.3 双板硬件连接 三&#xff0c;软件方案与软件实现3.1 方案实现3.2 软件代码实现3.2.1 4路I2S接收3.2.2 I2S DMA pingpong配置3.2.3 音频数…

【BUG】已解决:AttributeError: ‘str‘ object has no attribute ‘read‘

AttributeError: ‘str‘ object has no attribute ‘read‘ 目录 AttributeError: ‘str‘ object has no attribute ‘read‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998https://bbs.csdn.net/topics/617804998 欢迎来到我的主…

【CSS】容器查询:@container

目录 什么是容器查询如何使用container实际应用场景浏览器支持 什么是容器查询 容器查询是一种CSS特性&#xff0c;允许开发者根据组件所在的容器的大小来应用样式&#xff0c;而不是整个视口的大小。这使得组件能够更加灵活地适应不同的布局环境&#xff0c;而不仅仅是依赖于…

IDEA缓存和索引

IDEA缓存和索引 —2020年06月10日 IntelliJ IDEA首次加载项目的时候。都会创建索引&#xff0c;而创建索引的时间根项目的文件多少成正比。 IntelliJ IDEA的缓存和索引主要是用来加快文件查询&#xff0c;从而加快各种查找、代码提示等操作的速度。 某些特殊情况下&#xf…

2024“钉耙编程”中国大学生算法设计超级联赛(2)

Rank Search Result (hdu.edu.cn) URL划分 - HDU 7451 - Virtual Judge (vjudge.net)​​​​​​​ 这题唯一要注意的就是后面只输出有等号的部分&#xff0c;然后模拟即可。 #include<bits/stdc.h> using lllong long; using ullunsigned long long; using PIIstd::…

《梦醒蝶飞:释放Excel函数与公式的力量》18.1 图表类型与设计

第18章&#xff1a;创建图表和数据可视化 18.1 图表类型与设计 Excel提供了多种图表类型&#xff0c;帮助用户以直观的方式展示数据。选择合适的图表类型和设计可以显著提高数据的可读性和理解度。以下将介绍常见的图表类型及其应用&#xff0c;并通过具体案例进行说明。 18.…

ML.Net 学习之使用经过训练的模型进行预测

什么是ML.Net&#xff1a;&#xff08;学习文档上摘的一段&#xff1a;ML.NET 文档 - 教程和 API 参考 | Microsoft Learn 【学习入口】&#xff09; 它使你能够在联机或脱机场景中将机器学习添加到 .NET 应用程序中。 借助此功能&#xff0c;可以使用应用程序的可用数据进行自…

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.5技术架构

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

【人工智能】使用Python的dlib库实现人脸识别技术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、传统人脸识别技术1. 基于几何特征的方法2. 基于模板匹配的方法3. 基于统计学习的方法 三、深度学习在脸识别中的应用1. 卷积神经网络&#xff08;CNN&#xff09;2. FaceNet和ArcFace 四、使用Python和dlib库实…

微服务:网关

网关 网关,即网络的关口,当一个网络传输到另一个网络时就需要经过网关来实现 数据的路由和转发 以及 数据安全的校验 网关技术实现 SpringCloudGateWay: 基于Spring的WebFlux技术,完全支持响应式编程,吞吐能力更强 SpringCloudGateWay 依赖 <!--网关--><depe…

Linux中的时间函数

参考&#xff1a; 几种取时间的方法&#xff08;附代码&#xff09; Linux中gmtime和localtime的区别(time_t格式转换为tm格式) C 库函数 - time() mktime和localtime_r能在多线程环境下使用么&#xff1f; Linux_C环境编程&#xff1a;时间日期函数总结 细说时间测量RDT…

乐鑫AWS IoT ExpressLink方案,简化物联网设备连接AWS IoT服务

在现代科技迅速发展的今天&#xff0c;物联网&#xff08;IoT&#xff09;已经成为连接物理世界与数字世界的重要桥梁&#xff0c;越来越多的设备开始接入网络&#xff0c;实现智能化控制。 在这个大背景下&#xff0c;乐鑫携手亚马逊&#xff0c;推出了AWS IoT ExpressLink方…

免费视频批量横转竖工具

简介 视频处理器 v1.3 是一款由是貔貅呀开发的视频编辑和处理工具&#xff0c;提供高效便捷的视频批量横转竖&#xff0c;主要功能&#xff1a; 导入与删除文件&#xff1a;轻松导入多个视频文件&#xff0c;删除不必要的文件。暂停与继续处理&#xff1a;随时暂停和继续处理。…

开源AI智能名片S2B2C商城小程序在社群团购模式中的应用与探索

摘要 本文深入探讨了开源AI智能名片S2B2C商城小程序在社群团购模式中的创新应用与未来发展。通过详细分析社群团购模式的特征、发展趋势及其面临的挑战&#xff0c;结合开源AI智能名片S2B2C商城小程序的技术优势与实际应用案例&#xff0c;本文提出了一系列旨在提升社群团购效…

centos中zabbix安装、卸载及遇到的问题

目录 Zabbix简介Zabbix5.0和Zabbix7.0的区别监控能力方面模板和 API 方面性能、速度方面 centos7安装Zabbix(5.0)安装zabbix遇到的问题卸载Zabbix Zabbix简介 Zabbix 是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix 能监视各种网络参…