C++ macro(宏)使用小结
谈起C++中的宏,我们第一个想到的应该就是“#define”,它的基本语法长得像这样:
#define macroname(para1, para2, para3, ... ,paran) macro-body
宏的声明和普通的函数声明很像,但是两者之间有本质的区别:C++函数在运行时(runtime)才执行代码段;而宏则是在预编译时期(preprocessor)执行代码段。下面简单介绍一下几个宏的应用。
一、考虑下面的代码段:
#define PLUS_ONE(x) ((x) + 1)
int x=PLUS_ONE();
>>>x=((12) + 1)
>>>x=13
这是最简单的应用,用macro-body替换macroname;和C函数不一样的是,宏是没有返回值的,本身表达式的值将作为返回值传回。
二、考虑下面的代码段:
#define x 1+2
int t=x*;
std::cout<<t<<'\n';
那么输出t的值会是什么呢?答案也许不是你期望中的9,而是7。原因很简单,#define的替换实质上是表达式的替换,将上述代码里的宏展开后将变成这样:
int t = 1 + 2 * 3; //t = 7
这种结果显然不是我们愿意看到的,而且这种错误是很难察觉的,完全没有语法错误和语义错误;不过要解决这个问题也很容易,将表达式括起来就行了:
#define x (1+2)
>>>int t = (1+2)*3=9
不过这种使用宏的方法是不推荐的,因为容易引起一些不必要且难以察觉的错误。在C++里,我们完全可以这样声明x,也能达到同样的目的:
const int x=; //声明常数推荐用const关键字
三、Preprocessor预先定义好的值;
__FILE__ :编译的文件的绝对路径;
__LINE__ :当前行号;
__TIME__ :当前时间;
__DATE__ :当前日期。
四、C语言中macro的设计初衷之一是关于内联函数。如果我们定义一个求较大值的MAX函数:
#define MAX(a,b) ((a)>(b)?(a):(b))
>>>int myInt=MAX(x,y)
>>>int myInt=((x)>(y)?(x):(y)) //上一行调用的宏将直接这样插入到代码段里
如果我们将MAX写成一个一般的函数,那么我们调用MAX将有以下两个过程:①调用名称为MAX的函数 ②将比较得到的值返回。显然在这两种方案中,macro的方案更较高效,因为它省略的函数调用的开销,直接能得到结果(相当于inline函数的用法,这里不展开讲inline了)。
五、字符串操作函数
看如下macro定义:
#define MAX(a,b) ((a)>(b)?(a):(b))
这里的参数a和b实际上都是以string的方式传递的,例如MAX(10,12)返回的是字符串"12",而不是整型的12。预处理器提供两种方式处理string类型的参数传递。
1、stringizing operator '#':返回一个C风格的字符串;
#define TEST(n) std::cout << #n << " is " << (n) << std::endl
>>>int x= 6;
>>>TEST(x*2); //std::cout << "x*2" << " is " << (x*2) << std::endl
最终得到的结果是:x*2 is 12
那么这种看似tricky的语法有什么用呢?其实,当上述C++代码被翻译成机器码时,所有和变量x相关的概念或者语句都会被“消灭”,因为变量只会存在于C++代码层;而通过stringizing operator,让我们以字符串的形式保存一部分C++源代码变得可能,这可以应用于写一些“自我诊断(纠错)”的函数中,有机会再深入介绍吧!
2、string concatenation operator '##':顾名思义,字符串连接算子:
#define TEST2(type) type ones_##type
>>>TEST2(int);
>>>int ones_type; //这个宏的功能其实就是声明一个任意类型的,如int的变量,名字叫做ones_type
这个没感觉有什么特别的用途,trick。
C++ macro(宏)使用小结的更多相关文章
- uboot中的中断macro宏
目录 uboot中的中断macro宏 引入 内存分配 流程概览 普通中断 保存现场 中断函数打印具体寄存器 恢复现场 软中断 空间获取 保存现场 附录速记 疑惑待解 title: uboot中的中断m ...
- 转 freemarker macro(宏)的使用
有人说用freemarker,但没有用到它的宏(macro),就=没有真正用过freemarker.说的就是宏是freemarker的一大特色. 宏的定义可以查看相关的文档,里面介绍得很清楚,下面来看 ...
- [Umbraco] macro(宏)在umbraco中的作用
macro在umbraco中是一个核心的应用,它是模板页中用于动态加载内容的标签(模板指令),宏可以是基于XSLT文件创建,亦可以是基于ASP.NET用户控件创建 在develop下的Macros中创 ...
- Rust 1.7.0 macro宏的复用 #[macro_use]的使用方法
Rust 1.7.0 中的宏使用范围包含三种情况: 第一种情况是宏定义在当前文件里.这个文件可能是 crate 默认的 module,也可能是随意的 module 模块. 另外一种情况是宏定义在当前 ...
- FreeMarker学习(宏<#macro>的使用)
原文链接:https://my.oschina.net/weiweiblog/blog/506301?p=1 用户定义指令-使用@符合来调用 有两种不同的类型:Macro(宏)和transform( ...
- CMake语法—普通变量与包含、宏(Normal Variable And Include、Macro)
目录 CMake语法-普通变量与包含.宏(Normal Variable And Include.Macro) 1 CMake普通变量与包含.宏示例 1.1 代码目录结构 1.2 根目录CMakeLi ...
- 用VBA宏从一个工作薄复制内容到另一个工作薄
我们项目管理有两个工作薄,一个里面有多个表,每天建一个,记录当天项目,另一个工作薄,有多个表,其中一个是所有项目汇总. 以前都是第一个工作薄一个表做完,再复制粘贴到第二个工作薄的汇总表中. 写了个VB ...
- Excel 将A表的基础数据拼接到B表中来-三种方法: ctrl+回车, VLOOKUP()函数,宏
A表 基础信息表 B表 业务信息表 将a表中的基础数据 拼接到B表的后面, 应用场景是: B表很多数据,很繁乱,名字不一定全, A表也是比较多的行,B表乱:比如有8行有李晨的,却只有3行是范仲淹的, ...
- Confluence 6 用户宏示例 - Formatted Panel
下面的用演示了如果还写一个用户宏,并在这个宏中创建一个格式化的面板,并且指定颜色.将会创建下面的面板: (Title) 注意:这个面板的标题为空,如果你没有给这个面板标题参数的话. Macro n ...
- Confluence 6 空间中的常用宏
小组空间(Team Spaces): 介绍小组:User Profile Macro 将会对 Confluence 的用户显示属性的简单摘要,属性照片,联系方式. 在你小组中分享通知和新闻:The B ...
随机推荐
- 狂屌的Windows下的定时任务工具xStarter
xStarter是一款将某些常规计算机操作自动化进行为目的的程序. 它不能为你生成word文件,但是它可以周期性地为你备份文件以保持完整性. 程序的特点有:加强的任务计划工具;在系统事件上执行任务;用 ...
- 划分树---Feed the dogs
POJ 2761 Description Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to fee ...
- Hibernate框架之Criteria查询
首先给大家说说Hibernate检索方式 Hibernate提供了5种检索对象的方式 1.导航对象图检索方式:根据已经加载的对象导航到其他对象 2.OID检索方式:按照对象的OID来检索对象 3.HQ ...
- Android5.0新特性——图片和颜色(drawable)
图片和颜色 tint属性 tint属性一个颜色值,可以对图片做颜色渲染,我们可以给view的背景设置tint色值,给ImageView的图片设置tint色值,也可以给任意Drawable或者NineP ...
- 挖掘机技术哪家强(c++实现)
描述:为了用事实说明挖掘机技术到底哪家强,组织一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入:输入在第1行给出不超过105的正整数N,即参赛人数.随后N行,每行给出一位参赛者的 ...
- js 操作ASP.NET服务器控件
js 操作ASP.NET服务器控件 在ASP.NET中使用js时,js获取DOM元素时,经常获取不到,这是因为获取的方法有误,现在介绍一方法,解决如何使用js获取ASP.NET控件在浏览器端生成htm ...
- javamail 发送邮件demo
package com.suntray.test; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.M ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q66-Q69)
Question 66You have a custom theme named MyTheme. The theme is defined in a file named MyTheme.thmx. ...
- android studio问题rendering problems no render target selected
activity_main.xml选择Design显示rendering problems no render target selected 在stackOverflow上找到了答案: You ne ...
- IOS 网络浅析-(六 网络图片获取之三方SDWebImage)
网络图片获取是大多数app所能用到的,由于实际app开发中原生api很少用到,在这里就先不介绍了,以后有时间会给大家介绍.这篇文章会给大家介绍一个三方-SDWebImage.SDWebImage 是一 ...