编译预处理

C语言的编译预处理功能主要包括:文件包括(#include)、宏定义(#define)、条件编译

  • 编译预处理是C语言编译程序的组成部分,用于解释处理C语言源程序种的各种预处理指令,形式上都以#开头不属于C语言种真正的语句,但增强了C语言的编程功能,提高编程效率,C程序的编译处理用于把每一条C语句用若干条机器指令来实现,生成目标程序。由于#define等编译预处理指令不是语句,不能被编译程序翻译,需要在真正编译之前做一个预处理,解释完成编译预处理指令,从而把预处理指令转换成相应的C程序段,最终称为由纯粹C语句构成的程序,经编译后得到目标代码。
  • 所有编译预处理指令都在百衲衣预处理步骤中起作用,与程序真正运行过程无关。

宏基本定义

  • #define 宏名 宏定义字符串 (宏定义要在一行之内完成)如果一行之内完成不了,可以跟一个“\”符号表示改行未结束,与下一行合起来完成完整一行
  • 上述宏定义语句以#开始,表示它在编译预处理种起作用,而不是真正的C语句,行尾无需分号
#define PI 3.1415926
#define TRUE true
#define LONG_STRING "It represent a long string that \
is used as an example."
printf(LONG_STRING);

带参数的宏定义

  • 宏替换在程序编译预处理时完成,对于MAX(x,y)的编译预处理,首先用变量名x和y分别替换a,b,然后再用包含x,y的条件表达式替换MAX编译结束后,程序种MAX(x,y)便消失。
  • 在进行宏定义的时候注意对参数使用括号,因为宏替换仅仅是简单的替换,如果用两个参数eg:a+b替换为x的话可能产生歧义,当main种x=SQR(x+y)进行宏替换之后的结果可能不是人们想要的,结果是:x=x+yx+y;而人们想要的结果是x=(x+y)(x+y),要避免产生这种问题就要在进行宏定义的时候将原来的:
#define SQR(x) x*x改成#define SQR(x) (x)*(x)

#include<stdio.h>
#define MAX(a,b) a>b?a:b;
#define SQR(x) x*x
int main(){
    int x,y;
    scanf("%d%d",&x,&y);
    x=MAX(x,y);
    y=SQR(x);
    printf("%d %d",x,y);
    return 0;
}

文件包含

  • 文件包含的作用是把指定的文件模板内容插入到#include所在的位置,当程序编译连接时,系统会把所有的#include指定的文件凭借生产可执行代码,文件包含必须以#开头,这表示编译预处理命令,它将在程序编译时起作用,把指定的文件模块包含进来,当经过生成可执行代码后,include便不再存在,因此include不是真正的C语句,行尾不用分号结束
  • 文件包含的个格式:#incldue<需包含的文件名>或include “需包含的文件名”
  • 文件包含种指定的文件名如果使用尖括号<>,将使用C语言的便准头文件,由编译程序到C系统种设置好的include文件夹种把指定的文件包含进来,如果使用双引号“”,则编译程序首先到当前工作文件夹寻找被包含的文件,若找不到,再到系统include文件夹种查找文件,一般适用于编程者直接的包含文件,需要时可以在文件名前加上所在的路径。

条件编译

如果指向把源程序种一部分语句生成母便代码,可以使用条件编译。

#define FLAG 1
#if FLAG
	程序段1
#else
	程序段2
#endif	
  • 程序段1和2只有一个会被生成到目标程序种,这里FLAG被定义为1,所以会将第一个程序段编译;
  • 条件编译指令均以#开头,其意义与C语言的if-else语句完全不同,C语句if-else的两个分支程序段都会被生成到目标程序种,有程序运行时根据条件决定执行哪一段,而条件编译#if…#else…#endif不仅形式不同,而且它起作用的事可在编译与出口i的时候,一旦经过处理后,只有一段程序生成到目标程序种,另一段被舍弃。#if的条件只能起宏明,不能是程序表达式,因为在编译预处理时是无法计算表达式的,必须在程序运行时才做计算。

版权声明:本文为kz_java原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/kz_java/article/details/104632270