vlambda博客
学习文章列表

【C语言】09-预处理命令

【C语言】09-预处理命令

预处理命令


【C语言】09-预处理命令

一、编译:对源程序进行词法、语法分析,生成代码,优化等。

二、作用:在编译之前,对源程序中的特殊命令做一些处理,生成扩展C源程序

三、种类:

1.宏定义         #define

2.文件包含     #include

3.条件编译     #if  #else  #endif等

四、格式:

1.“#”开头

2.占单独书写行

3.语句尾不加分号


宏定义



【C语言】09-预处理命令

如   #define    YES   1

       #define     NO    0

       #define     PI      3.1415926

       #define     OUT     printf(“Hello,World”);

3.定义位置:任意(一般在函数外面)

4.作用域:从定义命令到文件结束

5.#undef可终止宏名作用域

     格式:   #undef     宏名

【C语言】09-预处理命令

【C语言】09-预处理命令

6.宏名一般用大写字母,与变量区别。

7.使用宏便于修改变量值,提高程序通用性。

例   #define   ARRAY_SIZE   1000

       int  array[ARRAY_SIZE] ;


8.宏展开:预编译时,用宏体替换宏名---不作语法检查

如             if(x==YES)           printf(“correct!\n”);

                 else if (x==NO)     printf(“error!\n”);

展开后:if(x==1)             printf(“correct!\n”);

                 else if (x==0)     printf(“error!\n”);


9.引号中的内容与宏名相同也不置换

例   #define   PI    3.14159

      printf(“2*PI=%f\n”,PI*2);

宏展开:printf(“2*PI=%f\n”,3.14159*2);


10.宏定义中使用必要的括号()

例  #define   WIDTH   80

      #define   LENGTH   (WIDTH+40)

      var=LENGTH*2;

宏展开:var=  (80+40) *2;


11.宏定义可嵌套,不能递归

【C语言】09-预处理命令

二、带参数的宏定义

1.一般形式:  #define    宏名(参数表)     宏体

2.功能:进行字符串替换,并进行参数替换

【C语言】09-预处理命令


3.宏展开:形参用实参换,其它字符保留

4.宏体及各形参外一般应加括号()

例  #define   POWER(x)      x*x

      x=4;   y=6;

      z=POWER(x+y);

宏展开:z=x+y*x+y;

一般写成:  #define    POWER(x)    ((x)*(x))

宏展开:  z=((x+y)*(x+y));


例  #define   S    (r)    PI*r*r

相当于定义了不带参宏S,代表字符串“(r)     PI*r*r” 

【C语言】09-预处理命令

5.带参宏定义与函数的区别

⊙函数调用时,先求实参表达式的值,再带入形参。

    宏只进行简单字符替换,不求值。

函数调用在程序运行时处理和分配临时内存单元。

    宏展开在编译时进行,不分配内存单元,无值传递和返值。

函数要定义形实参且类型一致,宏无类型,其参数无类型。

函数只有一个返回值,宏可以设法得到几个结果。

【C语言】09-预处理命令

宏展开使源程序变长,函数调用源程序不变长。

宏替换不占运行时间,只占编译时间。

    函数调用占运行时间。 

例  用宏定义和函数实现同样的功能

【C语言】09-预处理命令

【C语言】09-预处理命令


“文件包含”处理


一、功能:一个源文件可将另一个源文件的内容全部包含进来

二、一般形式:

【C语言】09-预处理命令


三、处理过程:预编译时,用被包含文件的内容取代该预处理命令,再将“包含”后的文件作为一个源文件单位进行编译,得目标文件.obj

【C语言】09-预处理命令

【C语言】09-预处理命令

四、被包含文件内容

1.源文件(*.c)

【C语言】09-预处理命令


五、文件包含可嵌套

【C语言】09-预处理命令六、预编译后已成为一个文件,因此file2.c中的全局静态变量在file1.c中有效,不必再用extern声明。

条件编译


一、功能:当文件中的部分内容在满足一定条件才进行编译

二、几种形式:

1.形式1:

⊙标识符已被#define命令

    定义过,则编译程序段1,

    反之编译程序段2


例   调试信息的输出

#define  DEBUG

          ┆

#ifdef DEBUG

printf("x=%d,y=%d,z=%d\n",x,y,z);

#endif


2.形式2:

⊙与形式1相反,标识符未被#define命令定义过,则编译程序段1,反之编译程序段2 

eg:

#ifndef  标识符

     程序段1

#else

     程序段2

#endif


3.形式3:

⊙表达式为真,则编译程序段1,反之编译程序段2 

eg:

#if  表达式

     程序段1

#else

     程序段2

#endif


例:输入字符串,根据需要设置条件编译, 使字母改为大写或小写

#include <stdio.h>

#define  LETTER  1    /* 1大写,0小写 */

void main()

{ char str[20]="C Language",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);}

   printf(“\n");

}

 引致:教材

 C程序设计 (第二版)

          谭浩强  编著 清华大学出版社


内容:提供更好的学习资源