94.【C语言】解析预处理(2)

目录

1.带有副作用的宏参数

代码

一个判断最大值的宏代码

运行结果

分析

"副作用"的解释

2.宏替换规则

解释

3.宏和函数的对比

附一张对比表


承接93.【C语言】解析预处理(1)文章

1.带有副作用的宏参数

代码

一个判断最大值的宏代码

cpp 复制代码
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
#include <stdio.h>
int main()
{
	int x = 5;
	int y = 8;
	int z = MAX(x++, y++);
	printf("x=%d\n", x);
	printf("y=%d\n", y);
	printf("z=%d\n", z);
	return 0;
}

注:不建议写成#define MAX(a, b) a > b ? a : b,不规范,x和y应该各代表一个整体

运行结果

分析

这里就产生了副作用,替换后为int z = ( (x++) > (y++) 1 ? (x++) : (y++));

执行(x++) > (y++)后, 还要执行y++,这里y加了两次,为副作用的体现

可以对比MAX函数,能更好理解

cpp 复制代码
#include <stdio.h>
int MAX(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	int x = 5;
	int y = 8;
	int z = MAX(x++, y++);
	printf("x=%d\n", x);
	printf("y=%d\n", y);
	printf("z=%d\n", z);
	return 0;
}

运行结果

显然在执行MAX(x++, y++);时,将参数x(未++的结果)和y(未++的结果)传了过去

"副作用"的解释

当宏参数在宏的定义中出现超过一次的时候(比如 ( (a) > (b) ? (a) : (b) )中a出现两次),如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果

2.宏替换规则

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

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

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

注意:

1.宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏不能出现递归(宏在预处理阶段就展开了,就是单纯的文本替换)

  1. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索

解释

cpp 复制代码
#include <stdio.h>
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
#define NUM 10
//......
	int z = MAX(x,NUM);
    printf("NUM=",NUM);
//......

1.首先对参数进行检查,MAX(x,NUM)的NUM首先被替换,之后为MAX(x,10);

2.再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号,MAX(x,10)被替换为( (x) > (10) ? (x) : (10) )

3.对于printf("NUM=",NUM);中的字符串常量"NUM="的NUM不被替换

3.宏和函数的对比

1.运算速度上:在执行简单的计算上,可能宏比函数快

若用函数:调用函数-->栈帧初始化-->执行计算-->返回值

若用宏:直接执行计算

2.参数类型上:函数需要指定参数的类型,而宏的参数和类型无关(这里体现出宏的缺点,不严谨)

比如

cpp 复制代码
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
//对比上下两段代码
int MAX(int a, int b)
{
	return a > b ? a : b;
}

3.宏可能产生运算符优先级问题

4.多次写某个宏,则意味着在预处理时会多次替换,增加程序的长度,而像函数就不会这样

5.宏无法调试,调试的是被替换后的内容

6.宏的参数可以是数据类型,而函数不行

cpp 复制代码
#include <stdlib.h>
#define MALLOC(NUM,TYPE) (TYPE*)malloc(NUM*sizeof(TYPE))
int main()
{
	int* p = MALLOC(5, int);
	return 0;
}

int* p = MALLOC(5, int);等价为int* p = (int*)malloc(5*sizeof(int));

附一张对比表

相关推荐
加号32 分钟前
【C#】 WebAPI 接口设计与实现指南
开发语言·c#
lly2024069 分钟前
jQuery 删除元素详解
开发语言
itzixiao10 分钟前
L1-047 装睡 (5分)[java][python]
java·开发语言·python
林恒smileZAZ18 分钟前
Three.js实现更真实的3D地球[特殊字符]动态昼夜交替
开发语言·javascript·3d
海绵宝宝的月光宝盒1 小时前
2-非金属材料
经验分享·笔记·学习·其他·职场和发展·课程设计·制造
|_⊙1 小时前
C++ 智能指针
开发语言·c++
电子科技圈1 小时前
IAR作为Qt Group独立BU携两项重磅汽车电子应用开发方案首秀北京车展
开发语言·人工智能·汽车·软件工程·软件构建·代码规范·设计规范
代码中介商1 小时前
C语言指针深度解析:从数组指针到函数指针
c语言·开发语言
Jasmine_llq1 小时前
《B4356 [GESP202506 二级] 数三角形》
开发语言·c++·双重循环枚举算法·顺序输入输出算法·去重枚举算法·整除判断算法·计数统计算法
zzh0811 小时前
GluserFS笔记
笔记