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

【C语言】宏定义

  • 🚩 WRITE IN FRONT🚩   

  • 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四"🔎
  • 🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大博主、华为云享专家、阿里云专家博主、掘金优秀创作者、全网粉丝量6w+、全网访问量100w+🏅
  • 🆔 本文章内容由 謓泽 原创 如需相关转载请提前告知博主 ⚠
  • 📝 个人主页:謓泽的博客📃
  • 📣 专栏系列:【C】系列 📃
  • 🧑‍💻 Gitee:謓泽 (wsxsx) - Gitee.com⭐️
  • 🎁 点赞👍+ 收藏⭐️+ 留言📝​

目录

🍑宏定义不带参数

🍈优点

🍑定义宏 

🍈说明

🍈命名事项

🍻字符串宏常量

🍈practice[练习]

🍻#undef


🍑宏定义不带参数

        说明:宏定义指令的 #define 用来定义一个标识符和一个字符串,我们可以以这个标识符来表示这个字符串,在程序当中每次遇到该标识符的时候就用来所定义的字符串来进行替换它。宏定义的作用相当于给指定的字符串起了一个别名。

不带参数的宏的定义方式如下(这也是我们经常用到的宏定义)

#define 宏名 字符串 //没有分号,说没有分号倒不如说最好不要加分号

        这里说下原因吧:因为宏定义它并不是C语言的语句,所以不用加分号。 

  • 表示这是一条预处理命令。
  • 宏名实际上就是一个标识符,必须要符合C语言当中标识符的语法规定的。

        标识符的规则:字母、数字、下划线,不以数字开头,注意:关键字不能作为标识符!预定义标识符有define、printf、scanf 它们是可以作为标识符的。

  • 字符可以是常数、表达式 以及 格式字符串符等。
#define Num 1000

        说明:上述代码的作用就是该程序中用Mum来替代1000,在编译预处理的时候,每当代码在源程序中遇到Mum就自动的用1000来进行代替。

        注意:宏名要简单且定义的明确,一般习惯会用大写字母来去表示,来区分和变量的区别。

🍈优点

  1. 方便程序的修改,不用对整个程序进行修改,只需对宏定义上进行修改。
  2. 提高程序的运行效率,更加方便模块化。

🍑定义宏 

        #define 机制包括了一个规则,允许把参数替换到文本当中去,这种实现操作通常被称之为是宏(macro) 或者是 定义宏(define macro)

        带参数的宏定义方式如下格式↓

#define 宏名(参数表)字符串

        那么光说是不行的,我们就用宏定义来实现两个数字的相加。代码示例如下👇

#define _CRT_SECURE_NO_WARNINGS 1
#define ADD(x,y) x+y
#include<stdio.h>
int main(void)
{printf("相加的值:%d\n",ADD(5, 5));return 0;
}

运行结果🖊 

        相加的值:10

        上述代码的意思是我们先调用宏也就是宏调用,把宏里面的值传递给宏名当中的参数表,然后再传过去的参数表替换到字符串的文本当中去。

注意:宏的参数是先完成替换的,不是先计算然后再进行传参的。如下代码所示↓

#define _CRT_SECURE_NO_WARNINGS 1
#define S(x) x*x
#include<stdio.h>
int main(void)
{printf("相加的值:%d\n",S(3+1));return 0;
}

        我一开始的时候看到这个代码以为是16,4*4不就是16吗。实际上我想错了。

        它的工作原理是这个样子的,这里3+1就是宏的参数,那么就会把3+1传递到宏的参数当中去。那么这个时候替换完成之后就是:3+1 * 3+1,这不就是7吗。没错(@^0^)

        一句话总结:参数会经过任何的计算直接传入进去。 

        实际上我们想要得到4*4的一个结果实际上这也很容易,把字符串文本修改下即可。

#define S(x) (x)*(x)

        当然这还是不够严谨,完美再加一个小括号再外面。

#define S(x) ((x)*(x))

        ()YYDS!那么这个概念性的东西就说到这里,具体还是要多上手打下代码去进行实践。 

        那么接下来我们再举出一个例子,看大家能不能做对。(╹ڡ╹ )

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define M(x) (x)+(x)
int main(void)
{printf("%d ", 10 * M(2));return 0;
}

        🍎注意⇢上述这两个代码是不一样的仔细看看哟😛

​#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define M(x) (x)+(x)
int main(void)
{int a = 2;printf("%d ", 10 * M(a));return 0;
}

        注意⇢上述这两个代码是等价的,变量也是可以传入到参数表当中去的。

选出上述代码正确的值不能 一共四个选项如下↓

A:40

B:22

C:88

D:10

        可能有些人会选择A这个选项,因为 10 * 2 = 20 然后,20+20 = 40,但实际上这是错误的和上面所犯的错误都是一模一样的。

printf("%d",10 * (2) + (2));

        原型如上代码所示↑

        那我们想要得到 40 的值就必须要加小括号。如下形式↓

#define M(x) ((x)+(x))

        其实这也无非就是操作符的优先级大小,切记(✿◕‿◕✿) 

