第25课 - # 和 ## 操作符使用分析
第25课 - # 和 ## 操作符使用分析
1. # 运算符
(1)# 运算符用于在预处理期将宏参数转换为字符串,即加上双引号 (# 运算符的操作对象是宏参数)
(2)# 的转换作用是在预处理期完成的,因此只在宏定义中有效;编译器并不知道 # 的转换作用
(3)在有参宏中,# 只能和宏参数连用,不能和其它东西连用,比如 #define INC(i) {i++; #hhh} // 这个预处理器会报错,error: '#' is not followed by a macro parameter
1 #include <stdio.h> 2 3 #define STRING(x) #x // 将宏参数x转换为字符串 4 5 int main() 6 { 7 printf("%s\n", STRING(Hello World!)); // "Hello World!" 8 printf("%s\n", STRING(100)); // "100" 9 printf("%s\n", STRING(while)); // "while" 10 printf("%s\n", STRING(return)); // "return" 11 12 return 0; 13 }
gcc -E 25-1.c 查看预处理结果,可以看到宏参数转变为了字符串格式
scott@scott-ubuntu:~/c_course/ch_25$ gcc -E 25-1.c # 1 "25-1.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "25-1.c" int main() { printf("%s\n", "Hello World!"); printf("%s\n", "100"); printf("%s\n", "while"); printf("%s\n", "return"); return 0; }
【# 运算符的妙用】
1 #include <stdio.h> 2 3 // 打印被调用的函数的函数名,然后调用该函数 4 #define CALL(f,p) (printf("Call function %s\n",#f),f(p)) 5 6 int square(int n) 7 { 8 printf("Call function %s\n", __func__) 9 return n*n; 10 } 11 12 int func(int x) 13 { 14 return x; 15 } 16 17 int main() 18 { 19 int iRet = 0; 20 21 iRet = CALL(square, 4); // Call function square 22 printf("result = %d\n", iRet); // result = 16 23 24 iRet = CALL(func, 10); // Call function func 25 printf("result = %d\n", iRet); // result = 10 26 27 return 0; 28 }
2. ## 运算符
(1)## 运算符用于在预处理期粘连两个标识符 (## 运算符的操作对象是标识符)
(2)## 的连接作用是在预处理器完成的,因此只在宏定义中有效;编译器并不知道 ## 的连接作用
【## 运算符的基本用法】
1 #include <stdio.h> 2 3 #define NAME(n) name##n 4 5 int main() 6 { 7 int NAME(1); // name1; 8 int NAME(2); // name2; 9 10 NAME(1) = 1; 11 NAME(2) = 2; 12 printf("%d\n", NAME(1)); // 1 13 printf("%d\n", NAME(2)); // 2 14 15 return 0; 16 }
【## 运算符的工程应用】
1 #include <stdio.h> 2 3 /* 4 typedef struct _tag_Student Student; 5 struct _tag_Student { 6 int id; 7 char *name; 8 }; 9 */ 10 11 // 当工程中有很多结构体时,这样可以提高代码编写效率 12 #define Struct(arg) typedef struct _tag_##arg arg;\ 13 struct _tag_##arg 14 15 Struct(Student) { 16 int id; 17 char *name; 18 }; 19 20 int main() 21 { 22 Student s1; 23 Student s2; 24 25 s1.id = 0; 26 s1.name = "Scott"; 27 28 s2.id = 0; 29 s2.name = "Fugui"; 30 31 printf("s1.id = %d\n", s1.id); 32 printf("s1.name = %s\n", s1.name); 33 34 printf("s2.id = %d\n", s2.id); 35 printf("s2.name = %s\n", s2.name); 36 37 return 0; 38 }