现在的位置: 首页 > 综合 > 正文

c/c++基础(十一) 预处理

2019年09月13日 ⁄ 综合 ⁄ 共 1537字 ⁄ 字号 评论关闭

预处理明亮是标准C统一规定的,但它不是C语言本身的一部分,不能直接对它们进行编译。必须在对程序进行通常的编译之前,先对程序的这些特殊命令进行预处理。经过预处理的程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的便已处理,得到可以共执行的目标代码。

预处理包括三大类:


1.宏定义

        1.不带参数的宏定义

           #define 标识符 字符串

          在预编译时将宏名替换成字符串的过程称为宏展开。


1.在这个过程中,只是做简单的置换,不作正确性检查;

2.宏定义不是C语句,不必再行末加分号;

3.#define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。当然,可以使用#undef命令终止宏定义的作用域。


#define G 10

void main()
{
   ...
}

#undef G  //G的有效范围从定义处到此为止

void f()
{
...
}

4.在进行宏定义时,可以引用已经定义的宏名,可以层层置换。

5.宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只做字符替换,不分配内存空间。

    

    

   2.带参数的宏定义

      #define 宏名(参数表)字符串

    例子:

     #define PI 3.14159

     #define s(r) PI*r*r

   

     如果S(2) ,则宏展开为3.14159*2*2;

     如果S(a+b),则宏展开后为3.124159*a+b*a+b -----------------说明宏展开只是简单的字符替换而已

     想得到正确的结果,则需这样定义:#define S(r) PI*(r)*(r)

     注意:在宏名誉带参数的括号之间不应加空格;否则将空格以后的字符串都作为替代字符串的一部分。

     如:#define S (r) PI*r*r 则认为S是符号常量(不带参数的宏名),代表字符串(r)PI*r*r

          area= S(a) --> area=(r) PI*r*r(a)



      函数调用与宏定义的区别:

      1.函数调用,先求出实参表达式的值,然后带入形参;宏只是简单的字符替换

      2.函数调用是程序运行时处理的,为形参分配临时的内存单元;而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值的传递处理,没有返回值概念

     3.函数的实参与形参要定义类型,二者类型要一致,不一致,应该进行类型转换。宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。

     4.调用函数只可以得到一个返回值,而宏可以设法得到几个结果。

     5.使用宏次数多时,宏展开后源程序变长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。

     6.宏替换不占运行时间,只占编译时间。而函数调用则占运行时间(分配单元,保留现场,值传递,返回)


2.文件包含


#include <文件名>:到存放C库函数头文件的目录中寻找要包含的文件


#include "文件名" :先在当前目录中寻找要包含的文件,若找不到,再按标准方式查找(尖括号方式查找)

3.条件编译


     语法方式一:

      #ifdef 标识符
           程序段1
      #else
	    程序段2
      #endif    

       其中#else可以没有

      #ifdef 标识符
           程序段1
      #endif    


     语法方式二:

      #ifndef 标识符
           程序段1
      #else
	    程序段2
      #endif   


     语法方式三:

      #if 标识符
           程序段1
      #else
	    程序段2
      #endif   

不用条件编译命令而直接用if语句也能达到要求,那么好处是什么呢?

用if语句处理的话,目标程序长(所有语句都需要编译),运行时间长;而采用条件编译,可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。当条件编译比较多时,目标程序长度可以大大减少。



抱歉!评论已关闭.