1. # 运算符

(1) # 运算符用于在预处理期 将宏参数转换为字符串,即加上双引号 (# 运算符的操作对象是宏参数)

(2) # 的转换作用是在预处理期完成的,因此只在宏定义中有效;编译器并不知道 # 的转换作用

(3)在有参宏中, # 只能和宏参数连用,不能和其它东西连用,比如 #define  INC(i)  {i++; #hhh } // 这个预处理器会报错,error: '#' is not followed by a macro parameter

 1 #include <stdio.h>
 3 #define STRING(x)  #x    // 将宏参数x转换为字符串
 5 int main()
 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"
12     return 0;

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>
 3 // 打印被调用的函数的函数名,然后调用该函数
 4 #define CALL(f,p) (printf("Call function %s\n",#f),f(p))
 6 int square(int n)
 8     printf("Call function %s\n", __func__)
 9     return n*n;
10 }
12 int func(int x)
13 {
14     return x;
15 }
17 int main()
18 {
19     int iRet = 0;
21     iRet = CALL(square, 4);  // Call function square
22     printf("result = %d\n", iRet);  // result = 16
24     iRet = CALL(func, 10);   // Call function func
25     printf("result = %d\n", iRet);  // result = 10
27     return 0;

2. ## 运算符

(1)## 运算符用于在预处理期粘连两个标识符        (## 运算符的操作对象是标识符)

(2)## 的连接作用是在预处理器完成的,因此只在宏定义中有效;编译器并不知道 ## 的连接作用

【## 运算符的基本用法】

 1 #include <stdio.h>
 3 #define NAME(n) name##n
 5 int main()
 7     int NAME(1); // name1;
 8     int NAME(2); // name2;
10     NAME(1) = 1;
11     NAME(2) = 2;
12     printf("%d\n", NAME(1));  // 1
13     printf("%d\n", NAME(2));  // 2
15     return 0;

【## 运算符的工程应用】

 1 #include <stdio.h>
 3 /*
 4 typedef struct _tag_Student Student;
 5 struct _tag_Student {
 6     int id;
 7     char *name;
 8 };
 9 */
11 // 当工程中有很多结构体时,这样可以提高代码编写效率
12 #define Struct(arg) typedef struct _tag_##arg arg;\
13                             struct _tag_##arg
15 Struct(Student) {
16     int id;
17     char *name;
18 };
20 int main()
21 {
22     Student s1;
23     Student s2;
25     s1.id = 0;
26     s1.name = "Scott";
28     s2.id = 0;
29     s2.name = "Fugui";
31     printf("s1.id = %d\n", s1.id);
32     printf("s1.name = %s\n", s1.name);
34     printf("s2.id = %d\n", s2.id);
35     printf("s2.name = %s\n", s2.name);
37    return 0;