🍈说明

        宏参数和#define的定义中可以出现其他的#define定义的变量。但是对于宏,是不能出现递归的。

        当预处理搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

在使用函数的时候我们需要注意它的数据类型,但是在宏当中我们是不需要注意的,想是整形就是整形想是浮点型就是浮点型。说明用宏在这里是更加灵活的只是处理简单问题上切记。

🍈命名事项

        相信有些小伙伴已经发现了这个函数的宏的使用语法和函数是非常类似滴。所以语言本身就会没办法帮我们区分二者的一些使用。那么我们平时写宏或者函数的时候的习惯是↓

  • 宏明全部大写形式。
  • 函数明不要全部大写,建议第一个字母大写。

🍻字符串宏常量

#include<stdio.h>
#define Name chenze
int main(void)
{printf("%s",Name);return 0;
}

(error)字符串没有带双引号编译器会直接报错✘

(correvt)正确写法是要在宏字符串带上双引号

#define Name "chenze"

        小知识点⇢宏是可以用来充当注释的效果的这个我在接触宏的时候我都没有想到这个问题,那么现在我们用BSC充当C++的风格注释。大家可以尝试去试一下这里我就不再演示了(@^0^)

🍈practice[练习]

        那么经过上述的知识点相信各位已经熟悉的差不多了接下来我们来做一道题目来练习practice以下吧。

        题目内容⇢用宏实现整形变量(a)和整形变量(b)把原来的值用宏实现清0并且打印原来(a,b)没有被宏清0之前的值。示例代码如下👇

#include<stdio.h>
#define empty0(a,b) a = 0;b = 0;
int main(void)
{int a = 20;int b = 10;printf("before:%d  %d\n", a, b);empty0(a, b);printf("after :%d  %d\n", a, b);return 0;
}

运行结果🖊

before:20  10

after   :0    0

✔说明⇢上述结果当中我们可以知道变量(a)和变量(b)通过宏被修改成为了0的值。

✔拓展⇢用do...while(0)语句结构可以在宏插入多条语句的结构因为有花括号{}在。

🍻#undef

#undef 是为取消定义,用于移除一个宏的定义。

格式形式如下

#undef NAME

如果现在的一共名字需要被重新定义的话,那么旧名字就会被移除。

🍏如下代码所示

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define NUM 10
int main(void)
{
#undef NUMprintf("num of:%d\n",NUM);
}

运行结果⇥error(错误)

        说明⇢上述代码原本是要打印NUM宏定义的值的,但是由于我们使用了#undef取消宏定义了。此时编译器就相当于未定义标识符NUM了说的简单点相当于不存在了,注:是在取消宏定义之后的语句当中的。

🍎拓展知识点⇥宏可以在任意地方使用。

#include<stdio.h>
int main(void)
{printf("num of 1:%d\n", 10);
#define M 20printf("num of 2:%d\n", M);return 0;
}

运行结果🖊

num of 1:10
num of 2:20

        🍏说明⇢在上述代码当中可以证明宏在源文件的任何地方宏都可以定义。宏的作用范围:从定义出开始往后它都是有效的。

相关文章:

【C语言】宏定义

&#x1f6a9; WRITE IN FRONT&#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四"&#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大博…...

库存三层模型概述

库存分层 &#xff08;1&#xff09;电商库存体系分为三层&#xff1a;销售层、调度层、仓库层。 库存三层模型&#xff1a;销售库存&#xff0c;调度层属于订单领域-履约。实物库存属于库存领域 WMS的库存跟调度层是一致的。 但是销售库存跟调度层可能不一致&#xff0c;因为…...

SNERT预备队招新CTF体验赛-Web(SWCTF)

目录 1、F12 2、robots 3、game1-喂青蛙 4、game 2 - flap bird 5、game 3 - Clash 6、Get&Post 7、sql &#xff08;1&#xff09;手工注入 &#xff08;2&#xff09;工具注入 8、命令执行漏洞 9、文件上传漏洞 10、文件泄露 11、php反序列化漏洞 12、PHP绕…...

OpenGLES:绘制一个彩色、旋转的3D圆柱

一.概述 上一篇博文讲解了怎么绘制一个彩色旋转的立方体 这一篇讲解怎么绘制一个彩色旋转的圆柱 圆柱的顶点创建主要基于2D圆进行扩展&#xff0c;与立方体没有相似之处 圆柱绘制的关键点就是将圆柱拆解成&#xff1a;两个Z坐标不为0的圆 一个长方形的圆柱面 绘制2D圆的…...

【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明

在智能驾驶中&#xff0c;DDS有可能被广泛使用&#xff0c;因此推出这篇说明教程。 1、基于【QT开发&#xff08;5&#xff09;】教程的项目文档进行开发 2、安装DDS 查看《【eProsima Fast DDS&#xff08;1&#xff09;】安装eProsima Fast DDS》 至少安装: foonathan_m…...

js 判断字符串中是否包含某个字符串

方法一(推荐使用): indexOf() indexOf() 方法&#xff1a;返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现&#xff0c;则该方法返回 -1。 var str "LiHeErNAN"; console.log(str.indexOf("A") ! -1 ); // true方法二:m…...

