编译预处理

从source code到可执行程序,一般经历一下步骤:
C源码  -》编译预处理 -》编译 -》连接 -》可执行程序
 
本文只讲述编译预处理的故事,编译预处理有三大作用:
1、宏定义
2、文件包含
3、条件编译
 
1、宏定义
(1)不带参数的宏定义
   define PI 3.1415926  
宏定义是在编译之前进行处理的,宏定义只是作简单的替换,不做语法检查。宏定义与变量不同,不能被赋值,不分配内存空间,只作字符替换。
#define命令出现在函数的外面,宏名的有效范围是从定义到本源文件结束,在需要终止有效范围时,可以用#undef,例如
(2)带参数的宏定义
在此种情况下,多使用括号,以免出现错误.
   #define  S(r)  r*r
语句  area=S(a+b); 替换为area=a+b*a+b
正确为#define  S(r)  (r)*r) 
替换为area=(a+b)*(a+b)
 
函数调用是在程序运行时处理的,分配临时的内存单元,有参数的传递过程和返回值;而带参数的宏是在编译时进行的,在展开时并不分配内存单元,无值传递和返回值.
函数调用占用运行时间;而宏替换占用编译时间
 
 
2、文件包含
 
“文件包含”指一个源文件可以将另一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中.
 
 
3、条件编译
 
对其中的一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件.
•(1) #ifdef    标识符     
•      程序段1
•        #else   
•     程序段2
•        #endif 
•(2) #ifdef    标识符     
•      程序段1
•        #endif   
 
例子:
  当标识符已被定义时(一般用#define命令定义),则对程序段1编译,否则编译程序段2.
  Eg: #define COMPUTER_A
      #ifdef   COMPUTER_A
          #define  INTEGER _SIZE  16
     #else
           #define  INTEGER _SIZE  32
     #endif
         以上例子起到开关控制的作用.  
 
(3)
#ifndef    标识符
          程序段1
      #else
          程序段2
       #endif
 
例如:
作用:若标识符未被定义编译程序段1,否则编译程序段2.
Eg:  #ifndef  RUN
            printf(“x=%d,y=%d”,x,y);
        #endif
如果未对RUN定义,则输出x,y的值                      
 
 (4)
#if   表达式
         程序段1
        #else
          程序段2
        #endif                                                  
例子:当指定的表达式为真时,编译程序段1,否则编译程序段2.
•#define  LETTER  1
• main( )
• {
      char str[ ]=“C Langue”,c; 
      int i=0;
•    while((c=str[i])!=’\0’)  
     {
           i++;
•         #if  LETTER
•              if(c>=’a’&&c<=’z’) 
                   c=c-32;
•         #else        
               if(c>=’A’&&c<=’Z’) 
•                 c=c+32;
•         #endif   
          printf(“%c”,c);   
     }
}                          
          
            
原文地址:https://www.cnblogs.com/zzj2/p/3003170.html