C语言 17 宏定义

news2024/9/30 4:10:38

前面认识了#include指令,接着来看#define指令,它可以实现宏定义。宏是啥意思?

在这里插入图片描述

把参数批量替换到文本中,这种实现通常称为(macro)或定义宏 (define macro)

可以通过#define来定义宏,规则如下:

#define 宏名(记号) 内容

比如现在想通过宏定义一个PI:

#define PI 3.1415926

这样就可以了,那么怎么去使用它呢?

#include <stdio.h>

#define PI 3.1415926

int main() {
    // 就像使用变量一样,我们可以直接将PI放到这个位置
    printf("π的值为:%f", PI);  
}
π的值为:3.141593

在编译时,预处理程序会进行宏替换操作,也就是将程序中所有的PI全部替换为3.1415926,注意这个跟类型无关,是赤裸裸的纯文本替换,也就是相当于把代码修改了,PI那里直接变成3.1415926,当然如果你定义为其他任意的内容,同样会替换到那个位置,但是至于替换之后程序还正不正常就不知道了。

通过下面这个例子来加深对文本替换这句话的理解:

#include <stdio.h>

#define M a + b

int main() {
    int a = 10, b = 20;
    printf("%d", M * a);
}
210

如果按照一般思维,M 是 a + b,那么替换上去之后应该就是 30,然后 30 x 10 最后得到的应该是 300 才对。

怎么会算出来是 210 的呢?

实际上在编译时仅仅是做了文本替换,相当于最后的代码是:

printf("%d", a + b * a);

最后结果就是 210 了。

当然任何地方都可以使用宏替换,包括类型,反正最后都会变成被替换的内容:

#define lbwnb long

int main() {
    lbwnb a = 10L;
}

当然除了这种简单的替换之外还可以添加参数,就像函数那样:

#include <stdio.h>

#define MUL(x) x * x

int main() {
    printf("%d", MUL(9));
}
81

虽然这里搞得像函数一样,但是最后还是会被替换为 x * x,而这个 x 就是填写的参数,所以最后会变成 9 * 9 替换上去,程序运行出来的结果就是 81 了。

直接调函数肯定也是没问题的,反正就纯替换:

#include <stdio.h>

#define bb(i) printf("我是宏替换的:%d", i);

int main() {
    bb(666);
}
我是宏替换的:666

那要是想在字符串里面加一个宏定义中的参数呢?

#include <stdio.h>

// 使用#直接在字符串中进行宏替换,否则默认情况下会被当做一个字符
#define bb(str) printf("我是宏替换的:" #str " <");  

int main() {
    bb("替换成功");
}
我是宏替换的:"替换成功" <

当然还可以替换宏中的部分:

// ##会使用参数进行拼接
#define TEST(n) x##n  

int main() {
    // 这里传入1,那么实际上就是被替换为x1
    int TEST(1) = 10;  
    // 所以上面其实是int x1 = 10
    x1 = 20;           
}

宏既然可以定义出来,那么也可以取消定义,可以使用#undef来取消已有的宏定义:

可以看到在使用#undef之后,直接不认识了。

当然除了我们自己可以去定义之外,系统也为我们提供了一些预定义的宏:

宏名称含义
_ _ DATE _ _当前的日期,格式为类似 Jun 27 2023 的字符串
_ _ TIME _ _当前的时间,格式为类似 10:23:12 的字符串
_ _ FILE _ _当前源代码文件的名称(含路径)的字符串
_ _ LINE _ _当前所处的行号是多少就替换为多少,整数

这里只列出了一部分。


环境:

  • GCC 11.4.0
  • VSCode 1.93.1

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

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

相关文章

Cyber Weekly #26

赛博新闻 1、Meta发布最强AR眼镜 Meta Connect 2024大会展示了多款新产品和技术&#xff0c;包括更便宜的Quest 3S系列AR眼镜、新功能丰富的Meta Rayban眼镜、OrionAR眼镜原型机&#xff0c;以及月活5亿用户的Meta AI。其中&#xff0c;OrionAR眼镜以其先进的交互体验和强大的…

鸿蒙开发(NEXT/API 12)【硬件(传感器开发3)】传感器服务

场景介绍 当设备需要获取传感器数据时&#xff0c;可以使用sensor模块&#xff0c;例如&#xff1a;通过订阅方向传感器数据感知用户设备当前的朝向&#xff0c;通过订阅计步传感器数据统计用户的步数等。 函数说明 名称描述OH_Sensor_GetInfos(Sensor_Info **infos, uint32…

算力运力解决方案:构建未来智算新生态

中国联通国际有限公司产品之算力运力解决方案&#xff1a;构建未来智算新生态 在当今这个数据爆炸、技术日新月异的时代&#xff0c;算力已成为推动社会进步和产业升级的关键力量。中国联通国际有限公司紧跟时代步伐&#xff0c;依托其强大的网络资源和深厚的技术积累&#xf…

Linux进程间的通信(四)System-V共享内存

什么是共享内存 共享内存&#xff0c;顾名思义就是允许两个不相关的进程访问同一个逻辑内存&#xff0c;共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。 不同进程之间共享的内存通常为同一段物理内存。进程可以将同一段物理内存连接到他们自己的地址空…

深度学习后门攻击分析与实现(二)

前言 在本系列的第一部分中&#xff0c;我们已经掌握了深度学习中的后门攻击的特点以及基础的攻击方式&#xff0c;现在我们在第二部分中首先来学习深度学习后门攻击在传统网络空间安全中的应用。然后再来分析与实现一些颇具特点的深度学习后门攻击方式。 深度学习与网络空间…

Node.js安装Express,Node.js支持Typescript以及Express支持Typescript的步骤

