网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
2、“#”和“##”的使用规则
“#” 是将宏参数转换为字符串。不管该参数宏什么,即“原貌”用字符串显示出来。即将宏参数用双引号“”包裹起来形成一个字符串。例如:
#define T(x) #x
int temp = 10;
cout<<T(temp)<<endl;//输出 temp 而不是 10
// T(temp) -> "temp" (将宏参数用双引号包含起来形成一个字符串)
“##” 被称为连接符(concatenation),把宏参数与之前的token(参数/字符串空格等)连接起来。例如:
#define T(x) x##[2]
int a[5] = {1,2,3,4,5};
cout<<T(a)<<endl; //输出 3 即 a[2]
// 1. 宏参数在宏体中未加括号包裹起来
#define T(a) a*10
int a = 1;
cout<<T(a+1)<<endl; //输出 11 而非20
// 2. 整个宏体内容未加括号包裹起来
#define T(x) x+1
cout<<10*T(1)<<endl; //输出 11 而非20
1、在宏定义中,将参数加上括号,这样在替换时保证括号内的表达式优先运算。2、利用括号将整个宏定义的内容括起来,保证整个宏定义中的表达式优先运算。宏嵌套是宏使用的难点,也是易错点。下面我将宏嵌套的展开规则用流程图来说明一下:
宏嵌套的展开规则流程图
注意:上图中的 2 和 3 是条件或,只要满足一个条件就会进入流程5。下面举例说明:
// example 1
#include <cstdio>#define TO_STRING2(x) #x
#define TO_STRING1(x) #x
#define TO_STRING(x) TO_STRING1(x)
#define PARAM(x) #x
#define ADDPARAM(x) INT_##x
int main()
{
const char *str = TO_STRING(PARAM(ADDPARAM(1)));
printf("%s\n",str); //输出: "ADDPARAM(1)"
str = TO_STRING2(PARAM(ADDPARAM(1)));
printf("%s\n",str); //输出: PARAM(ADDPARAM(1))
return 0;
}
上例中两个嵌套宏的展开流程如下:
TO_STRING(PARAM(ADDPARAM(1)))
-> 展开 PARAM:TO_STRING("ADDPARAM(1)")
-> 展开 TO_STRING:TO_STRING1("ADDPARAM(1)")
-> 展开 TO_STRING1:"\"ADDPARAM(1)\""
TO_STRING2(PARAM(ADDPARAM(1)))
-> 展开 TO_STRING2:"PARAM(ADDPARAM(1))"
![img](https://img-blog.csdnimg.cn/img_convert/54ededb8587d644ecbed466f3e1ae103.png)
![img](https://img-blog.csdnimg.cn/img_convert/54238c1bcd238a41dfc0df9bffb0ac71.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
cs/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**