预处理详解(一) -- 预定义符号与#define定义


在这里插入图片描述

一. 预定义符号

%s _ _FILE_ _ //文件
%s _ _ DATE_ _ //日期
%s _ _ TIME_ _ //时间
%d _ _ LINE_ _ //行号
%d _ _ STDC_ _ //如果编译器支持 ANSI C,那么该值为1,
//否则未定义

在这里插入图片描述
在这里插入图片描述

二. #define

1.#define定义常量

define name stuff
#define定义常量在预处理阶段被替换成对应的内容(stuff)
// name:符号名
// stuff:符号内容

举个例子:

#define MAX 1000
#define reg registe
//使用reg 等同于使用 registe,还更为简洁
#define forever for(;;)
//初始化
//调整
//判断都可以省略不写
//但是判断不写,条件会恒为真,会造成死循环
int main()
{

	printf("%d\n", MAX);
	MAX直接被替换为1000

	return 0;
}

2.#define定义宏

#define name(parament-list) stuff
name:符号名
parament-list:是由逗号隔开的参数表,他们有可能出现在stuff中
stuff:符号内容 == 表达式
注意:
parament-list的左括号必须紧挨到name,不然parament-list会被识别为stuff中的内容

举个例子:

#define SQUARE(x) x*x

int main()
{
   int a = 10;
   printf("%d\n",SQUARE(a));//100
   printf("%d\n",SQUARE(a+1));//21
   
   return 0;
}

这里的 x = 10,1010 = 100
**a+1是直接进行替换,是a+1
a+1 = 2*a + 1 = 21
注意:
宏替换时不要吝啬括号,尽量能加括号的就加括号
所以加括号可以避免符号运算中出现不可预料的结果
那么这题正确是:#define SQUARE(x) ((x) * (x))

3.带有副作用的宏参数

宏的参数带有副作用就可能出现不可预料的结果

a + 1;//没有副作用
a++;//具有副作用

MAX可以证明带有副作用的宏

#define MAX(a,b) ((a>b) ? (a) : (b))
 
int main()
{
  int a = 1;
  int b = 2;
  int c = MAX(a++,b++);
  printf("%d %d %d",a,b,c);
  // a = 2 b = 4 c = 3
  return 0;
}

正确的写法:
在这里插入图片描述

4.宏替换的规则

1.在调用宏的时,首先对参数进行检查,检查是否有宏定义的符号,如果有,他们首先被替换
2.替换文本随后被插入到程序中原来文本的位置。
对于宏,参数名被他们的值所替换
3.最后再次对结果文件进行扫描,检查它是否还有#define定义的符号。如果是,就重复上述处理过程

注意:
1.宏参数和#define定义中可以出现其他#define定义的符号,但对于宏不能出现递归

#define MAX(a,MAX(2,3))//不是递归,是MAX的参数
#define MAX(x,y) MAX(x,y)//不能出现递归
//宏的内部调用了宏(表达式部分调用了宏)

2.当预处理器搜索#define出现的符号时,字符串常量并不被搜索

#define M 10
#define MAX(a,b) ((a>b) ? (a) : (b))
MAX(M,2);//M会被替换成10

printf("M = %d");//字符串常量不会被替换

5.宏和函数的对比

1.宏的优点:
通常被用于简单的运算
执行一条和函数有同样功能的语句,速度快,效率高
宏只有执行运算的时间,宏不存在内存的栈区静态区堆区,宏是不占用内存空间的
宏的参数无类型,所以宏可以进行任何类型的计算,是直接进行替换的
宏的参数可以出现类型:

#define MALLOC(num, type)\  // \为续行符,可以连接下一行
(type)malloc(num*sizeof(type))
...
//使⽤
MALLOC(10, int); //类型作为参数
//预处理器替换之后:
(int)malloc(10*sizeof(int));

2.宏的缺点:
宏会增加代码的长度,宏不能进行递归等等
3. 函数的优点:
函数会将值算好,才传参过去
在这里插入图片描述
4.函数的缺点:
函数的执行操作比较复杂,在反汇编中执行长度比较长
函数只能求特定类型的大小的运算等等

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值