首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >宏的使用(C语言详解)

宏的使用(C语言详解)

作者头像
用户11719974
发布2025-11-15 09:15:46
发布2025-11-15 09:15:46
580
举报

在写一个代码生成可执行文件的过程需要经过编译和链接,编译又要经过三部:预处理,编译,汇编。

#define定义的变量和宏就是在预处理阶段会处理的。

一个简单的宏定义:

代码语言:javascript
复制
#include<stdio.h>;
#define Max(a,b) a>b?a:b
int main()
{
	int x = 4, k = 9;
	printf("%d", Max(x, k));
}

Max:宏名

a,b:宏参数

a>b?a:b:宏体

宏定义有些类似函数,Max(a,b)会被替换为 a>b?a:b

比如这里printf("%d",Max(x,k));在预处理阶段会被替换为printf("%d",x>k?x:k);

注意:在#define定义的宏或变量后面不能加分号(;)

例如: 

1.运算符优先级处理

思考下面输出结果:

代码语言:javascript
复制
#define Mul(a,b) a*b
int main()
{
	int x = 4, k = 3;
	printf("%d", Mul(x, k + 2));
	return 0;
}

这里printf("%d", Mul(x, k + 2));会被替换为printf("%d",x*k+2);

所以结果为14,注意这里只是一一替换在预处理阶段进行,结果并不是20,而计算阶段是再生成的.exe后缀文件执行以后的事,所有在定义宏的时候,为了达到想要的效果我们通常在宏体里面加一些括号来避免这种问题的出现

例如:

代码语言:javascript
复制
#define Mul(a,b) ((a)*(b))

2.带副作用的宏参数

在给宏传参的时候我们尽量避免传一些前缀或后缀++ --这样的参数,这是一些带有副作用的参数

 例如:

代码语言:javascript
复制
#define Max(a,b) ((a)>(b)?(a):(b))//添加括号是解决优先级带来的潜在问题,上一个板块讲到
int main()
{
	int x = 2, k = 3;
	printf("%d", Max(++x, ++k));
}

程序执行后输出5,这里x变为3,k变为5。结果是我们无法预料的。

3.函数与宏的区别:

4.宏替换的规则

在程序中扩展#define定义符号和宏时,需要涉及⼏个步骤。 1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先被替换。 2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。 3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。 注意: 1. 宏参数和#define定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索

5.#运算符的使用

#运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执⾏的操作可以理解为”字符串化“。 当我们有⼀个变量 int a = 10; 的时候,我们想打印出: the value of a is 10 . 就可以写:

代码语言:javascript
复制
#define Print(n) printf("the value of "#n" is %d", n);
int main()
{
	int a = 0;
	Print(a);
	return 0;
}

而写作下面的形式只会打印 the value of n is 10,其中的n并不会被替换

代码语言:javascript
复制
 #define Print(n) printf("the value of n is %d", n);

6.##运算符的使用

        ## 可以把位于它两边的符号合成⼀个符号,它允许宏定义从分离的⽂本⽚段创建标识符。 ## 被称为记号粘合,这样的连接必须产⽣⼀个合法的标识符。否则其结果就是未定义的。         这⾥我们想想,写⼀个函数求2个数的较⼤值的时候,不同的数据类型就得写不同的函数,比如:

代码语言:javascript
复制
int int_max(int x, int y)
{
    return x>y?x:y;
}

float float_max(float x, float y)
{
    return x>y?x:y;
}

这么写很繁琐我们可以用宏定义来写函数。

7.宏定义函数

代码语言:javascript
复制
#define Max(type) type type##_max(type x,type y)\
				  {			\
						return x>y?x:y;	\
				  }
////这里\为续行符
Max(int)
Max(float)
Max(char)
int main()
{
	printf("%d\n", int_max(5, 9));
	printf("%.2f\n", float_max(5.2, 5.32));
	printf("%c\n", char_max('p', 'h'));
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.运算符优先级处理
  • 2.带副作用的宏参数
  • 3.函数与宏的区别:
  • 4.宏替换的规则
  • 5.#运算符的使用
  • 6.##运算符的使用
  • 7.宏定义函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档