一、字符串化操作符#
1. # 的功能:将#后面的宏参数转化成字符串。
2. 使用条件:只能用于有传入参数的宏定义中,且#必须置于宏定义体中的参数名前。
#include<stdio.h>
// s是宏参数
#define Str(s) #s //功能:使用Str(s)将s转化为字符串
int main()
{
printf(Str(HelloWorld));
return;
}
//输出:HelloWorld
3.对空格的处理
#define example1(instr) #instr
string str=example1(abc); 将会展成:string str="abc";
🥝 a、忽略传入参数名前面和后面的空格。
如:str=example1( abc ); 将会被扩展成 str="abc";
🥝 b、当传入参数名间存在空格时,编译器将自动连接各个子字符串,用每个子字符串中只一个空格连接,忽略多余一个空格。
如:str=exapme1( abc def ); 将会被扩展成 str="abc def";
4. 宏定义作为宏参数,不展开,仍然作为字符串字面信息输出。
#include <limits.h>
#include <stdio.h>
#define STR(s) #s
int main()
{
// INT_MAX是某个文件中定义的宏,
printf("int max: %s\n", STR(INT_MAX)); // 输出int max: INT_MAX
return 0;
}
二、符号连接操作符 ##
1. ## 的功能: 将前后两个标识符连接形成一个标识符。
2. 使用条件:只能用于有传入参数的宏定义中,且##必须置于宏定义体中的参数名前。
#include<stdio.h>
#define Var(x) var##x
int main()
{
int Var(1)=1,Var(2)=2,Var(3)=3;
printf("var1=%d\n",var1);
printf("var2=%d\n",var2);
printf("var3=%d\n",var3);
return 0;
}
3.注意
a、当用##连接形参时,##前后的空格可有可无。
如:#define exampleNum(n) num ## n 相当于 #define exampleNum(n) num##n
b、连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义。连接之后只是组成了一个参数名,并没有定义,因此要求这个参数名需要是已经存在或者说已经被定义了的参数或宏定义。
c、当宏参数是另一个宏时,凡宏定义中存在#或##的地方,宏参数不会再展开。
( 只有当前宏生效, 参数里的宏!不会生效 !)
#define TOW (2)
#define MUL(a,b) (a*b)
printf("%d*%d=%d/n", TOW, TOW, MUL(TOW,TOW));
这行的宏会被展开为:
printf("%d*%d=%d/n", (2), (2), ((2)*(2)));
MUL里的参数TOW会被展开为(2).
② 宏定义存在’#‘或’##'的时候(#在上方有讲解)
#include <limits.h>
#include <stdio.h>
#define A 2
#define CONS(a,b) (int)(a##e##b) //ps:##放到宏参数后面相当于一个连接 无其他作用
int main()
{
// 由于A是宏,且作为宏CONS的参数,并且宏CONS##符号,所以A不能被解引用,因此上方程序编译报错。
printf("%d\n", CONS(A, A)); // compile error 无法展开
//printf("%d\n", (int)(AeA));
return 0;
}
// 报错信息如下:
main.c: In function ‘main’:
main.c:8:22: error: ‘AeA’ undeclared (first use in this function)
8 | printf("%d\n", CONS(A, A)); // compile error 无法展开
| ^
main.c:5:26: note: in definition of macro ‘CONS’
5 | #define CONS(a,b) (int)(a##e##b) //ps:##放到宏参数后面相当于一个连接 无其他作用
| ^
main.c:8:22: note: each undeclared identifier is reported only once for each function it appears in
8 | printf("%d\n", CONS(A, A)); // compile error 无法展开
| ^
main.c:5:26: note: in definition of macro ‘CONS’
5 | #define CONS(a,b) (int)(a##e##b) //ps:##放到宏参数后面相当于一个连接 无其他作用
| ^