程序的预处理

前言:

        前几次讲解了一个程序从写出的C语言代码到预编译——>编译——>转汇编——>链接——>可执行程序

        其中翻译环境我们基本上了解了,大概清楚其中的原理,接下来探究一下预编译阶段的过程。

预定义符号:

__FILE__      //进行编译的源文件

__LINE__     //文件当前的行号

__DATE__    //文件被编译的日期

__TIME__    //文件被编译的时间

__STDC__    //如果编译器遵循ANSI C,其值为1,否则未定义

这些符号在进行与编译阶段就会被替换成相应的信息,在运行时进行打印。

例如:
 

#include<stdio.h>
#define M 100

int main()
{
	//预定义符号
	printf("%s\n", __FILE__);
	printf("%d\n", __LINE__);
	printf("%s\n", __DATE__);
	printf("%s\n", __TIME__);
	return 0;
}

在VS2019\2022中的编译器没有严格遵循ANSI C!!

#define定义的标识符

        

#include<stdio.h>
#define M  100 //给M赋值为100
#define AD   advance_int//给advance_int重新取一个简短的名字AD
#define CASE  break;case        //在写case语句的时候自动把 break写上。
int main()
{
	int a = 0;
	a = M;
	int AD = M;
	printf("%d\n", a);
	printf("%d\n", AD);
	int i = 0;
	scanf("%d", &i);
	switch (i)
	{
	case 1:
	CASE 2 :
	printf("%d\n", i);
	CASE 3:
	printf("%d\n", i);
	CASE 4:
	printf("%d\n", i);
	}
	return 0;
}

参与编译阶段#define定义的标识符被自动替换,也就变成如下

#include<stdio.h>
int main()
{
	int a = 0;
	a = 100;
	int advance_int = 100;
	printf("%d\n", a);
	printf("%d\n", advance_int);
	int i = 0;
	scanf("%d", &i);
	switch (i)
	{
	case 1:
	break;case 2:
	printf("%d\n", i);
	break;case 3:
	printf("%d\n", i);
	break;case 4:
	printf("%d\n", i);
	}
	return 0;
}

#define定义的宏

        #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。

例如:

#define add(x,y) ((x)+(y))//定义一个有参数的函数
#define mul(x,y) ((x)*(y))
int main()
{
	int a = 10;
	int b = 20;
	int c = add(a, b);
	int d = mul(a, b);
	printf("%d\n", c);
	printf("%d\n", d);
	return 0;
}

 #define 替换规则

在程序中扩展#define定义符号和宏时,需要涉及几个步骤。

1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。

2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。

3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上 述处理过程。

注意:

1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

#define中##的作用

#define add(x,y) ((x)+(y))//定义一个有参数的函数
#define mul(x,y) ((x)*(y))
#define add2(x,y) x##y+=y//意思是给xy +10
int main()
{
	int a = 10;
	int b = 20;
	int c = add(a, b);
	int d = mul(a, b);
	int e = add2(a, b);//出现编译错误
	printf("%d\n", c);
	printf("%d\n", d);
	printf("%d\n", e);
	return 0;
}

作用:

##可以把位于它两边的符号合成一个符号。

它允许宏定义从分离的文本片段创建标识符。

#undef

这条指令用于移除一个宏定义。

例如:

没有使用#undef之前:

#include<stdio.h>
#define M 100
int main()
{
	int a = 0;
	a = M;
	printf("%d\n", a);
	return 0;
}

使用#undef之后

#include<stdio.h>
#define M 100
#undef M
int main()
{
	int a = 0;
	a = M;
	printf("%d\n", a);
	return 0;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值