C/C++你真的了解宏吗?

         宏?提到这个词想必很多初学者吃过它的亏,但是为什么,一些程序员老鸟写一下代码时坚持使用宏呢?带着这样的疑问,下面我将对上面的问题一 一进行解答。

        首先想一个问题?如果一个功能,用宏和函数都可以实现,你们会选择什么呢?可能有的人会选择宏,有的人会选择函数,但是我想告诉你,其实选择什么是要看场景的。

如果功能不是非常的复杂这个时候应该首先宏

        宏在经过预处理阶段就已经完成了替换,到了编译阶段,计算机直接写出汇编指令对应的计算就可以了。而函数在此阶段,计算机需要先写 创建函数栈帧 的汇编指令,才可以写 与 实际计算 有关 的汇编指令,还要考虑函数的返回值等问题。所以宏是最好的选择

如果功能非常的复杂这个时候应该首先函数 

        函数有宏不具有的优势,函数在处理复杂问题时,可以进行调试,帮助我们化繁为简。但宏可以接受很多不同类型的参数,且宏还可以传递类型,说实话很泛泛,不够精细化,而且宏不可调试。

作为新手应该如何用好宏?

这里我归纳出了3点建议

 1.口诀

   defi 定义宏,

   切记不加 ;  。

   宏里有参数,
   括号来几副。
   参数有增减,
   值得注意点。

 这个是个人总结的一句口诀,按照这个口诀,你将避免50%以上的出错记录。

下面我们来举个反例。

#define MUL(x,y) x+y

int mian(int argc,char *argv[])

{

        int a=3;

        int b=5;

        int c=MUL(a,b)*a+b;//在这里很多新手会想当然 8*3+5,最后得到29,但其实这是错误的

                                        //其实真确的结果应该是 3+5*3+5,最后得到23。

        return 0;

}

其实解决方法很简单 ,我们可以这样写

#define MUL(x,y) ((x)+(y))//给参数自己加上括号,还有就是参数整体加上括号

还有很多反例,我在这里就不一 一赘述了,上面的例子是说口诀的中间两句,下面我再给口诀的最后两句举个例子。

#define MAX(x,y,z) ((x)>(y)?(z):(x))

int mian(int argc,char *argv[])

{

        int a=3;

        int b=5;

        int c=6;

        int d=MAX(a++,b++,c++);//这个计算过程是这样的

                                                //a++>b++?c++:a++

                                                //a和b比较  a不大于比 a从3->4 b从5->6

                                                //选择后者a++   a从4->5

                                                a=5 b=6 c=6 d=4(第一次变第二次没变的a)

        printf("a=%d b=%d c=%d d=%d",a,b,c,d);  

        return 0;

}

这出现宏中的参数带++/--,大家遇到这种题一定要把式子带到里边一点点的算,这种操作在日常写代码的时候不建议使用,这会带来很严重的副作用。

2.#在宏的作用

  #宏参数名 可以让参数名在字符串中灵活变换

举个例子 
#define PRINT(a,b,c)  printf(#a"=%d "#b "=%d"#c "=%d", a, b, c)

#include<stdio.h>

int main() 
{
    int a = 3;

    int b = 5;

    int c = 6;

    PRINT(a,b,c);//这里打印的结果是a=3 b=5 c=6
    return 0;
}

从这里看出我们成功的把参数本身的名字和字符串拼接到了一起。

3.##在宏的作用

##宏参数名 可以让常量名合并

举个例子

 

#define CONNECT(x,y)  x##y

#include<stdio.h>

int main() 
{
    int ab = 3;
    
    printf("ab=%d\n", ab);
    printf("ab=%d",CONNECT(a, b));//这里打印的结果是

                                                        ab=3

                                                        ab=3                                 
    return 0;
}

从这里可以看出我们很好的实现了常量名的合并使用。

那么今天就写到这里吧,不知不觉已经到了深夜1点40,希望大家给我点个赞,给我更多的鼓励,我会坚持更新的,例子是为了让读者们能够更好的理解宏,烦请各位大佬高抬贵手不要喷我!!!

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

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

相关文章

canvas绘制横竖坐标轴(带有箭头和刻度)

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

[项目管理] 如何使用git客户端管理gitee的私有仓库

最近发现即使翻墙也无法g使用ithub了&#xff0c;需要把本地的项目搬迁到新的git托管平台。 gitee 是一个国内开源项目托管平台&#xff0c;是开源开发者、团队、个人进行 git 代码管理和协作的首选平台之一。本文将详细介绍如何向 gitee 提交私有项目。 注册 Gitee 账号并创建…

P3372 【模板】线段树 1

网址如下&#xff1a; P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题如其名 昨天做了一道开关&#xff08;也是线段树的&#xff09; 想着今天复习一下 代码如下&#xff1a; #include<iostream> using namespace std; typedef long long…

golang 引入swagger(iris、gin)

golang 引入swagger&#xff08;iris、gin&#xff09; 在开发过程中&#xff0c;我们不免需要调试我们的接口&#xff0c;但是有些接口测试工具无法根据我们的接口变化而动态变化。文档和代码是分离的。总是出现文档和代码不同步的情况。这个时候就可以在我们项目中引入swagge…

【漏洞复现】多语言药房管理系统MPMS文件上传漏洞

Nx01 产品简介 多语言药房管理系统 (MPMS) 是用 PHP 和 MySQL 开发的, 该软件的主要目的是在药房和客户之间提供一套接口&#xff0c;客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库&#xff0c;并根据到期、产品等各种参数提供各种报告。 Nx02 漏洞描述 …

显示器颜色显示技术原理

