C中宏展开问题
C中宏展开问题
简单记录一下碰到的问题。
#define STR(x) #x
我们知道使用上面的宏可以将x转换为字符串"x"。
但是如果这样用:
#define NUM 3
#define STR(x) #x
STR(NUM) --> 实际输出为:"NUM".
这是为啥呢?C99标准中有一段话:
... After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded...
简单解释一下这段话的意思。在C中类函数的宏定义会在“调用”的时候将其能展开的全部展开,除非(unless)宏定义中出现#或##.也即,上面的STR(x)中的x是不会展开的。为了使其展开,必须添加一个助手宏。
解决方法:
#define NUM 3
#define STR(x) #x
#define XSTR(x) STR(x) //添加一个助手宏
XSTR(NUM) --> 实际输出为:"3".
添加一个助手宏XSTR(x),在XSTR(x)宏中就不存在#或者##了,因此STR和x都会展开。
C中宏展开问题的更多相关文章
- C宏展开的几个注意事项
前阵子仔细重新研究了一下C的宏展开.总结起来,有以下几个主要规则: 每次宏展开的结果会被重复扫描,直到没有任何可展开的宏为止. 每展开一个宏,都会记住这次展开,在这个宏展开的结果及其后续展开中,不再对 ...
- 一个C语言宏展开问题
转自一个C语言宏展开问题 一个令人比较迷惑的问题,学C语言好多年,今天终于搞明白,记之. ------------------------------------------------------- ...
- c语言 预处理的使用 宏展开下的#,##
1. #include 包含头文件 2.define 宏定义(可以理解为替换,不进行语法检查) 写法 #define 宏名 宏体 加括号 #define ABC (5+3) #define AB ...
- C# 实例解释面向对象编程中的开闭原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
- WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)
最近在做一个winform的小软件(抢票的...).登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是 ...
- 【解答】关于内核中没开MMU之前的虚拟地址物理地址转换问题
1. 内核没开MMU之前有虚拟地址吗?没有MMU哪来的虚拟地址? 答:有,由于载入时地址和执行时地址不同导致的没打开MMU之前也会有虚实地址问题. 2. 载入时地址和执行时地址什么差别.为什么有这样的 ...
- win10中查看开关机时间及查看admin的RID的方法
原文链接: https://www.toutiao.com/i6772133439593251339/ 打开系统的注册表 键盘输入win+r组合键出现运行窗口命令 输入regedit 按回车键,进入注 ...
- 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)
相信使用Windows Server2008的朋友都遇到过这种情况,用IE打开网站时会弹出“Internet Explorer增强安全配置正在阻止来自下列网站的此应用程序中的内容”的对话框.如下图所示 ...
- AndroidStudio2.2 Preview3中NDK开发之CMake和传统 JNI在目录结构和配置文件上的区别(转载)
自从AndroidStudio更新到2.2,就有了CMake和传统JNI两种开发NDK的方法,主要就是在目录结构和build.gradle上的区别,下面我们将分别介绍目录区别和build.gradle ...
随机推荐
- XML与DataSet相互转换,DataSet查询
以FileShare.Read形式读XML文件: string hotspotXmlStr = string.Empty; try { Stream fileStream = new FileStre ...
- Jupyter增加内核
本例的Jupyter安装在Python3下,以增加Python2内核为例. 首先确认在Python3下已安装了内核: ipython kernel install --user #or python3 ...
- VC中常用的宏[转]
我们在VS环境中开发的时候,会遇到很多宏定义,这些宏可以应用到代码中,或用于编译.工程选项等设置,总之是我们开发中必不可少的工具,有必要做一个总结.有些宏是C/C++定义的,有些宏是VC环境预定义的. ...
- NLog使用总结
一.代码调用方式: public static readonly Logger Logger = LogManager.GetCurrentClassLogger(); Logger .Trac ...
- zookeeper的安装和启动
最近的手上一个项目要用到dubbo,顺便研究下zookeeper 1.下载 下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/,下载解压到D:\t ...
- js 判断pc与手机
var u = navigator.userAgent; if ((u.indexOf('Mac') > -1 || u.indexOf('Windows') > -1) &&am ...
- How to log in to Amazon EC2 using PEM format from SecureCRT
SecureCRT requires both a private and a public key. Use the supplied key.pem file from EC2 here as y ...
- VS 统计代码行数
使用正则表达式 : ^:b*[^:b#/]+.*$ 简单说明如下: ^:行头 $:行尾 +:一个或多个 *:0个或多个 :b:表示空白,匹配空格或者制表符 # 表示后面是include,/表示注 ...
- 【转】Delphi多线程学习(9):多线程数据库查询(ADO)
原文:http://www.cnblogs.com/djcsch2001/articles/2382559.html ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用 ...
- iOS开发——语法OC篇&Block回顾
Block回顾 这里知识简单介绍一下关于Block的语法,如果你觉得这里很简单或者想学习更深入的的使用清查看记者之前写的使用block传值和高级Block使用: http://www.cnblogs. ...