1.明示常量 #define
预处理指令结尾不带;(分号),在预编译的过程中使用宏的地方会进行展开,是用多少次就展开多少次,但是只替换 不计算,预处理器在发现程序中的宏后,会用宏等价的替换体进行替换,如在上图中,M 将被替换为100
但是双引号中的宏不会被替换
其实很好理解,如果宏和你所使用的字符串重名,那么双引号的字符串当然不会被理解成宏
2.在#define中使用参数
很明显看到后两个和预期不符,此处验证了宏参只替换不运算的性质
倒数第二个表达式 x+1*x+1=5+1*5+1=11
最后一个 100/x*x=100/5*5=100
所以你想让任何地方的Square都不出错最好的办法就是不要吝啬括号的使用
即使这样也无法解决前置++的问题
由于第一个表达式前置++,所以两个++x都应该先++再使用,++两次之后x变成7
最后一个后置++是使用x的值计算,最后再把x++
可以很好看到前置后置的区别,如果对这块还不是很清楚,可以去看 前置 后置辨析
3.用宏参数创建字符串
前面说到过,双引号中的宏并不会被替换,但是想在双引号里面包含宏怎么办呢?
“#x” 就会把双引号里面的字符宏变成真正的宏
4.预处理器粘合剂:##运算符
##可以把两个字符串粘结在一起
x和1粘合在一起就是x1
5.变参宏:...和__VA_ARGS__
__VA_ARGS__是C99中新增的
...表示宏参中可以变化的部分,而__VA_ARGS__则出现在替换部分中,表明省略号代表什么
值得注意的是,省略号只能代替最后的宏参数
6. #undef
#undef表示取消定义
前面无论是否写过 #define M 100这样的宏M
使用#undef M之后就会把在之前的都清除
但是千万注意,宏的作用域是全局
这题最后的答案是A,因为define在预处理阶段就把main中的a全部替换为10了。另外,不管是在某个函数内,还是在函数外,define都是从定义开始直到文件结尾,所以如果把foo函数的定义放到main上面的话,则结果会是50..50
7.条件编译
#ifdef 后面加宏,表示如果定义过这个宏,就执行后面紧跟的语句
由于我们没有定义过M,所以输出No
#ifdef和#endif一定要一起使用,即使没有#else
具体的使用规则和if else相似
8.#ifndef
和上面#ifdef的用法完全一样,但是逻辑相反,#ifndef M表示如果没有定义M的话就执行后面紧跟的语句
9.#if 和 #elif后面加常量表达式
同样后面吧必须加上#endif
如果对你有帮助的话,留一个免费的