C语言学习笔记--#和##操作符
1. #运算符
(1)#运算符用于在预处理期将宏的参数转换为字符串
(2)#的转换作用是在预处理期完成的,因此只在宏定义中有效,即其他地方不能用#运算符
(3)用法:#define STRING(x) #x
printf("%s\n",STRING(Hello World!));//注意,Hello World!不加引号!
#include <stdio.h> #define STRING(x) #x int main() { //注意宏参数不用加引号,#运算符在宏替换时会自动加上去 printf("%s\n",STRING(Hello World!)); //"Hello World!" printf("%s\n",STRING(100)); //"100" printf("%s\n",STRING(while)); //"while" printf("%s\n",STRING(return)); //"return" return 0; }
#运算符的妙用
#include <stdio.h> //注意宏后面的为逗号表达式,返回的是第 1 个表达式的值 //该宏最大的用处在于,可以输出被调用的函数的名称 #define CALL(f,p) (printf("Call function %s\n",#f),f(p)) int square(int n) { return n*n; } int func(int x) { return x; } int main() { int iRet = 0; //将函数名称作用宏参数,利用#运算符将这个名称转为字符串输出 //同时,逗号表达式最后一个式子调用相应的函数 iRet = CALL(square,4); printf("result = %d\n",iRet);//输出函数名,并调用函数 iRet = CALL(func,10); printf("result = %d\n",iRet);//输出函数名,并调用函数 return 0; }
2. ##运算符
(1)##运算符用于在预处理期粘连两个标识符
(2)##的连接作用是在预处理期完成的,因此只在宏定义中有效。
(3)编译器不知道##的连接作用
(4)用法:
#define CONNECT(a,b) a##b
int CONNECT(a,1); //int a1;
a1 = 2;
#include <stdio.h> #define NAME(n) name##n int main() { int NAME(1); //name1; int NAME(2); //name2; NAME(1) = 1; //name1 = 1; NAME(2) = 2; //name2 = 2; printf("%d\n",NAME(1)); printf("%d\n",NAME(2)); return 0; }
##运算符的工程应用
#include <stdio.h> //该宏可以方便定义结构体,并给结构体命名。 //省去每次在定义结构体时,都要重复地写上 //typedef struct ....之类的相同代码 #define STRUCT(type) \ typedef struct _tag_##type type;\ struct _tag_##type //定义结构体,并命名为 Student STRUCT(Student) { char* name;int id; }; int main() { Student s1; Student s2; s1.name = "s1"; s1.id = 1; s2.name = "s2"; s2.id = 2; printf("s1.name = %s\n",s1.name); printf("s1.id = %d\n",s1.id); printf("s2.name = %s\n",s2.name); printf("s2.id = %d\n",s2.id); return 0; }
参考资料:
www.dt4sw.com
http://www.cnblogs.com/5iedu/category/804081.html