如何打印宏
1. 问题描述
我们都知道,在C/C++中经常会用到宏定义,宏实际上就是给一个字段取的一个别名,它是属于预编译系统的一部分,其形式如:
#define PI 3.141592654
当我们想要使用3.141592654
这个值的时候,直接用它的别名PI
就可以了。如果什么时候,我们需要将PI
的精度提高,则只需要修改这个宏定义就可以了,而不用一个一个的去修改。
同时,宏是没有类型的,在预编译时,系统对它只是完全的字符替换而已,例如:
#define SQR(x) x*x
int main()
{
int a=SQR(5+3);
printf("the result is:%d",a);
return 0;
}
在预编译后,代码相当于:
int main()
{
int a=5+3*5+3;
printf("the result is:%d\n",a);
return 0;
}
结果是:the result is:23
因为宏是没有类型的,编译后只是简单字符的替换,那如果我想将PI以字符串的形式打印出来呢,该如何操作?
其实这还不好操作,直接将一个字符串取一个别名如:
#define HELLO "hello World!"
int main()
{
printf("the string is:%s",HELLO);
return 0;
}
结果是:the string is:hello World!
既然这样,那就再问一个问题,如果一开始你就跟本不知道定义的宏是个字符串形式呢?如:
#define PI 3.141592654
我依然想将3.141592654
打印出来,该如何操作呢?
2. 分析思路
需要将宏打印出来,其实就是将#define PI 3.141592654
转换成#define PI “3.141592654”
。
在这里需要用到#
符号,它是一个预处理运算法,作用是将语言符号转化成字符串。然后先来实验下:
#include<stdio.h>
#define PI 3.141592654
#define str(s) #s
int main()
{
printf("printf:%s\n",str(PI));
return 0;
}
然后进行预编译命令:
gcc -E test.c -o test.i
编译后得到的test.i文件就是预编译后的文件,打开查看里面有如下内容:
int main()
{
printf("printf:%s\n","PI");
return 0;
}
我们要的是3.141592654
,而不是PI
字符串,所以需要再加个宏定义,具体如下:
#include<stdio.h>
#define PI 3.141592654
#define xstr(s) str(s)
#define str(s) #s
int main()
{
printf("printf:%s\n",xstr(PI));
return 0;
}
同样按前面的方式进行预编译,得到的预编译文件大体如下:
int main()
{
printf("printf:%s\n","3.141592654");
return 0;
}
通过它编译出来的程序,执行结果如下:
user@user-Lenovo-Product:/local/sdb/tempFile/cTest$ ./test.o
printf:3.141592654
3. 总结
这个问题也是无意中看到的,在解决一个问题时,当时是希望将宏写入到编译后的文件中(即编译后文件会分配空间并存储该宏的内容),具体如图所示:
然后发现有使用打印宏的这个功能,感觉比较有趣,做个笔记方便后面查询。