C,C++宏中#与##的讲解

文中__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 pastern ) 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(xWIDEN2(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

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

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

相关文章

int?id与id??1 的意思

http://blog.csdn.net/jingmeifeng/article/details/24710143 int? id 表示id是可以为null的整型 跟Nullable<int> id 是一样的 id ?? 1等于 idnull?1:id;

彻夜怒肝!Spring Boot+Sentinel+Nacos高并发已撸完,快要裂开了!

很多人说程序员是最容易实现财富自由的职业&#xff0c;也确实&#xff0c;比如字节 28 岁的程序员郭宇不正是从普通开发一步步做起的吗&#xff1f;回归行业现状&#xff0c;当开发能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。最近我也一直在思考这个…

java中get接口示例_Java LocalDateTime类| 带示例的get()方法

java中get接口示例LocalDateTime类的get()方法 (LocalDateTime Class get() method) get() method is available in java.time package. get()方法在java.time包中可用。 get() method is used to get the value for the given field from this date-time object. get()方法用于…

湖南多校对抗5.24

据说A,B,C题都比较水这里就不放代码了 D:Facility Locations 然而D题是一个脑经急转弯的题&#xff1a;有m行&#xff0c;n列&#xff0c;每个位置有可能为0&#xff0c;也可能不为0&#xff0c;问最多选K行是不是可以使得每一列都至少有一个0&#xff0c;其中代价c有个约束条件…

PPT演讲计时器

下载 GitHub 源码地址 如果访问不到的话&#xff0c;可以从百度盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bK4sug-eK85fmPgi9DzhcA 提取码&#xff1a;0vp3 文件&#xff1a;VB.Equal.Timer-VB计时器软件-绿色无残留 写在前面 转眼也工作了两年了&…

2万字!66道并发面试题及答案

我花了点时间整理了一些多线程&#xff0c;并发相关的面试题&#xff0c;虽然不是很多&#xff0c;但是偶尔看看还是很有用的哦&#xff01;话不多说&#xff0c;直接开整&#xff01;01 什么是线程&#xff1f;线程是操作系统能够进⾏运算调度的最⼩单位&#xff0c;它被包含在…

stl向量_如何在C ++ STL中将数组元素复制到向量?

stl向量Given an array and we have to copy its elements to a vector in C STL. 给定一个数组&#xff0c;我们必须将其元素复制到C STL中的向量。 将数组元素复制到向量 (Copying array elements to a vector) In C STL, we can copy array elements to a vector by using…

YoloV8的目标检测推理

YoloV8的目标检测推理 原始的YoloV8封装的层次太高&#xff0c;想要为我们所用可能需要阅读很多API&#xff0c;下面给出比较简单的使用方式 导入所需的库 os&#xff1a;用于操作文件系统。cv2 (OpenCV)&#xff1a;用于图像处理。numpy&#xff1a;提供数学运算&#xff0…

【翻译】从Store生成Checkbox Group

原文&#xff1a;Ext JS: Generating a Checkbox Group from a StoreExt JS的checkbox group可以用来将复选框组合成一个单一的逻辑字段。由于复选框时不时需要动态的从Store中生成&#xff0c;因而&#xff0c;如果将store绑定到扩展类&#xff0c;就最好不过了。以下是第一次…

25种代码坏味道总结+优化示例

前言什么样的代码是好代码呢&#xff1f;好的代码应该命名规范、可读性强、扩展性强、健壮性......而不好的代码又有哪些典型特征呢&#xff1f;这25种代码坏味道大家要注意啦1. Duplicated Code &#xff08;重复代码&#xff09;重复代码就是不同地点&#xff0c;有着相同的程…

滚动照片抽奖软件

CODE GitHub 源码 1、女友说很丑的一个软件 说个最近的事情&#xff0c;女友公司过年了要搞活动&#xff0c;需要个抽奖的环节&#xff0c;当时就问我能不能给做一个&#xff0c;正好我也没啥事儿&#xff0c;就在周末的时候用C#做了一个&#xff0c;虽然派上用场了&#xf…

Java即时类| 带示例的compareTo()方法

即时类compareTo()方法 (Instant Class compareTo() method) compareTo() method is available in java.time package. compareTo()方法在java.time包中可用。 compareTo() method is used to compare this Instant object to the given object. compareTo()方法用于将此Instan…

11个小技巧,玩转Spring!

前言最近有些读者私信我说希望后面多分享spring方面的文章&#xff0c;这样能够在实际工作中派上用场。正好我对spring源码有过一定的研究&#xff0c;并结合我这几年实际的工作经验&#xff0c;把spring中我认为不错的知识点总结一下&#xff0c;希望对您有所帮助。一 如何获取…

MFC中的几种播放声音的方法

一&#xff0e;播放声音文件的简单方法  在VC 中的多媒体动态连接库中提供了一组与音频设备有关的函数。利用这些函数可以方便地播放声音。最简单的播放声音方法就是直接调用VC中提供的声音播放函 数BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound(…

标志枚举的使用

标志枚举的使用大多是在标记多重状态&#xff0c;比如说文件的属性&#xff1a;只读&#xff0c;可写&#xff0c;隐藏&#xff0c;系统文件等相关属性&#xff0c;都对应相应的标志位&#xff0c;如果在C#中想实现自己的标志枚举&#xff0c;也是可以的&#xff0c;下文是亲身…

duration java_Java Duration类| 带示例的getUnits()方法

duration java持续时间类getUnits()方法 (Duration Class getUnits() method) getUnits() method is available in java.time package. getUnits()方法在java.time包中可用。 getUnits() method is used to get the List object that contains the units of seconds and Nanos …

synchronized 的超多干货!

synchronized 这个关键字的重要性不言而喻&#xff0c;几乎可以说是并发、多线程必须会问到的关键字了。synchronized 会涉及到锁、升级降级操作、锁的撤销、对象头等。所以理解 synchronized 非常重要&#xff0c;本篇文章就带你从 synchronized 的基本用法、再到 synchronize…

团队项目—第二阶段第三天

昨天&#xff1a;快捷键的设置已经实现了 今天&#xff1a;协助成员实现特色功能之一 问题&#xff1a;技术上遇到了困难&#xff0c;特色功能一直没太大的进展。网上相关资料不是那么多&#xff0c;我们无从下手。 有图有真相&#xff1a; 转载于:https://www.cnblogs.com/JJJ…

C# struct 装箱拆箱例子

值类型&#xff1a;拆箱、装箱 struct是值类型 struct和class的区别 类是引用类型&#xff0c;struct是值类型在托管堆上创建类的实例&#xff0c;在栈上创建struct实例类实例的赋值&#xff0c;赋的是引用地址&#xff0c;struct实例的赋值&#xff0c;赋的是值类作为参数类…

stl min函数_std :: min_element()函数以及C ++ STL中的示例

stl min函数C STL std :: min_element()函数 (C STL std::min_element() function) min_element() function is a library function of algorithm header, it is used to find the smallest element from the range, it accepts a container range [start, end] and returns a…