#define定义宏

一、#define定义标识符

//基本语法:
#define name stuff
//举例:
#define MAX 100
#define reg register
#define print printf("hello world")
#define do_forever for(;;)

define定义常量的逻辑:
在后面的代码中遇到name就用stuff替换掉

二、 #define定义宏

#define 允许把参数替换到文本中,这种实现与函数很类似,通常被称为宏

//申明方式
#define name(parament) stuff//注意name和(参数)之间不能有空格,否则就变成定义标识符了
//举例:
#define ADD(a,b) ( (a) + (b) )
#define SQUARE(x) ( (x) * (x) )
#define MAX(a,b) ( (a) > (b) ? a : b )

你或许会好奇为什么要加这么多括号?这些括号似乎没什么必要,那么,我们把去掉如何?
观察下面代码块:

#define SQUARE(a) a * a
int a = 5;
printf("%d", SQUARE(5 + 1));
//输出结果会是36吗?

在这里插入图片描述
为什么呢?其实原因很简单,还记得上面讲#define定义标识符是将name替换成stuff吗?这里也是如此,SQUARE(5+1)在我们看来是传入了参数6,但在宏看来是传入了参数5+1并替换掉参数a

//函数就变成了
printf("%d", 5 + 1 * 5 + 1);
//此时只需要给参数加上括号即可解决
#define SQUARE(a) (a) * (a)
//函数就变成了
printf("%d", (5 + 1) * (5 + 1));

这里还有一个宏定义,即使给参数加上了括号也会出现问题:

#define DOUBLE(a) (a) + (a)
printf("%d", 10 * DOUBLE( 5 ));

在宏看来,这个函数就等同于

printf("%d", 10 * (5) + (5) );

要想解决这个问题也很简单,就是把宏的计算结果再括起来就行

#define DOUBLE(a) ( (a) + (a) )
//函数就变成了
printf("%d", 10 * ( (5) + (5) ) );

三、宏的一些注意事项

  1. 当宏参数在宏的定义中出现超过⼀次的时候,如果参数带有副作用(a++这种),表达式求值的时候出现的永久性效果。
  2. 宏定义中可以出现其他宏,但不能出现自己(可以嵌套,不能递归)
  3. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
  4. 宏通常被应用于一些简单的计算,比如输出a和b中的较大的一个

四、宏和函数的对比

优势:

  1. 宏是直接替换程序内容,相较于函数的调用和输出,一般情况下运行速度更快,规模更小
  2. 函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使⽤。反之这个宏可以适用于整形、长整型、浮点型等可以用来比较的类型。宏是类型无关的

劣势:

  1. 每次使用宏的时候,⼀份宏定义的代码将插⼊到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
  2. 宏没法调试
  3. 宏由于类型无关,就不够严谨
  4. 宏可能会带来运算符优先级的问题,导致程序容易出错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值