转 C语言预处理功能——关于字符串化和符号粘贴
2014-08-21 09:17
225 查看
http://blog.chinaunix.net/uid-20554957-id-3430791.html
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语言开发中,宏定义是一个非常有用的工具,它可以使我们的代码更容易理解,更容易维护。如查一个常量在多处被使用,且今后可能会根据不同需要而 修改的话,将其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语言预处理功能――关于字符串化和符号粘贴
- 我试图用ANSI “字符串化” 预处理操作符# 向信息中插入符号常量的值, 但它字符串化的总是宏的名字而不是它的值。
- C语言练习题:编写函数,该函数的功能是:移动字符串中的内容,移动的规则如下::把第1到第m个字符,平移到字符串的最后,把第m+1到最后的字符移到字符串的前部。例如,字符串原有的内容为ABCDEFGHI,m的值为4,移动后,字符串中的内容应该是EFGHIABCD
- C语言中关于字符数组与字符指针的本质区别
- 关于C语言中输入字符的问题
- 关于C语言中的无符号数和有符号数
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- C语言中需要加反斜杠的特殊字符符号表
- 关于C语言,字符数组中越界的两个问题
- 山东理工大学ACM平台题答案关于C语言 1176 C语言实验——删除指定字符
- C语言中关于string的字符函数
- 关于预处理的三大功能之一 —— 条件编译(ifndef)
- 关于iOS uiwebview 禁止弹出复制和粘贴功能
- 【C语言】关于宏定义中#和##符号的使用和宏定义展开问题
- C++ 把枚举变量的名称,直接当字符串使用方法 字符串化符号 #
- c语言指针的*和&两符号的功能
- C语言 ispunct() 函数—测试字符是否为标点符号或特殊符号 C语言 ispunct() 函数—测试字符是否为标点符号或特殊符号
- 玩儿转C语言:符号和字符(1)