预处理器详解

C/C++编译系统编译文件的过程称为预处理、编译、链接。预处理器在在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序。预处理指令以#号开头标识,末尾不含分号。C/C++提供的预处理功能主要包括文件包含、宏替换、条件编译等。
1、预定义符号
FILE :代表进行编译的源文件名
LINE :文件当前的行号
DATE :文件被编译的日期
TIME :文件被编译的时间
STDC :如果编译器遵循ANSI C,其值为1,否则未定义

#include 
#include 
int main()
{
    printf("file:%s\n,line:%d\n,time:%d\n,date:%d\n", __FILE__, __LINE__, __TIME__, __DATE__);
    system("pause");
    return 0;
}

预处理器详解_第1张图片
2,#define
使用#define指令,你可以把任何文本替换到程序里面,通常把这种实现称为宏或者定义宏,下面是标准的宏声明方式:

#define name(参数列表) stuff

参数列表的左括号必须与name紧挨,否则参数列表将会被解释为stuff的一部分,分析下面这个程序

#include 
#include 
# define sqare(x) x*x
int main()
{
    int a = 3;
    printf("%d\n", sqare(a));//结果为9
    printf("%d\n", sqare(a + 1));//本以为结果会是16,但实际结果为7,3+1*3+1=7
    system("pause");//所以使用宏的时候一定要注意()的使用
    return 0;
}


3.#运算符
把一个宏参数变成对应的字符串。例如:

#include 
#include 
#define M 20
#define PRINT( FORMAT, VALUE )\
    printf("the value of "#VALUE" is "FORMAT"\n", VALUE);//#让参数M的值不被替换
int main()
{
    PRINT("%d", M);
    system("pause");
    return 0;
}

4.##运算符

##运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号。看下面的例子:
#include 
#include 
#define cat(x,y) x##y//x##y表示连接xy
int main()
{
    printf("cat=%s", cat("he","llo"));
    system("pause");
    return 0;
}

最后程序的输出为:
hello
5.带副作用的宏参数

#include 
#include 
# define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{
    int x = 7;
    int y = 9;
    int z = MAX(x++, y++);
    printf("%d", z);
    system("pause");
    return 0;
}
结果为10

所以下面就来分析一下,先来进行一个简单的替换 ((x++)>(y++)?(x++):(y++))
发现最小值进行++操作了一次,但是最大值进行了++操作两次,所以宏的副作用就很明显了。
5.带副作用的宏参数

#include 
#include 
# define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{
    int x = 7;
    int y = 9;
    int z = MAX(x++, y++);
    printf("%d", z);
    system("pause");
    return 0;
}
结果为10

所以下面就来分析一下,先来进行一个简单的替换 ((x++)>(y++)?(x++):(y++))
发现最小值进行++操作了一次,但是最大值进行了++操作两次,所以宏的副作用就很明显了。
6、#undef
这条预处理命令用来移除一个宏定义,如果一个现存的名字需要重定义,那么它的就定义首先应该用#undef移除
7、条件编译
条件编译存在的必要性:在编译一个程序时,如果我们要选择某一条语句或者某组语句进行翻译或者被忽略时,我们就需要用到条件编译
语法形式:

#if 常量表达式
   statements
#endif

常量表达式由预处理器进行求值,如果它的值为非0,那么statements的部分就会被正常编译。否则,预处理器就会删除他们。

#if DEBUG 1
      printf("hehe");
#endif
则执行输出hehe
#if DEBUG 0
      printf("hehe");
#endif
则忽略这条代码。

8、#if #ifdef
判断是否被定义

#include 
#include 
#define DEBUG

int main()
{
#ifdef DEBUG
    printf("yes\n");
#endif
#ifndef DEBUG
    printf("no\n");
#endif
    system("pause");
    return 0;
}
结果为:yes

9、其他指令

9、其他指令
#error //指令允许你生成错误的信息
#if 常量表达式
//....
#elif 常量表达式
//...
#else
//...
#endif

10、文件包含
本地文件包含:#include”filename”
库文件包含:#include

你可能感兴趣的:(计算机科学与技术)