部署在阿里云ECS服务器上的微服务项目中获取到的时间和windows的时间不一样的问题

继上一篇文章《阿里云ECS服务器无法发送邮件问题解决方案》之后&#xff0c;又发现登录的时候发送邮件中的时间和自己windows上的时间不一样&#xff0c;大概找了一下原因&#xff0c;是LocaDateTime使用的时区不一样导致的远程服务器和本机时间不一致。 只需要在LocaDateTime…...

怎么通过portainer部署一个vue项目

这篇文章分享一下今天通过docker打包vue项目&#xff0c;并使用打包的镜像在portainer上部署运行&#xff0c;参考了vue-cli和docker的官方文档。 首先&#xff0c;阅读vue-cli关于docker部署的说明 vue-cli关于docker部署的说明https://cli.vuejs.org/guide/deployment.html#…...

Springboot实现websocket(连接前jwt验证token)

背景 用户连接服务器weksocket前&#xff0c;需经过jwt的token验证&#xff08;token中包含账号信息&#xff09;&#xff0c;验证合法后&#xff0c;才可以于服务器正常交互。 实现 一、配置依赖&#xff08;pom.xml&#xff09; <!-- websocket --><dependency&g…...

2023/10/3

平荒尽处是春山 二零二三年的十月 似乎已经过去了很久很久 没有了曾经的意气风发 也没有了歌伴夜声 之前一直不知道自己为什么喜欢打篮球 虽然打得不好 但是今天突然明白了 我喜欢的不是过人后的喜悦 而是篮球应声入网的清脆的声音 当然 出来进球 还有的是擦筐而出和三不沾 但是…...

zemax场曲/畸变图与网格畸变图

网格畸变是XY两个方向上的几何畸变&#xff0c;是不同视场实际像高与近轴像高的偏差。 垂轴放大率在整个视场范围内不能保持常数 当一个有畸变的光学系统对一个方形的网状物体成像时,若δy>0&#xff0c;则主光线的交点高度y比理想像高y低,视场越大&#xff0c;低得越多&a…...

【小尘送书-第六期】《巧用ChatGPT轻松玩转新媒体运营》AI赋能运营全流程,帮你弯道超车、轻松攀登运营之巅

大家好&#xff0c;我是小尘&#xff0c;欢迎你的关注&#xff01;大家可以一起交流学习&#xff01;欢迎大家在CSDN后台私信我&#xff01;一起讨论学习&#xff0c;讨论如何找到满意的工作&#xff01; &#x1f468;‍&#x1f4bb;博主主页&#xff1a;小尘要自信 &#x1…...

GD32F10 串口通信

1. 什么是通信 通信&#xff0c;指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递&#xff0c;从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法&#xff0c;任意媒质&#xff0c;将信息从某方准确安全地传送到另方。通信双方如果想正确传输…...

QT常用控件介绍

QT信号与槽机制 connect (A,SIGNLA(aaa())&#xff0c;B, SLOT(bbb()))&#xff1b; GUI继承简介 布局管理器 垂直布局水平布局网格布局表单布局 输出控件 Label: 标签Text Browser: 文本浏览器Graphics View : 图形视图框架Calendar Widget: 日历控件LCD Number: 液晶字体数…...

[FineReport]安装与使用(连接Hive3.1.2)

一、安装(对应hive3.1.2) 注&#xff1a;服务器的和本地的要同时安装。本地是测试环境&#xff0c;服务器的是生产环境 1、服务器安装 1、下载 免费下载FineReport - FineReport报表官网 向下滑找到 2、解压 [rootck1 /home/data_warehouse/software]# tar -zxvf tomcat…...

黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)

参考文章1&#xff1a;https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2&#xff1a;https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇数据库相关概念&#xff08;数据库DataBase&#xff08;DB&#xff09;、数据库管理系统DataBase Management Sy…...

最新AI智能创作系统源码V2.6.2/AI绘画系统/支持GPT联网提问/支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…...

神器 CodeWhisperer

这两天看到了好多关于 Amazon CodeWhisperer 针对个人用户终身免费使用的消息&#xff0c;便抽空简单来重点介绍下如何在 VS Code 这款 IDE 上安装和使用 CodeWhisperer。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视…...

GraphQL全面深度讲解

目录 一、GraphQL 是什么 二、GraphQL 规范 数据模型 字段 参数 三、运行示例 四、优势和劣势 优势 劣势 一、GraphQL 是什么 GraphQL 是一种用于 API 的查询语言&#xff0c;也是一个基于服务端的运行引擎。 GraphQL 提供了一套完整的规范和描述用于查询 API&#xf…...

9.1 链表

链表&#xff1a;数据结构&#xff0c;一堆数据的集合&#xff0c;链表的每一项都是结构体&#xff0c;都使用指针指向下一个结构体。 数组的缺点&#xff1a;由于数组的地址是连续的&#xff0c;对数组的数据进行增、删、改后数据不连续&#xff0c;需要较大的运算量才能实现…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...