前言
1、本人QQ – 330952038 欢迎一起学习交流。
2、#define 的用法,相信大家有用过,本文抱着学习的态度来重新理解#define(宏定义)
正文
一、不带参数的宏定义
eg: #define BUF_MAX_LEN 100 // 定义 BUF_MAX_LEN为 100,此时就可以把BUF_MAX_LEN当做100使用。
unsigned char *buf[BUF_MAX_LEN ] ; // 申请一个100字节数组
注意:
1) 宏定义习惯用大写字母表示(只是建议并非强制)
2) 宏定义可以提高通用性,比如上面例子,可能被多处引用,只需要改变BUF_MAX_LEN 大小就可以改变所有被调用的地方
3) 宏定义不是C语言语句(宏定义需要通过预处理后转换成C语句), 不需要加入分号,所以声明时不能在末尾加入分号,否则会有导致使用时出现语法出错
eg: #define a 10;
unsigned char b = a*5; —-> (10;)*5 — 会导致语法错误
二、带参数的宏定义
#define 宏名(参数表) 字符串
eg: #define fun(x,y) (x)*(y)
area = fun(2,3); // 该功能相对于 area = (2)*(3);
注意
1)
带参数的宏定义,在后面的表达式中,参数最好是带上括号!
上面(x)*(y) 这两个参数为什么要加入括号呢?因为实参去替换形参时,并不会自动转换成你要的结果,而是原样替换。
比如 #define fun(x,y) x*y
char a = 4, b =3;
area = fun(a+b,a-b);
那么结果会是: area = a+b*a-b;
所以使用这种形式时,千万别忘记加入括号。
2)
在定义宏时,在宏名和带参数的括号之间不能加空格,否则将空格以后的字符都作为替代字符串的一部分,如:
#define S (r) r*r
area = S(a);
则area = (r) r*r(a);// 这是个错误的表达式
3)
很多人把带参数的宏定义和函数混淆。下面我们介绍一下两者区别:
a) 函数调用时,先求出实参表达式的值才会进行代入形参,而使用带参数的宏定义只是进行替换。
eg:
#define fun1(x,y) x*y
#define fun2(x,y) (x)*(y)
u8 fun3(u8 x,u8 y)
{
return x*y;
}
int main()
{
u8 a = 3,b = 2;
u8 t1,t2,t3;
t1 = fun1(a+b,a-b);// 直接进行替换形参,则t1 = a+b*a-b = 7
t2 = fun2(a+b,a-b);// 直接进行替换形参,则t2 = (a+b)*(a-b) = 5
t3 = fun3(a+b,a-b);// 先计算实参表达式值,即a+b = 5, a-b = 1,然后代入形参,计算结果是 t3 = 5*1;
while(1);
}
b) 对函数中的实参和形参都要定义类型,二者的类型要求一致,如果不一致,需要进行类型转换。而宏不存在这样的问题,宏名无类型,他的参数也是无类型,只是一个符号代表。置换时,代入指定的字符串即可。定义宏时,可以是任何类型的数据
eg: #define num 1.23 // 数值
#define name “zhangsan” // 字符串
上面num和name不需要定义类