宏定义的使用与#、##用法
初学C语言时常常忽略宏定义的使用,因为觉得声明局部变量,全局变量,静态变量就够用了,所以忽略了宏定义的使用
上述想法完全是错误的,因为宏定义在系统编译时就将其全部替换,定义的变量不会在运行时候分配内存。所以它有无可替代的优点:效率特别高!!!不占用内存空间!!!
宏定义不仅可以定义变量,使用带参数的宏定义可完成函数调用的功能,又能减少系统开销,提高运行效率。
如果不使用宏定义,在发生函数调用时,需要保留调用函数的现场,以便子函数执行结束后能返回继续执行,同样在子函数执行完后要恢复调用函数的现场,这都需要一定的时间,当函数调用次数特别多的时候,这些时间的消耗是不可忽略的。
而使用宏定义就不会出现这个问题,因为它在预处理阶段即进行了宏展开,在执行时不需要转换。
宏定义有无参宏定义和带参数宏定义两种
1.无参宏定义的一般形式为:
# define 宏名 字符序列 //宏名与字符序列之间用空格符分隔,用于替代后面的字符序列
——每个宏定义都在源程序中单独占一行,换行符是宏定义的结束标志。如果一个宏定义一行不够时可采用续行的方法。续行是在按回车前先输入符号"/"
注意!!回车要紧接在符号"/"后,中间不能插入其它符号
——宏定义的有效范围称为辖域,辖域从定义开始到源文件末尾。可用预处理命令#undef终止宏定义名的辖域
——宏名可被重复定义,重定义后会覆盖之前的字符序列
一般无参宏定义用于定义常量,比如定义数组长度(数组长度不能由变量定义,除了宏定义外,还可以使用const 关键字定义)
2.带参宏定义的一般形式为:
# define 宏名(参数表) 字符序列 //参数间用逗号分隔,字符序列中应包含参数表中的参数
注意!!宏名与左圆括号之间不允许有空白符
以下是易错点!!!!!!!!!!!!!
易错点一:大家要深入理解宏替换的“替换”两个字!例如:
#define F(x) x * x
如果a = 1, b = 2,那么F(a + b)为多少?
很多同学会认为是9,但是答案是5。
原因是替换!只是简单的替换!!!
F(x) = x * x = 1 + 2 * 1 + 2 = 5
就是酱紫。。所以代码需要改成#define F(x) (x) * (x) 才会输出9
在宏定义中,我们使用#把宏参数变为一个字符串
用##把两个宏参数连在一起(这里说的是在预处理是对源文件的操作)
例如:
#define S(s) #s
#define F(a,b) int(a##e##b)
易错点二:
对于以下代码
#define a 1e5
const int b = 1e5;
输出a和b的值,分别是多少呢?
a: -272632256
b: 100000
所以,要想宏定义科学计数法,需:
#define a int(1e5)
此时a的值为100000
关于宏中#和##的用法:
在字符序列中:
用#可以把宏参数变为一个字符串
用##可以把两个宏参数连接在一起
例如下面代码:
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
//...省略其余代码
printf(STR(hello)); // 输出字符串"vck"
printf("%d/n", CONS(1,5)); // 输出:100000
如果有写的不对或者不全面的地方 请指正! 谢谢~