文中__FILE__与示例1可以参见《使用ANSI C and Microsoft C++中常用的预定义宏》

宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号。

如定义好#define STRING(x) #x之后,下面二条语句就等价。

char *pChar = "hello";

char *pChar = STRING(hello);

还有一个#@是加单引号(Charizing Operator)

#define makechar(x) #@x

char ch = makechar(b);与char ch = 'b';等价。

但有小问题要注意,宏中遇到#或##时就不会再展开宏中嵌套的宏了。什么意思了?比如使用char *pChar = STRING(__FILE__);虽然__FILE__本身也是一个宏,但编译器不会展开它,所以pChar将指向"__FILE__"而不是你要想的形如"D:\XXX.cpp"的源文件名称。因此要加一个中间转换宏,先将__FILE__解析成"D:\XXX.cpp"字符串。

定义如下所示二个宏:

#define _STRING(x) #x

#define STRING(x) _STRING(x)

再调用下面语句将输出带""的源文件路径

char* pChar = STRING(__FILE__);

printf("%s %s\n", pChar, __FILE__);

可以比较下STRING(__FILE__)与__FILE__的不同,前将带双引号,后一个没有双引号。

再讲下##的功能,它可以拼接符号(Token-pasting operator)。

MSDN上有个例子:

#define paster( n ) printf( "token"#n" = %d\n", token##n )

int token9 = 100;

再调用  paster(9);宏展开后token##n直接合并变成了token9。整个语句变成了

printf( "token""9"" = %d", token9 );

在C语言中字符串中的二个相连的双引号会被自动忽略,于是上句等同于

printf("token9 = %d", token9);。

即输出token9 = 100

有了上面的基础后再来看示例1

#define WIDEN2(x) L ## x

#define WIDEN(x) WIDEN2(x)

#define __WFILE__ WIDEN(__FILE__)

wchar_t *pwsz = __WFILE__;

第一个宏中的L是将ANSI字符串转化成unicode字符串。如:wchar_t *pStr = L"hello";

再来看wchar_t *pwsz = __WFILE__;

__WFILE__被首先展开成WIDEN(__FILE__),再展开成WIDEN2("__FILE__表示的字符串"),再拼接成 L"__FILE__表示的字符串" 即L"D:\XXX.cpp" 从而得到unicode字符串并取字符串地址赋值给pwsz指针。

在VC中_T(),TEXT ()也是用的这种技术。

在tchar.h头文件中可以找到:

#define _T(x)       __T(x)

#define __T(x)     L ## x

在winnt.h头文件中可以找到

#define TEXT(quote) __TEXT(quote)   // r_winnt

#define __TEXT(quote) L##quote     // r_winnt

因此不难理解为什么第三条语句会出错error C2065: 'LszText' : undeclared identifier

wprintf(TEXT("%s %s\n"), _T("hello"), TEXT("hello"));

char szText[] = "hello";

wprintf(TEXT("%s %s\n"), _T(szText), TEXT(szText));

而将"hello"定义成宏后就能正确运行。

#define SZTEXT "hello"

wprintf(TEXT("%s %s\n"), _T(SZTEXT), TEXT(SZTEXT));

注:由于VC6.0默认是ANSI编码,因此要先设置成unicode编码,在project菜单中选择Setting,再在C/C++标签对话框中的Category中选择Preprocessor。再地Preprocessor definitions编辑框中将_MBCS去掉,加上_UNICODE,UNICODE。

转载于:https://www.cnblogs.com/cyjsegull/p/4526296.html

