C语言缺陷与陷阱读书笔记(六)

预处理器##

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;

第二个声明则是正常的结构指针。

posted on 2015-09-22 16:20  陆游君语  阅读(218)  评论(0编辑  收藏  举报

导航