文章目录
一、#和##
1.#运算符
这里的#不是#include和#define前面的那个#,它是一个运算符,这个运算符将宏的⼀个参数转换为字符串字⾯量,它仅允许出现在带参数的宏的替换列表中,#运算符所执⾏的操作可以理解为”字符串化“
在讲解这个运算符之前我们先来看一段代码,如下:
#include <stdio.h>
int main()
{
printf("hello world!\n");
printf("hello"" world!\n");
return 0;
}
这里的第二个printf中的字符串由两个字符串组成,这样写和第一种printf的效果有什么不同呢?我们来看看代码运行结果:
可以看到,两个printf打印出来的内容是一致的,所以我们可以得出,如果两个字符串挨着一起写,会实现字符串的合并
为了讲清楚#运算符,我们先来看看这样一个例子,我们定义一个变量a = 3,然后我们想要在屏幕上打印 the value of a is 3,该怎么做呢?经过前面的学习,我们已经可以直接写出来了,如下:
int a = 3;
printf("the value of a is %d\n",a);
这个时候我们随便更改a的值都可以使得这句话是正确的,它会随着a的改变而改变,然后我们这个时候说,再创建几个变量,也要以这种形式进行打印,那么每打印一次我们都要写这么长的一串,有没有什么办法简化一下呢?
这个时候我们就可以定义一个宏来解决,在上面那个字符串中,有三个变化的地方,一个就是of后面的a,还有就是占位符%d,然后就是最后面的a,那么我们就可以定义一个宏PRINT,它的参数就是我们要打印的那个值和占位符,如下:
#define PRINT(x , format) printf("the value of x is %d\n",x);
首先我们写出来这个宏后可以发现最后面的那个x会随着我们提供的变量变化,所以已经解决了,还有两个地方要处理,就是of后面的x和后面的占位符,因为它们都在字符串中,所以替换的时候不会替换它们,那么我们怎么办呢
对于占位符的替换,我们可以使用上面学习的两个字符串可以合并的思想,如下:
#define PRINT(x , format) printf("the value of x is "format"\n",x);
这样,前面的the value of x is 就变成一个字符串,后面的\n也变成了一个字符串,这个时候只需要我们传参的时候传上我们的占位符就可以了,如下:
int a = 3;
PRINT(a, "%d");
经过传参后format会被替换成"%d",又是一个字符串,前面一个,中间一个,后面一个字符串,最后合并成了一个字符串
然后就是最后一个要解决的问题,就是of后面的x,我们怎么能够使得它随着我们的传参变化而变化呢?这个时候就要请出我们的#运算符了,它可以使得宏的参数字符串化,只需要将x左右的字符串分开,然后在它前面加上#即可,如下:
#define PRINT(x , format) printf("the value of "#x" is "format"\n",x)
这里将原本的参数x字符串化了,最后也变成了一个字符串,和其它几个字符串合并在了一起,但是这个时候x的内容就会随着我们的传参改变而改变了,比如把变量a传给x,那么of后面就是a,把变量b传给x,那么of后面就是b
然后我们来看看完整代码:
#include <stdio.h>
#define PRINT(x , format) printf("the value of "#x" is "format"\n",x)
int main()
{
int a = 3;
float b = 5.1f;
PRINT(a, "%d");
PRINT(b, "%f"