C,C++宏中#与##的讲解相关推荐

  1. 【转】C,C++宏中#与##的讲解

    转自:C,C++宏中#与##的讲解 - MoreWindows - 博客园 文中__FILE__与示例1可以参见<使用ANSI C and Microsoft C++中常用的预定义宏> 宏 ...

  2. c语言 macro,C/C++中宏/Macro的深入讲解

    前言 宏(Macro)本质上就是代码片段,通过别名来使用.在编译前的预处理中,宏会被替换为真实所指代的代码片段,即下图中 Preprocessor 处理的部分. C/C++ 代码编译过程 - 图片来自 ...

  3. 有声专栏-宏基因组专业词汇讲解

    有声专栏-宏基因组专业词汇讲解开播了,点击上方播放本词条的有声版.也可在喜马拉雅FM中搜索<宏基因组>持续收听本专辑更新. 对于刚接触宏基因组的同学,想必有很多概念不明白,那么接下来就让我 ...

  4. C/C++常用宏定义,注意事项,宏中#和##的用法

    总结下宏和函数的不同之处,以供大家写代码时使用,这段总结摘自<C和指针>一书. 当然宏定义非常重要的,它可以帮助我们防止出错,提高代码的可移植性和可读性等. 下面列举一些成熟软件中常用得宏 ...

  5. 有声专栏-宏基因组专业词汇讲解——001宏基因组

    宏基因组专业词汇讲解--001宏基因组 有声专栏-宏基因组专业词汇讲解开播了,点击上方播放本词条的有声版.也可在喜马拉雅FM中搜索<宏基因组>持续收听本专辑更新. 对于刚接触宏基因组的同学 ...

  6. 创建物化视图commit_oracle 中物化视图讲解

    oracle 中物化视图讲解 oracle中的物化视图首先需要创建物化视图日志,oracle根据用户创建的物化视图日志来创建物化视图日志表,物化视图日志表名称为mlog$_基表名,如果表名超过20位, ...

  7. php视图,thinkPHP框架中视图的讲解(附代码)

    这篇文章给大家介绍的内容是关于thinkPHP框架中视图的讲解(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. thinkPHP中有一个方法和display()相似,fetc ...

  8. [c、c++]宏中#和##的用法(zz)

    http://blog.csdn.net/blackbillow/article/details/3850587 [c.c++]宏中"#"和"##"的用法(zz ...

  9. python保存运行结果下次使用_将python运行结果保存至本地文件中的示例讲解

    一.建立文件,保存数据 1.使用python中内置的open函数 打开txt文件 #mode 模式 #w 只能操作写入 r 只能读取 a 向文件追加 #w+ 可读可写 r+可读可写 a+可读可追加 # ...

最新文章

  1. A and B and Lecture Rooms CodeForces - 519E LCA+dfs序
  2. linux下Makefile中包含有shared library动态链接库文件时候的简单例子
  3. python爬虫教程pdf-《Python爬虫开发与项目实战》pdf完整版
  4. 关于Go语言在服务端做Restful接口和socket通信
  5. ThreadLocal原理及用法详解
  6. 如果公司的网络屏蔽了游戏【英雄联盟】的链接请求,使用这种方法玩游戏。
  7. 背景图层和普通图层的区别_新手如何在PS中创建图层?不容错过的7种方法,你值得学习...
  8. 算法复习第五章贪心法
  9. 初学嵌入式STM32基础下选哪款开发板适合学习
  10. PPTP与Open×××区别
  11. python中文意思-请问在python中**是啥什么意思?
  12. fw313r虚拟服务器,迅捷FW313R无线wifi怎么设置上网 - falogincn登录页面
  13. excel锁定第一行_将Excel标题行锁定在适当的位置
  14. KS检验-如何理解KS检验中的p-value
  15. Python基础笔记
  16. latex学习3:教你如何在word中像LaTex那样打公式
  17. vue实现微信扫码拨打电话
  18. python opcua使用教程
  19. ServiceMesh到底好不好
  20. gc java ibm_gc分析工具(IBM Pattern Modeling and Analysis Tool for Java Garbage Collector)

热门文章

  1. php繁体输出,PHP输出控制功能在简繁体转换中的应用
  2. php有哪些高级扩展,php扩展有哪些
  3. 释放tcp连接的命令是_最实用的6个网络命令,网络故障不求人
  4. android listview countdowntimer,Android-ListView中的CountDownTimer随机闪烁
  5. win7装mysql一直未响应6_win7重装mysql最后一步无响应解决方法
  6. Android usb 权限广播,android10.0 USB弹窗权限流程解析
  7. java 10进制转 000x_java 如何把 00 转换成 0x00 或者 10 转换成 0x10
  8. 1099: 角谷猜想(多实例测试)
  9. 《软件需求分析(第二版)》第 3 章——需求工程的推荐方法 重点部分总结
  10. teechart mysql_TeeChart 的应用