预处理处理
预处理命令是c标准规定加入C谔言源程序中的,目的是改进程序设计环境,提高编程效率.但这些命令不是C语言本身的组成都分,所以编泽器无法识别,不能对它们直接进行变编译.因而要编译程序在对c源程序进行编译之前,先由预编译程序对这些编译预处理命令进行处理,这一过程称为“预编译处理”
在c语言中,凡是以“#”开头的行,都称为预编译指令,主要有:
#include
#define
#if
#else
#endif
#elif
#ifndef
#undef
#line
#program
#error根据需要,指令可以出现在程序的任何位置,其作用域一直持续到源文件结束.
预处理符号
#define宏定义
#define指令的一些简单用法,就是为数值命名一个符号.正式描述一下定义方式:#define标识符替换数值(stuff)有了这条指令后,预处理器会将源程序中出现的所有标识符,替换成数值.数值可以是常数表达式字符串等任意字符,甚至C语言语句也可以.如果定义中的stuf非常长,它可以分成几行,除了最后一行之外,每行的末尾都要加一个反斜杠
#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为带参宏.
下面是宏的声明方式:#define name(参数列表) stuff其中,parame list(参数列表)是一个由逼号分隔的符号列表,它们可能出现在stuf中.参数列表的左括号必须与name紧邻.如果两者之间有任何空白存在,参数列表就会被解释为suf的一部分.当宏被调用时,名字后面是一个由逼号分隔的值的列表.每个值都与宏定义中的一个参数相对应,整个列表用一对括号包围.当参数出现在程序中时,与每个参数对应的实际值都将被替换到stuff中.
带参宏
警告:带参宏仅仅做替换,意味着使用时会出现一个问题.比如:乍一看,你可能觉得输出的是16.实际上它输出的是7,想知道为什么吗?我们来观察一下被替换的宏文本.参数x被文本3+1替换,所以这条语句实际上是:
由替换产生的表达式并没有按照预想的次序进行求值.在宏定义中加上两个括号,这个问题便很轻松地解决了!
在前面那个例子里,预处理器现在将用下面这条语句执行替换,从而产生预期的结果.由替换产生的表达式并没有按照预想的次序进行求值.在宏定义中加上两个括号,这个问题便很轻松地解决了! 在前面那个例子里,预处理器现在将用下面这条语句执行替换,从而产生预期的结果.
警告:上面的问题得到解决,但是又会出现一个新的问题比如:
又一看,你可能觉得输出的是10.实际上它输出的是90,再一次,通过观察被替换的宏文本.可以发现问题所在: 乘除优先级相同,从左往右运行.这个错误很好解决:在定义宏是,你只要在整个表达式两遍加上一对括号就可以了.
提示:所有用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时,由于参数中的操作符或邻近的操作符之间不可预料的相互作月: