#define定义宏

#define的定义范围

 

#define不光可以定义变量,常量,还可以定义几乎所有的东西,因为#define可以定义一串代码(即宏),所以包含在代码中的东西都能被定义。

 


#define定义宏



定义是宏名必须于它的参数括号紧挨,中间不能有任何符号,空格都不行。

宏中传参的时候是直接把传进去的参数直接替换,而不是先计算表达式再传参。

所以如果你的参数只有一个,但你却传了一个表达式,他会把这个表达式直接替换进去,这个时候如果不加括号,肯定就会出现错误。

ee5d1d0bb9424b339a195a9a7a5472a9.png 

 因为*的优先级大于+,所以他得到的结果不是36,而是11。

 

此时加上括号就可以解决

即   square(x) (X)*(X)

 

其实光给X打括号还不够安全

4c4302319efa4fc2953ad8a4e175270d.png

我们想要的来是,3传进去得到6,6在与10相乘得到60

 

但其实实际得到的结果是33。

 

此时如果在在两个x的后打一个包括两个X的括号,就可以解决。

即   square(x)((X)*(X))

 

所以为了安全,尽量给宏的参数和整个宏的内容都打上括号。

 


#define替换规则



1.在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。

 

2.替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。

 

3.最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。

 

宏参数和#define定义中可以出现其他#define定义的符号。

但是对于宏,不能递归。

当预处理器搜索#define定义的符号的时候,字符串中的内容并不被搜索和改变

 


宏的内容中的#的作用



的作用是,放在参数的前面

可以将传进来的参数变成对应的字符串。

 

例   假设传进去的参数是abcd,如果你在宏的内容中的参数前加了#,他就会被修改为"abcd"


宏中的##的作用



将##两边的符号合成一个符号,但是合成之后的符号必须是定义过的

例:如果宏中有sum##a,在执行程序的时候,sum##就相当于suma被使用

 

##也可以放在宏参数和宏参数之间或者宏参数和符号之间

4554b832d54e430e9c093d13b3601ab1.png

 


带副作用的宏参数



当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

 

e9ce7892d5e14a64ab0d04c61f1c8cdb.png

 上图的宏参数传了a++和b++,传入了MAX后的代码相当于106行写的代码。

 

可以看到a和b都在宏中被多次赋值,得到的结果,可能不是我们想要的结果。

 

而且宏不像函数传值调用时函数调用结束后不改变实参,


宏调用之后不管你是传值还是传地址,传入的参数只要在宏中改变了,宏调用结束后,实参也会被改变。


所以MAX调用结束后m的值为6,a的值为7,b的值为5

所以使用宏时参数尽量不要使用有副作用的参数。

 


宏对于函数的优缺点


优点:

1.因为宏是在预处理的时候就编译了,运行的时候不用再编译,只需要执行计算就可以,所以用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。

 

2.更为重要的是函数的参数必须声明为特定的类型,而宏不用

所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于>来比较的类型。

 

缺点:

1.每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。

2.宏是没法调试的。

3.宏由于类型无关,也就不够严谨。

4.宏可能会带来运算符优先级的问题,导致程容易出现错。

5、宏不能递归。

 

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

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

相关文章

用linux中定时任务Crontab,向企业微信群通过机器人发送消息

1.使用yum命令安装Crontab:这个很关键,没有安装的话会提示命令not found yum install vixie-cron yum install crontabs 注:vixie-cron软件包是cron的主程序; crontabs软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表…

Oracle中long 和 varchar 区别

Oracle中的LONG和VARCHAR2是两种用于存储字符数据的数据类型,但它们之间存在一些关键差异。以下是它们的主要区别: 存储容量: LONG:可以存储最多2 GB的字符数据。 VARCHAR2:在Oracle Database 12c及更早版本中&#…

Leetcode7-库存管理(158)

1、题目 仓库管理员以数组 stock 形式记录商品库存表。stock[i] 表示商品 id&#xff0c;可能存在重复。请返回库存表中数量大于 stock.length / 2 的商品 id。 示例 1: 输入: stock [6, 1, 3, 1, 1, 1] 输出: 1 限制&#xff1a; 1 < stock.length < 50000 给定数…

GitOps实践指南:GitOps能为我们带来什么?

Git&#xff0c;作为开发过程中的核心工具&#xff0c;提供了强大的版本控制功能。即便在写代码的时候稍微手抖一下&#xff0c;我们也能通过 Git 的差异对比&#xff08;diff&#xff09;轻松追踪到庞大工程中的问题&#xff0c;确保代码的准确与可靠。这种无与伦比的自省能力…

子类能继承父类的那些内容