此图片来源于网络 1、人眼是如何看到颜色的 以下介绍如何定义颜色的基本知识。首先人眼是如何看到颜色的。可见光的光谱范围从380纳米到750纳米。在此范围内&#xff0c;可以看到每种可见颜色的相应波长。将讨论如何将可见光谱的波长组合成其他颜色&#xff0c;以及这一过程是…

2023年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A:10倍 B:2倍 C:4倍 D:8倍 答案:C 二进制进位规则是逢二进一,因此末尾添加一个0,是扩大2倍,添加两个0…

DataX源码分析-JobContainer

系列文章目录 一、DataX详解和架构介绍 二、DataX源码分析 JobContainer 三、DataX源码分析 TaskGroupContainer 四、DataX源码分析 TaskExecutor 五、DataX源码分析 reader 六、DataX源码分析 writer 七、DataX源码分析 Channel 文章目录 系列文章目录JobContainerJobContain…

postman执行批量测试

1.背景 有许多的人常常需要使用第三方系统进行重复的数据查询&#xff0c;本文介绍使用PostMan的方式对数据进行批量的查询&#xff0c;减少重复的劳动。 2.工具下载 3.初入门 一、如图示进行点击&#xff0c;创建collection 二、输入对应的名称 三、创建Request并进行查…

C++后端开发之Sylar学习二:配置VSCode远程连接Ubuntu开发

C后端开发之Sylar学习二&#xff1a;配置VSCode远程连接Ubuntu开发 没错&#xff0c;我不能像大佬那样直接在Ubuntu上面用Vim手搓代码&#xff0c;只能在本地配置一下VSCode远程连接Ubuntu进行开发咯&#xff01; 本篇主要是讲解了VSCode如何配置ssh连接Ubuntu&#xff0c;还有…

无损音乐下载,最新音乐下载,mp3格式音乐下载,一键下载mp3格式音乐,我只用这个软件,歌曲资源丰富,全网音乐免费下载,稳定运行,告别收费

一、软件简介 现在很多支持一键下载mp3音乐/无损音质音乐的音乐播放器通常都是解析接口套了一个壳&#xff0c;一旦解析接口失效&#xff0c;软件就不能下载音乐了&#xff0c;因此一个稳定的解析接口是这类软件最大的保障。本次小编推荐的音乐下载软件接口非常稳定&#xff0…

货仓选址(c++题解)

题目描述 在一条数轴上有N家商店&#xff0c;它们的坐标分别为 A[1]~A[N]。现在需要在数轴上建立一家货仓&#xff0c;每天清晨&#xff0c;从货仓到每家商店都要运送一车商品。为了提高效率&#xff0c;求把货仓建在何处&#xff0c;可以使得货仓到每家商店的距离之和最小。 …

单片机学习笔记---LED点阵屏的工作原理

目录 LED点阵屏分类 LED点阵屏显示原理 74HC595的介绍 一片74HC595的工作原理 多片级联工作原理 总结 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合&#xff0c;如汽…

3分钟带你了解Vue3的nextTick()

前言 Vue 实现响应式并不是数据发生变化之后 DOM 立即变化&#xff0c;而是按一定的策略进行 DOM 的更新。简单来说&#xff0c;Vue在修改数据后&#xff0c;视图不会立刻更新&#xff0c;而是等同一事件循环中的所有数据变化完成之后&#xff0c;再统一进行视图更新&#xff…

第五篇【传奇开心果系列】vant开发移动应用示例:深度解读高度可定制

传奇开心果博文系列 系列博文目录Vant 开发移动应用示例系列 博文目录前言一、Vant高度可定制的重要作用二、样式定制介绍和示例代码三、组件定制介绍和示例代码四、组件库定制介绍和示例代码五、主题定制介绍和示例代码六、语言环境定制介绍和示例代码七、资源加载定制介绍和示…

网络层DoS

网络层是OSI参考模型中的第三层&#xff0c;介于传输层和数据链路层之间&#xff0c;其目的 是实现两个终端系统之间数据的透明传送&#xff0c;具体功能包括&#xff1a;寻址和路由选择、连 接的建立、保持和终止等。位于网络层的协议包括ARP 、IP和ICMP等。下面就 ICMP为例&…

创建一个VUE项目(vue2和vue3)

背景&#xff1a;电脑已经安装完vue2和vue3环境 一台Mac同时安装vue2和vue3 https://blog.csdn.net/c103363/article/details/136059783 创建vue2项目 vue init webpack "项目名称"创建vue3项目 vue create "项目名称"

diffusers单机多卡推理(全网首发)

起因 博主在部署InstantID项目时&#xff0c;显存不够&#xff0c;想要将模型分散在多张卡上。 翻到这篇发现是分布式推理&#xff0c;博主一直以为这个可以达到我想要的效果&#xff0c;但是效果是多线程并行推理&#xff0c;并不能将一个模型切片在多个GPU上。 Distributed …

一起玩儿物联网人工智能小车(ESP32)——57. SPI总线协议初探(一)

摘要&#xff1a;介绍SPI总线的基本知识 前面已经学习过IIC总线协议&#xff0c;今天开始介绍另一个总线协议——SPI。SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是由Motorola提出的一种高速、全双工、同步的通信总线。并且在芯片的管脚…

TI的电量计驱动在卸载时导致Linux卡死

背景 最近移植TI电量计芯片bq40z50的驱动&#xff0c;移植完毕后&#xff0c;能正常读取电池信息了&#xff0c;但是无意中发现驱动卸载会导致Linux卡死&#xff0c;死前终端闪过大量打印&#xff0c;将putty的缓冲区都耗尽了&#xff0c;必须启用syslog转发并用visual syslog…