C/C++预处理

目录

1.前言

2.文件包含

2.宏定义

2.1 无参数的宏

2.2 带参宏定义

3.条件编译 


 

1.前言

预处理是指在进行编译的词法扫描和语法分析之前所作的工作。预处理指令指示在程序正式编译前就由编译器进行的操作,可放在程序中任何位置。处理完毕自动进入对源程序的编译。C/C++中的预处理主要包含三种:文件包含、宏定义、条件编译

2.文件包含

文件包含命令行的一般形式为:

#include"文件名" 或 #include<文件名>

值得注意的是,

(1)<>表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的include目录),而不在当前源文件目录去查找;

(2) ""则表示首先在当前源文件目录中查找,若未找到才到包含目录中去查找。

(3)一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。

(4)一个包含文件中可以包含别的包含文件。

2.宏定义

C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简单的字符串替换,根据是否带参数分为无参和带参

2.1 无参数的宏

#define 宏名 一段符号

其中一段符号表示你需要的用宏名来代替的一段符号,在编译预处理时,程序中出现的所有你设定的宏名都将被这段符号代替。

样例:#define ip 114514

表示程序中出现的所有ip都将表示114514。

测试:

#include 
#define	ip  114514
 
int main()
{
	int a = ip;
    printf("%d\n",a);
    return 0;
}

结果:

C/C++预处理_第1张图片  

一般我们使用宏定义是为了方便修改和管理代码。

需要注意的是宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错。

测试1:

#include 
#define	ip  1+2 = 3

int main()
{
    int a = 0;
    printf("%d\n", a);
    return 0;
}

结果:

C/C++预处理_第2张图片

 这里没使用宏,宏没被展开,宏没做语法检查而不报错。

测试2:

#include 
#define	ip  1+2 = 3

int main()
{
    int a = ip;
    printf("%d\n", a);
    return 0;
}

结果:

 宏被展开了,直接编译报错。

2.2 带参宏定义

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

在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

样例:#define MULTIPLY_2(x,y) ((x)*(y))

 注意:在这个宏中,x和y作为参数在表达式中,应被括号分隔开。也就是说当宏中有表达式时,其内部参数需被括号独立,防止程序出错。

样例:

#include 
#define	a1(x,y) (x*y)
#define	a2(x,y) ((x)*(y))
int main()
{
    int a = 1;
    int b = 2;
    int sum1 = a1(a + b, b);//sum1=(a+b*b)
    int sum2 = a2(a + b, b);//sum2=((a+b)*b)
    printf("%d %d\n", sum1,sum2);
    return 0;
}

结果:

C/C++预处理_第3张图片

3.条件编译 

一般情况下,源程序中所有的行都参加编译。但有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是条件编译

样例1:

#include 
#define	a1(x,y) (x*y)
#define	a2(x,y) ((x)*(y))
int main()
{
    int a = 1;
    int b = 2;
    int sum1 = a1(a + b, b);
	int sum2 = 0;
#ifdef a2   //这里只是检查宏有没有定义,并不检查值
	if (a == 1)
	{
		sum2 = a2(a + b, b);
	}
#else
	if (a == 2)
	{
		int sum2 = a2(a + b, b);
	}
#endif
	{
		printf("%d %d\n", sum1,sum2);
	}
	
    return 0;
}

 结果:

C/C++预处理_第4张图片

 样例2:

#include 
#define	a1(x,y) (x*y)
//#define	a2(x,y) ((x)*(y))
int main()
{
    int a = 1;
    int b = 2;
    int sum1 = a1(a + b, b);
	int sum2 = 0;
#ifdef a2   //这里只是检查宏有没有定义,并不检查值
	if (a == 1)
	{
		sum2 = a2(a + b, b);
	}
#else
	sum2 = sum1;
#endif
	{
		printf("%d %d\n", sum1,sum2);
	}
	
    return 0;
}

结果:

C/C++预处理_第5张图片

 显而易见的,宏有没有定义直接影响了程序运行的结果。

ps:c编译器中,有几个特殊形式的预定义宏需要我们注意。

__FILE__ 宏所在文件的源文件名

__FUNCTION__   宏所在函数名

__LINE__ 宏所在行的行号

__DATE__ 代码编译的日期

__TIME__ 代码编译的时间

样例:

#include 
#define	a1(x,y) (x*y)
//#define	a2(x,y) ((x)*(y))
int main()
{
    int a = 1;
    int b = 2;
    int sum1 = a1(a + b, b);
	int sum2 = 0;
#ifdef a2   //这里只是检查宏有没有定义,并不检查值
	if (a == 1)
	{
		sum2 = a2(a + b, b);
	}
#else
	sum2 = sum1;
#endif
	{
		printf("%d %d\n", sum1,sum2);
	}
	printf("文件名:%s\n", __FILE__);
	printf("函数名:%s\n", __FUNCTION__);
	printf("行  号:%d\n", __LINE__);  // 
	printf("日  期:%s\n", __DATE__);  // 
	printf("时  间:%s\n", __TIME__);  // 
	return 0;
}

结果:

C/C++预处理_第6张图片

 

你可能感兴趣的:(c++,c语言,经验分享)