C语言查缺补漏(四)宏定义与#、##用法

宏定义的使用与#、##用法

​ 初学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

转载请注明出处!!!

如果有写的不对或者不全面的地方 请指正! 谢谢~

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/82918258