C宏定义中的##,#,#@用法介绍
关于字符串化和符号粘贴
在C语言开发中,宏定义是一个非常有用的工具,它可以使我们的代码更容易理解,更容易维护。如查一个常量在多处被使用,且今后可能会根据不同需要而 修改的话,将其define一下那是再好不过了。除此之外,宏定义还有其他的功能,了解它,将更好地辅助我们开发C程序。先看个例子 #define Conn(x,y) x##y #define ToString(x) #x #define ToChar(x) #@x 这几个宏定义中分别用到了“##”、“#”,“#@”它们的功能分别是: 1、粘接操作符##--连接两个宏名,注意所连接的是宏名,而不是其所指代的值; 如int Conn(a,b);定义了一个int型变量ab,以后可以直接调用ab,而不必采用Conn(a,b)的形式; printf(Conn("ab","cd"));输出结果为:abcd 但是: #define M 0 #define var(x) Var_##x ... int var(M);//此处定义了什么? 根据ANSI/ISO C,##操作符只是简单地粘接两个宏名,则int var(M)定义的应该就是Var_M,据测试,这一点是没有问题的。但在一些比较古老的C编译环境中,也有可能定义的是Var_0,比如在TC 2.0中测试发现“Var_0=0”可编译通过,而“Var_M=0”出现ERROR。 2、字符串化操作符#--将宏名转化为字符串 如printf(ToString(var1));输出结果为:var1。var1可以是一个已定义的变量名,也可以是一个从未出现的字符组合 类似地,若有: #define STR 0 ... printf(Tostring(STR));// 当前流行编译环境会输出STR,而TC 2.0则会输出0。 3、字符化操作#@--将宏名转化为字符,注意:早期编译器可能不支持 如: char c; c = ToChar(1);//c = '1' c = ToChar(a);//c = 'a' 如果提供的宏中不止一个字符(注意,不能超过4个,否则编译器报错),则转化结果为最后一个字符,如 c = ToChar(abc);//c = 'c' c = ToChar(abcd);//c= 'd' c = ToChar(abcde);//ERROR 总结一下,关于其用法是自己总结的,肯定不全。 1、使用中遵循ANSI C中规定,但要记得编译通不过是可能是早期编译器不支持C标准的问题; 2、##操作可应用在变量定义中,若程序开发中遇到要定义一大堆变量,且这些变量具有相同的前缀时,##很显得尤为重要,它可以使代码更加整洁,且减少了出错的机率。如果一旦后来发现需要批量修改变量前缀,你会庆幸自己使用了这么一件利器; 3、#操作符可用于调试时将变量名输出,可配合##一起使用,如定义#define CHECK_VAR(x,fmt) printf(#x " = " #fmt "\n", x),则CHECK_VAR(var1,%d)相当于printf("var = %d\n", var1); Tips: 1、ANSI C中规定若宏定义名出现在引号(' '或" ")中,则不进行替换,但有些早期编译器的处理可能有所不同,如#define CTRL(c) (‘c’ & 37),按照标准CTRL(d)被扩展成('c' & 37)。显然,这没有完成作者的本意,它在某些编译器下碰巧能工作不过是个意外,实际使用中应避免。 2、字符串的连接不必使用##这么麻烦,实际中两个字符串常量可以直接写到一起,如printf("ab""cd")输出abcd。或在使 用##宏定义时,可以用printf(ToString(str) "\n");输出字符串后换行,以前不敢这样用,后来试验了下发现还比较好使,当然直接用puts也可完成同样功能。 3、若要使#或##转换的是宏字符常量的值也不是其名字,可以使用间接方法,如: #define ToString(x) #x #define Xstr(x) ToString(x) #define STR1 STR2 ... printf(Xstr(STR1));//输出结果是STR2而非STR1 |
C宏定义中的##,#,#@用法介绍相关推荐
- 巧用c语言宏定义实现自动注释调试代码,C语言宏定义中的特殊用法
C宏定义中的特殊用法 在分析一些C源码时,经常会遇到各种宏定义操作,本文即总结一下C语言宏定义中常见的预定义宏.调试宏:宏的条件编译用法及特殊的宏关键字用法. #undef 限定宏的作用域 一般来讲宏 ...
- #define宏定义中的#,##,@#,\ 这些符号的神奇用法
C/C++ 宏命令的神奇用法. 先看下面三条语句: #define Conn(x,y) x##y #define ToChar(x) #@x #define ToString(x) #x 1 2 3 ...
- do...while(0)在宏定义中的巧妙用法
大家都知道,do-while(condition)可以表示循环,但你有没有遇到在一些宏定义中可以不用循环的地方,也用到了 do-while.比如: #define DELETE_POINTER(p) ...
- 宏定义中的 ## ... __VA_ARGS__
宏定义中的##操作符和... and _ _VA_ARGS_ _ 1.Preprocessor Glue: The ## Operator 预处理连接符:##操作符 Like the # operat ...
- javascript中in用法介绍
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 数据库 SQLServer中GUID用法介绍
数据库 SQLServer中GUID用法介绍 1.NEWID用法 NEWID()作用是生成无顺序的GUID字符串.用法如下: SELECT NEWID() --生成36位的GUID SELECT RE ...
- CC#中List用法介绍详解学习通http://www.bdgxy.com/roundWorker类用法总结学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- #与##在宏定义中的--宏展开
#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int m ...
- define宏定义中的#,##,@#及\符号
define宏定义中的#,##,@#及\符号 在#define中,标准只定义了#和##两种操作.#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串. 1.# (string ...
最新文章
- 西南民族大学计算机基础技能应用培训基地,计科学院第九期Office应用培训开班典礼顺利举办...
- Java程序执行过程
- Docker 私有仓库 Harbor registry 安全认证搭建 [Https]
- mysql connector安装教程_通过安装MySQL Connector/Net实现VS2017 C#编程连接MySQL数据库-网络教程与技术
-亦是美网络...
- 最长递增子序列问题合集
- PWN-PRACTICE-BUUCTF-3
- 阿里P8架构师谈:Dubbo的详细介绍、设计思路、以及4大适用场景
- SpaceX提交星链项目修订申请,计划用星际飞船发射3万颗卫星
- 在CF卡上建立文件系统和安装引导加载程序
- api调用实例python_调用阿里云API 的demo示例(java/python)
- 使用OpenCV获取图像中某一点的像素值和修改某一点的像素值
- 考计算机一级用什么软件学,大学计算机一级考试用的是什么word软件
- Go开发关键技术指南
- 机器学习:心血管疾病数据分析
- 人工智能的历史(History of artificial intelligence)
- L Norms 范数
- excel中求某个日期是第几周
- java通过调用鼠标模拟自动添加微信好友
- 2020-03-10
- linux 下的文本处理——除去重复行uniq命令