一文讲清楚c/c++中的宏
一文讲清楚c/c++中的宏
文章目录
- 一文讲清楚c/c++中的宏
- 一、如何理解这个“宏”字面的意思呢?
- 二、c/c++中的宏详解
- 三、宏的使用场景
一、如何理解这个“宏”字面的意思呢?
在刚开始学习C语言的时候,始终有点分不清楚"宏"这个字面上的意思,现在来讲讲如何理解这个"宏"。
"宏" 这个词在不同的上下文中可以有不同的意义,但在计算机编程领域中,通常指的是一种预处理指令,用于在编译之前进行文本替换。下面我将从几个角度解释 “宏” 这个词的含义:
-
计算机编程中的宏:
在编程中,宏是一种编译预处理指令,允许您在代码中定义一个标识符,并将其替换为特定的代码片段。这种替换是在实际编译之前完成的。宏可以用于定义常量、创建代码缩写、实现条件编译等。在C++等编程语言中,您可以使用 #define 指令来创建宏。 -
宏观:
“宏” 这个词也可以用于表示对事物的整体、全局或宏观的理解。例如,“宏观经济学” 指的是研究整个经济体系的学科,而不是关注于个别市场或行业。 -
大规模:
在一些语境下,“宏” 也可以表示大规模、广泛或全局的概念。例如,“宏观管理” 可能指的是整体的管理方法,而不是局部细节。 -
宏命令:
在某些情况下,“宏” 也可能指的是一系列预定义的命令序列,可以在一个步骤中执行多个操作。这在图形设计、办公软件等领域中常见。
总的来说,“宏” 这个词在计算机编程中通常指的是一种预处理指令,用于在代码编译之前进行文本替换。然而,根据上下文,它还可能有其他意义,如对整体的理解、大规模的范围或预定义的命令序列。
二、c/c++中的宏详解
C++中的宏(Macro)是一种预处理指令,用于在编译之前进行文本替换。宏允许您在代码中定义一些缩写或替代品,以便在编译时将它们替换为实际的代码片段。宏通常以 #define 指令开始,后面跟着宏的名称和替换文本。
以下是一些关于C++宏的基本用法和注意事项:
1、宏定义
#define MAX_VALUE 100
在代码中使用 MAX_VALUE 将被替换为 100。
2、带参数的宏
#define SQUARE(x) (x * x)
这个宏接受一个参数 x,并计算其平方。注意,宏中的参数没有类型检查,因此要小心使用。
3、宏调用
int result = SQUARE(5); // 将被替换为 int result = (5 * 5);
4、宏与括号
宏中使用的参数应该用括号括起来,以防止优先级问题导致意外的结果。例如,定义一个安全的平方宏应该这样写:
#define SAFE_SQUARE(x) ((x) * (x))
5、宏的限制
- 宏不会执行类型检查,可能导致意外的错误;
- 宏展开后可能会产生意想不到的副作用;
- 调试宏可能会变得困难,因为你看到的是替换后的代码而不是原始代码。
6、条件编译宏
宏可以用于条件编译,以在不同的情况下编译不同的代码:
#define DEBUG_MODE
#ifdef DEBUG_MODE// 调试模式下的代码
#endif
7、取消定义宏
使用#undef指令可以取消之前定义的宏:
#undef MAX_VALUE
8、预定义宏
c++还提供了一些预定义的宏,如__FILE__(当前文件名)、__LINE__(当前行号)等,用于在代码中获取编译时的信息。
宏在c++是强大但潜在危险的工具。在现代c++中,它们通常被安全和灵活的特性(如常量表达式、内联函数等)取代。使用宏时,要小心遵循最佳实践,以避免潜在的问题。
三、宏的使用场景
虽然在现代C++中有更安全和灵活的特性可以取代宏,但在某些情况下,仍然可以考虑使用宏。以下是一些使用宏的情况:
1、编译时常量:宏可以用于定义编译时的常量值,如数组大小、枚举值等。
#define ARRAY_SIZE 10
int arr[ARRAY_SIZE];
2、条件编译:宏可以用于在不同条件下编译不同的代码。这在处理平台特定代码或调试代码时很有用。
#ifdef DEBUG_MODE// 调试模式下的代码
#endif
3、代码重用:宏可以用于创建代码片段的缩写,以减少重复输入。
#define LOG(message) std::cout << message << std::endl;
LOG("Hello, world!");
4、简单的计算:对于简单的表达式和计算,宏可能比函数调用更高效。
#define SQUARE(x) ((x) * (x))
int result = SQUARE(5);
5、内联函数模拟:在老版本的C++编译器中,宏被用于模拟内联函数,以减少函数调用的开销。
#define INLINE_FUNCTION inline
INLINE_FUNCTION int add(int a, int b) {return a + b;
}
尽管这些情况下宏是有用的,但在现代C++中,您通常会更倾向于使用常量表达式、constexpr、inline函数等更安全和易维护的方法。宏的使用往往会导致可读性下降、难以调试和维护的问题。因此,在使用宏之前,请权衡利弊并考虑是否有更好的替代方案。
相关文章:
一文讲清楚c/c++中的宏
一文讲清楚c/c中的宏 文章目录 一文讲清楚c/c中的宏一、如何理解这个“宏”字面的意思呢?二、c/c中的宏详解三、宏的使用场景 一、如何理解这个“宏”字面的意思呢? 在刚开始学习C语言的时候,始终有点分不清楚"宏"这个字面上的意思…...
typescript进阶语法
typescript进阶语法 interface 接口定义 interface userType {name:string,age:number,sex?:string }type接口定义 type userType {name:string,age:number,sex?:string } type userType username # 固定值写法 let user:userType age # 报错 只能等于usernamepick摘取…...
宝塔终端 查看 7003端口 占用 并且杀死
要查看端口是否被占用并杀死相关进程,你可以按照以下步骤执行: 打开宝塔面板,进入服务器管理页面。在左侧导航栏中选择「工具」,然后选择「终端」进入宝塔终端界面。输入以下命令查看端口占用情况:netstat -tuln | gr…...
可解释性的相关介绍
一、可解释性的元定义(Meta-definitions of Interpretability) The extent to which an individual can comprehend the cause of a model’s outcome. [1]The degree to which a human can consistently predict a model’s outcome. [2] 可解释性&am…...
AUTOSAR规范与ECU软件开发(实践篇)6.7 服务软件组件与应用层软件组件端口连接
在生成了BSW模块的代码后, 切换到ISOLAR-A系统级设计界面,会发现产生一些基础软件模块的服务软件组件: BswM、 ComM、 Det和EcuM等, 如图6.60所示。 图6.60 生成了BSW后的服务软件组件 此时, 如果涉及服务软件组件与应用层软件组件的交互, 就需要为应用层软件组…...
菜鸟教程《Python 3 教程》笔记(6):列表
菜鸟教程《Python 3 教程》笔记(6) 6 列表6.1 删除列表元素6.2 列表函数和方法6.2.1 max()、min()6.2.2 reverse()6.2.3 sort() 6 列表 出处: 菜鸟教程 - Python3 列表 6.1 删除列表元素 >>> list [Google, Runoob, 1997, 2000]…...
LeetCode-56-合并区间
题目描述: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 可以使用 LinkedList,…...
Git gui教程---番外篇 gitignore 的文件使用
想说的 .gitignore 的文件一般大型的编译器带git的都会生成,他可以将你不想提交的文件在git下忽略掉,你应该不想将一大堆编译生成的过程文件,还有一些贼大的文件提交上git的。 凡是都有例外,一些冥顽不灵的编辑器,只能…...
javaee spring 用注解的方式实现ioc
spring 用注解的方式实现ioc spring核心依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…...
Linux基础(二)
这里写目录标题 一、网络管理1- 网络状态查看1.1 net-tools1.2 iproute2 2- 网络故障排除 !step1:检测当前主机和目标主机是否畅通 [ping]step2:检测网络质量,追踪路由 [traceroute]step3:检测网络质量,检查是否有数据包丢失 [mrt]step4: 检查端口是否畅通 [telnet]…...
155. 最小栈(中等系列)
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部的元素。 int top() 获取堆栈顶部的元素。 int…...
用python从零开始做一个最简单的小说爬虫带GUI界面(3/3)
目录 上一章内容 前言 出现的一些问题 requests包爬取小说的不便之处 利用aiohttp包来异步爬取小说 介绍 代码 main.py test_1.py test_3.py 代码大致讲解 注意 系列总结 上一章内容 用python从零开始做一个最简单的小说爬虫带GUI界面(2/3)_…...
SpringBoot+Vue如何写一个HelloWorld
一、SpringBoot介绍 Spring Boot是一个用于创建独立且可执行的Spring应用程序的框架。它简化了基于Spring框架的应用程序的开发过程,并提供了一种快速和简便的方式来构建Java应用程序。 Spring Boot提供了自动配置机制,通过引入适当的依赖项࿰…...
深度强化学习。介绍。深度 Q 网络 (DQN) 算法
马库斯布赫霍尔茨 一. 引言 深度强化学习的起源是纯粹的强化学习,其中问题通常被框定为马尔可夫决策过程(MDP)。MDP 由一组状态 S 和操作 A 组成。状态之间的转换使用转移概率 P、奖励 R 和贴现因子 gamma 执行。概率转换P(系统动…...
【C++随笔02】左值和右值
【C随笔02】左值和右值 一、左值和右值1、字面理解——左值、右值2、字面理解的问题3、左值、右值4、左值的特征5、 右值的特征6、x和x是左值还是右值7、复合例子8、通常字面量都是一个右值,除字符串字面量以外: 二、左值引用和右值引用三、左值引用1、常…...
几个nlp的小任务(多选问答)
@TOC 安装库 多选问答介绍 定义参数、导入加载函数 缓存数据集 随机选择一些数据展示 进行数据预处理部分(tokenizer) 调用t...
【C++学习记录】为什么需要异常处理,以及Try Catch的使用方法
1.什么是异常,什么是错误? 程序无法保证100%正确运行,万无一失。有的错误在编译时能发现,比如:关键字拼写、变量名未定义、括号不配对、语句末尾缺分号等。这是在编译阶段发现的,称为编译错误。 有的能正常…...
孪生网络(Siamese Network)
基本概念 孪生网络(Siamese Network)是一类神经网络结构,它是由两个或更多个完全相同的网络组成的。孪生网络通常被用于解决基于相似度比较的任务,例如人脸识别、语音识别、目标跟踪等问题。 孪生网络的基本思想是将输入数据同时…...
【Redis】Redis是什么、能干什么、主要功能和工作原理的详细讲解
🚀欢迎来到本文🚀 🍉个人简介:陈童学哦,目前学习C/C、算法、Python、Java等方向,一个正在慢慢前行的普通人。 🏀系列专栏:陈童学的日记 💡其他专栏:CSTL&…...
8月26日,每日信息差
1、上海发布两项支持高级别自动驾驶的5G网络标准,在上海市通管局的指导下,由上海移动和中国信息通信研究院牵头组织二十余家标准起草单位共同参与编写的《支持高级别自动驾驶的5G网络规划建设和验收要求》和《支持高级别自动驾驶的5G网络性能要求》等两项…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
