《你必须知道的495个C语言问题》笔记--C预处理器

来源:互联网 发布:阿里云注销 编辑:程序博客网 时间:2024/05/01 17:25

如何正确定义函数式宏?

宏扩展是纯粹的文本扩展,为了避免意外,在定义函数式宏的时候,请记住下边的三条规则:

1.宏扩展必须使用括号,以便保护表达式中低优先级的操作符,例如:

#define square(x) x*x

调用

1 / suqare(n)

会被扩展为

1 / n * n

这等价于(1 / n) * n 而你需要的是:

1 / (n * n)

在这里,问题出在结合性而不是优先级上,但是效果是一样的。


2.在宏定义内部,所有的参数的出现都必须使用括号括起来,以便保护实参中任何低优先级的操作符不受宏扩展其他部分的

影响。同样以squre()为例,调用

square(n + 1)

会被扩展为

n+1 * n+1

但你需要的是

(n+1) * (n+1)


3.如果一个参数在扩展中出现了多次,而实参是带副作用的表达式,则宏可能不能正确运行,再以squre宏为例,调用

square(i++)

会被扩展为

i++ * i++

遵循规则1和规则2的正确的square宏的定义应该是

#define square(x) ((x) * (x))


完整的头文件搜索规则是怎样的?

通常,用<>命名的头文件会先在一个或多个标准位置搜索。用“”命名的头文件会首先在“当前目录”搜索,然后再在标准位置

搜索。(标准只规定了用“”命名的文件也会按照<>文件的方式搜索)

另一个区别在于“”文件的“当前目录”的定义。传统上(尤其是在UNIX编译器下),当前目录是包含#include指令的文件所

在的目录。

0 0
原创粉丝点击