预处理器##
6.1 不能忽视宏定义中的空格###
宏提供了一种对组成C程序的字符变换的方式,而并不作用于程序中的对象。
不能忽视宏定义中的空格:
#define f (x) ((x)-1)
这是的结果是f(x)代表 (x)((x)-1)。
这一规则不适用于宏调用。
6.2 宏并不是函数###
宏putc在库文件stdio.h中的详细定义如下:
__CRT_INLINE int __cdecl __MINGW_NOTHROW putc (int __c, FILE* __F)
{
return (--__F->_cnt >= 0)
? (int) (unsigned char) (*__F->_ptr++ = (char)__c)
: _flsbuf (__c, __F);
}
其中putc的第一个参数为_c,是将要写入文件的字符,第二个参数__F则为一个指向一个用于描述文件的内部数据结构的指针,这里的__c由于是在条件表达式:的两侧,所以只会被求值一次,不会出现问题.
而__F这个指针,代表将要写入字符的文件,总是会被求值两次,但是由于它一般不需要进行递增递减之类有副作用的操作.但是这样也会出现一些错误.
6.3 宏并不是语句###
宏并不是语句。
6.4 宏并不是类型定义###
宏并不是类型定义
比如:
#define T1 struct foo *
typedef struct foo *T2
从概念上来看,T1和T2完全相同。下面对a,b进行定义
T1 a,b;
T2 a,b;
第一个声明会被扩展为:
struct foo *a,b;
第二个声明则是正常的结构指针。