子类能继承父类的那些内容 子类不能继承父类的构造方法。 package oop.Extends.a02oopextendsdemo02; public class Test {public static void main(String[] args) {}class Fu{String name;int age;public Fu() {}public Fu(String name, int age) {this.name name;this.ag…

树莓派非常实用的程序-1 tvservice

tvservice 是一个命令行应用程序&#xff0c;用于获取和设置有关显示器的信息&#xff0c;主要针对HDMI视频和音频。 键入 tvservice 本身将显示可用命令行选项的列表。 -p, --preferred 使用首选设置打开 HDMI 输出。 -o, --off 关闭显示器输出。 NOTE 使用此命令关闭输…

【leetcode100-023】【链表】反转链表

【题干】 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 【思路】 太经典了&#xff0c;感觉也没什么必要用文字来描述了&#xff0c;今天实在太累了&#xff0c;直接代码吧。 【题解】 class Solution { public:ListNode* reverseL…

Leetcode5-在长度2N的数组中找出重复N次的元素(961)

1、题目 给你一个整数数组 nums &#xff0c;该数组具有以下属性&#xff1a; nums.length 2 * n. nums 包含 n 1 个 不同的 元素 nums 中恰有一个元素重复 n 次 找出并返回重复了 n 次的那个元素。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,3] 输出&#xff1a…

一、C++简介

C语言的发展史 1983年&#xff0c;贝尔实验室&#xff08;Bell Labs&#xff09;的Bjarne Stroustrup发明了C。 C在C语言的基础上进行了扩充和完善&#xff0c;是一种面向对象程序设计&#xff08;OOP&#xff09;语言。 Stroustrup说&#xff1a;“这个名字象征着源自于C语言变…

Redis 核心知识总结

Redis 核心知识总结 认识 Redis 什么是 Redis&#xff1f; Redis 是一个由 C 语言开发并且基于内存的键值型数据库&#xff0c;对数据的读写操作都是在内存中完成&#xff0c;因此读写速度非常快&#xff0c;常用于缓存&#xff0c;消息队列、分布式锁等场景。 有以下几个特…

2022 年全国职业院校技能大赛高职组云计算正式赛卷第二场-容器云

2022 年全国职业院校技能大赛高职组云计算赛项试卷 云计算赛项第二场-容器云 目录 2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第二场-容器云 【任务 1】容器云平台搭建[5 分] 【任务 2】容器云应用部署&#xff1a; Docker Compose 编排部署[7.0…

WPF+Halcon 培训项目实战(6):目标匹配助手

前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主的提供的教程。这里只做笔记分享&#xff0c;想要源码或者教学视频可以和他联系一下。 相关链接 微软系列技术教程 WPF 年度公益课程 Halcon开发 CSD…

springcloud之通过openfeign优化服务调用方式

写在前面 源码 。 在前面的文章中我们实际上已经完成了优惠券模块微服务化的改造&#xff0c;但是其中还是有比较多可以优化和增强的地方&#xff0c;本文就先来对服务间的通信方式进行优化&#xff0c;具体就是使用openfeign来替换调原来的webclient。下面我们就开始吧&#…

C# 根据指定的类型,动态转换object数据到指定类型

封装类 namespace EFCoreDynamicCondition.Helptool {public class Helptool{public static T ConvertToType<T>(object value){try{return (T)Convert.ChangeType(value, typeof(T));}catch (InvalidCastException){// 转换失败的处理Console.WriteLine($"Convers…

Redis实现限流

1. 基于Redis的zset数据结构实现滑动窗口限流 我们可以将请求打造成一个zset数组&#xff0c;当每一次请求进来的时候&#xff0c;value保持唯一&#xff0c;可以用UUID生成&#xff0c;而score可以用当前时间戳表示&#xff0c;因为score我们可以用来计算当前时间戳之内有多少…

【Redis】八、哨兵模式

文章目录 一、概述这里的哨兵有两个作用多个哨兵 二、哨兵测试1、配置哨兵配置文件 sentinel.conf2、启动哨兵3、断开Master节点 三、哨兵模式优点&#xff1a;缺点&#xff1a; 哨兵模式的全部配置 参考&#xff1a;狂神说Java bilibili哨兵模式 一、概述 自动选取老大的模式…

在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序

如果您有 Android 设备&#xff0c;您可能会将个人和专业的重要文件保存在设备的 SD 卡上。这些文件包括照片、视频、文档和各种其他类型的文件。您绝对不想丢失这些文件&#xff0c;但当您的 SD 卡损坏时&#xff0c;数据丢失是不可避免的。 幸运的是&#xff0c;您不需要这样…

Appium+python自动化(一)- 环境搭建—上(超详解)

简介 今天是高考各地由于降水&#xff0c;特别糟糕&#xff0c;各位考生高考加油&#xff0c;全国人民端午节快乐。最近整理了一下自动化的东西&#xff0c;先前整理的python接口自动化已经接近尾声。即将要开启新的征程和篇章&#xff08;Appium&python&#xff09;。那么…

2023-12-27 语音转文字的whisper应用部署

点击 <C 语言编程核心突破> 快速C语言入门 语音转文字的whisper应用部署 前言一、部署whisper二、部署whisper.cpp总结 前言 要解决问题: 需要一款开源的语音转文字应用, 用于视频自动转换字幕. 想到的思路: openai的whisper以及根据这个模型开发的whisper.cppC应用. …

代码随想录算法训练营第三十天|332.重新安排行程、51. N皇后 、37. 解数独

332.重新安排行程 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 文档讲解&#xff1a;代码随想录 C代码&#xff1a; class Solution { public: unordered_map<string, map<string, int>> targets;bool backtrack…