1. Node.js 安装Express 运行如下命令&#xff1a; $ mkdir express-demo $ cd express-demo$ npm install express $ npm install body-parser //(可选)中间件&#xff0c;用于处理 JSON, Raw, Text 和 URL 编码的数据 $ npm install cookie-parser //(可选)通过req.cookies…

怎么用gitee做一个图片仓库,在md文档中用这个图片网络地址,然后显示图片

痛因&#xff1a;我为什么要这样做&#xff0c;呃&#xff0c;我一开始图片都是存本地地址的&#xff0c;放在和这个md文档同级的assets文件夹下面&#xff0c;这样子确实当时很方便&#xff0c;复制粘贴什么也不用管&#xff0c;但是想把这个文档分享给别的人的时候&#xff0…

Windows打开HDF5图像:HDFView软件的下载、安装

本文介绍在Windows电脑中&#xff0c;下载、安装用以查看HDF5图像数据的软件HDFView的方法。 HDF5&#xff08;Hierarchical Data Format 5&#xff09;是一种用于存储和管理大量科学数据的文件格式&#xff0c;其由HDF Group开发和维护&#xff0c;广泛应用于科学计算、工程、…

ESP8266wifi模块的使用

文章目录 概要整体架构流程技术名词解释具体配置过程小结 概要 本文旨在介绍ESP8266,做为客户端 电脑做为服务端&#xff0c;通过TCP/IP协议在同一个局域网下通过WiFi进行数据交互 设备选用 esp8266 软件选择 安信可串口调试助手 网络调试助手 &#xff08;若没有软件可私…

OpenCV threhold()函数

OpenCV threhold()函数的主要用途是将灰度图转换为二值图像,实现灰度图的二值化&#xff0c;在机器视觉中使用频度较高&#xff0c;如尺寸量测&#xff0c;物体识别等。其原型如下&#xff1a; 函数参数&#xff1a; src 输入数组&#xff08;多通道、8 位或 32 位浮点&#xf…

SpringBoot3脚手架

MySpringBootAPI SpringBoot3脚手架&#xff0c;基于SpringBoot3DruidPgSQLMyBatisPlus13FastJSON2Lombok&#xff0c;启动web容器为Undertow(非默认tomcat)&#xff0c;其他的请自行添加和配置。 <java.version>17</java.version> <springboot.version>3.3…

项目集成SpringSecurity框架

目录 项目没集成SpringSecurity框架的实现 项目之前的登录接口 LoginReqVo 接收前端的数据类型 LoginRespVo返回给前端的数据 项目集成SpringSecurity 第一步:导入依赖 第二步:创建security包结构 第三步&#xff1a;实现认证过滤器 第一步&#xff1a;自定义认证过滤器…

Modbus调试工具和源码分享

我们应该知道了学习Modbus协议应该具备主从两个设备才行&#xff0c;但是在学习过程中如果没有真实的物理设备&#xff0c;应该怎么调试呢&#xff1f; 我们可以通过软件工具来模拟主从设备&#xff0c;下面我们推荐几个比较实用的工具。 以下内容包含&#xff1a;实用工具、…

超好用的10款视频剪辑软件,从入门到精通

视频剪辑软件哪款比较好呢&#xff1f;无论是专业制作团队、自媒体创作者&#xff0c;还是家庭用户&#xff0c;一款好用的视频剪辑软件都能极大地提升创作效率和作品质量。以下是十款备受推崇的视频剪辑软件&#xff0c;分别从适用人群、易用程度和功能特点进行介绍。 1.影忆…

揭秘移动硬盘RAW:原因、恢复策略与预防措施

移动硬盘RAW概述 移动硬盘&#xff0c;作为现代数据存储的重要工具&#xff0c;其稳定性与数据安全直接关乎用户的数据资产安全。然而&#xff0c;在使用过程中&#xff0c;不少用户会遇到移动硬盘状态突然变为RAW格式的情况&#xff0c;这往往伴随着数据无法直接访问的困扰。…

1688客服代码怎么做生成悬浮客服代码阿里巴巴国内站1688平台悬浮特效悬浮代码悬浮客服 1688客服代码怎么做生成器软件代码工具制作客服代码阿里巴巴

阿里巴巴国内站1688平台悬浮特效悬浮代码悬浮客服 1688客服代码怎么做生成器软件代码工具制作客服代码阿里巴巴 一秒美工工具

王道-操作系统

3 下列说法正确的是_____ 答案:A 解析: A 正确。如链接文件可以顺序存取,但不能随机存取。连续文件可随机存取,也可顺序存取。 B 错误。一个 FCB 就是一个文件目录项。在引入索引节点后,每个文件的目录项只保留文件名和指向该文件对应的索引节点指针,而索引节点的有关信息…

一书直接讲透自然语言处理《Getting Started with Google BERT_ Build and train》

《Getting Started with Google BERT: Build and Train》是一本面向初学者和中级读者的指南&#xff0c;旨在帮助他们理解和使用Google的BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;模型。BERT是近年来自然语言处理&#xff08;NLP&…

WIFI密码默认显示

文章目录 需求分析遇到问题问题原因解决方案 需求 在进入设置&#xff0c;点击某一个wifi,连接wifi 界面&#xff0c;显示密码默认选中状态&#xff0c;效果如下 分析 在 WiFi密码被输入法挡住 中我们已经分析了整个流程&#xff0c;布局文件和控制中心。 结局系统设置WIFI连…

9.29总结

这星期学了概率和组合数学 这是我觉得的一个有趣的题目&#xff0c;每个人身上都有n-1根绳子&#xff0c;如果组不成稳定三角&#xff0c;那么肯定有两个人相邻两根绳子颜色不一样&#xff0c;那么每两个这样的人就会贡献一个不稳定三角形&#xff0c;所以只要所有三角形减去每…