C 语言宏定义
1、例子如下:
#define PRINT_STR(s) printf("%s",s.c_str())
string str = "abcd";
PRINT_STR(str);
结果如下:abcd
2、现在我期望打印出,str=abcd, 容易想到的解决办法是:
#define PRINT_STR(s) printf("s" "=" "%s",s.c_str())
打印出来的结果是 s=abcd,不是我们所期望的,想一下,为什么?
在这里,编译器不认为"s"中s就是前面的s,不进行替换。如果进行替换,那么"%s" 也就换成了"%str",这显然错误。
3、怎么解决上面的问题?使用另一种方式,也就是#(字符串替换,前后加上双引号),如下:
#define PRINT_STR(s) printf(#s "=" "%s",s.c_str())
可以认为,对于#s,编译器对s进行替换,并且在s前后加上双引号

4、考虑下面的情况,
int token8 = 102;
PRINT_TOKEN(8);
期望打印出 token8,容易想到的解决办法是:
#define PRINT_TOKEN(d) printf("%d",tokend)
这样是明显错误的,编译器认为tokend是一个整体,不可能只去替换d,怎么解决?
5、怎么解决这个问题?要进行替换,必须把d隔离出来,而一旦隔离出来,替换是可以了,但是不能与token合在一起构成一个变量了。
这就要使用##(宏连接符),可以认为## 进行分割,分割后替换,替换之后,再把##去除,如下:
#define PRINT_TOKEN(d) printf("%d",token##d)

6、一个# 字符串替换,两个# 宏连接符

C 语言宏定义的更多相关文章

  1. 将C语言宏定义数值转换成字符串!

    将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...

  2. C语言 宏定义之可变参数

    可变参数宏定义 C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏.可变参数宏就像下面这个样子: #define dbgprint(. ...

  3. C语言宏定义时#(井号)和##(双井号)的用法1

    #在英语里面叫做 pound 在C语言的宏定义中,一个#表示字符串化:两个#代表concatenate 举例如下: #include <iostream> void quit_comman ...

  4. C语言宏定义时#(井号)和##(双井号)的用法

    C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...

  5. c语言宏定义

    一. #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时 ...

  6. C语言宏定义相关

    写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义......1,防止一个头文件被重复包含#ifndef COMDEF_H# ...

  7. 转:C语言宏定义时#(井号)和##(双井号)的用法

    转自:http://www.cnblogs.com/welkinwalker/archive/2012/03/30/2424844.html#2678295 #在英语里面叫做 pound 在C语言的宏 ...

  8. c语言宏定义#define的理解与资料整理

    1. 利用define来定义 数值宏常量 #define 宏定义是个演技非常高超的替身演员,但也会经常耍大牌的,所以我们用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码就就都认 ...

  9. C程序设计语言--宏定义

    C语言中的宏定义 C语言中的宏定义也叫做预处理命令,预处理命令是C语言本身的组成部分,不能直接对它们进行编译. 1.基本概念: 1>预处理不是C语句,是在编译前进行的 2>预处理功能主要用 ...

随机推荐

  1. Java学习笔记八(反射)

    1.介绍 反射为Java程序在执行时提供了动态的能力.利用反射能够在执行时对程序进行动态的控制.本篇博客着重解说一下Java中的反射. 2.Class类的使用 在Java执行过程中,每一个类被载入后都 ...

  2. Revit API布置卫浴装置

    //放置卫浴装置 [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public clas ...

  3. delphi Image 处理

    procedure ResizeBmp(Src,Dst:String);var SrcBM,DstBM:TBitMap; Rect:TRect; NewW,NewH,PicW,PicH:Integer ...

  4. Make the DbContext Ambient with UnitOfWorkScope(now named DbContextScope by mehdime)

    The Entity Framework DbContext (or LINQ-to-SQL DataContext) is a Unit Of Work implementation. That m ...

  5. Android 程序目录介绍

    还是回到 Eclipse 中,首先展开 HelloWorld 项目,你会看到如图 1.17 所示的目录结构. 图   1.17 一开始看到这么多陌生的东西,你一定会感到有点头晕吧.别担心,我现在就对上 ...

  6. Windows Phone本地数据库(SQLCE):7、Database mapping(翻译)

    这是“windows phone mango本地数据库(sqlce)”系列短片文章的第七篇. 为了让你开始在Windows Phone Mango中使用数据库,这一系列短片文章将覆盖所有你需要知道的知 ...

  7. C#编程(四十)----------运算符重载

    运算符重载 所谓的运算符重载是指允许用户使用用户定义的类型编写表达式的能力. 例如,通常需要编写类似与以下内容的代码,入江两个数字相加,很明显,sum是两个数字之和. int i=5,j=4; int ...

  8. ArcGIS Engine Maplex Label(标注)使用一例(转)

    /// <summary> /// MaplexEngine标注 /// </summary> /// <param name="pGeoFeatLyr&quo ...

  9. 详解Java Spring各种依赖注入注解的区别

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Comp ...

  10. 找不到"javax.servlet.annotation.WebServlet"解决方法

    以前创建的一个项目,打开的时候总是报错. import javax.servlet.annotation.WebServlet; 后来想起当时这个项目是发布在tomcat7.0下面的, 也就是说当时这 ...