C语言的宏定义中#和##使用与区别

解释

#:“字符串化”,把#后面的参数变为 字符串

##:连接,把##前面和后面的参数连接在一起

举例

#include <stdio.h>

// 转字符串的宏定义 
#define		STR(s)		#s
// 连接的宏定义 
#define		CON(a,b)	(a##_love_##b)

int main()
{
    
    

	printf("After STR: %s\n",STR(Hello));
	
	printf("After CON: %s\n",CON(I,you));
	
	return 0;
}
  • 被展开成为:

    printf("After STR: %s\n","Hello");

    printf("After CON: %s\n",I_love_you);

  • 输出(这里其实是有个小坑的

    After STR: Hello

    After CON: I_love_you (编译会报错)

问题(小坑)

但是第二句编译会报错,它只是进行连接,像是没有定义一样,举个例子:

// 正确:
int a = 10;
printf("%d",a);

// 错误:
printf("%d",b);

CON(I,you) 这里只是进行了宏的展开和替换并完成连接,完成后就是:printf("After CON: %s\n",I_love_you);
有没有发现了,就像是你凭空调用一个变量I_love_you,所以是不通过的。

解决

所以这里就需要想办法了,我可以多加一层中间转换宏,把所有的宏参数在这一层进行全部展开,那么就可以正常使用得到我们想要的答案了。

#include <stdio.h>

// 转字符串的宏定义 
#define		_STR(s)		#s
#define		STR(s)		_STR(s)
// 连接的宏定义 
#define		_CON(a,b)	a##_love_##b
// 正确
#define		CON(a,b)	STR(_CON(a,b))

// 错误
//#define		CON(a,b)	_STR(_CON(a,b))

int main()
{
    
    

	printf("After CON: %s\n",CON(I,you));
	
	return 0;
}

这里转化如下:
CON(I,you) -> STR(_CON(I,you)) -> _STR(I_love_you) > "I_love_you"

这里第二步往第三步 转换有点绕,可以多看看

下面是实际跑的代码,注意看下我圈出来那里CON输出结果,根据上面推一下。

正确版:
11111

错误版:
222222

猜你喜欢

转载自blog.csdn.net/qq_30722795/article/details/108113671