宏函数(宏定义)使用注意

前言

  一些经常使用的简单函数,我们会把他定义为宏函数,宏函数确实具有一些优势,本文将讲述宏函数的使用方法和重点踩坑。

  • 使用方便
  • 提高系统运行效率:宏函数并不是真正的函数,只是把语句嵌在其他函数内,所以宏函数并不需要函数调用。

1. 宏函数和内联函数的区别

  未了解以前,我感觉这两者似乎没有什么区别,就是书写方式不同而已。但有了了解以后,感觉这两者还是颇有差距的。

  • 宏函数在预处理阶段就会展开,而内联函数在编译时才会展开(展现)
  • 编译器在处理内联函数会优化,可能不会按我们的需求进行展开.
  • 其他比如调试方面的差异.

2. 宏函数书写方式

2.1 一行宏函数

  可以实现一些简单的取最小值、最大值、打印、计数等功能。

  1. 最小值(该方式仍有问题,后续解决)
    #define MIN(X,Y) ((X)<(Y)?(X):(Y))
  2. 打印
    #define PRINT(str) printf(#str)
  3. 计数
    #define COUNT(num) num++
  4. 判断
    #define IS_SUCCESS(ret) (SUCCESS == ret)

2.2 多行宏函数

 多行宏函数书写可以用于进行一些判断后操作、FOR循环前置等一些包含多条语句的功能.

2.2.1 判断后进行操作
#define DEF_CHK_NUM_OPT(num, opt)\
	do{\
		if(100 == num)\
		{\
			PRINT(num);
			opt++;\
		}\
	}while(0);
2.2.2 PRINT使用预定义宏
#define PRINT_STR(s)\
	{\
		printf("File:%s, Line%d:%s,Function:%s: %s\n", __FILE__,__LINE__,__FUNCTION__,s);
	}

/* 各种预定义宏 */
__LINE__:在源代码中插入当前源代码行号;
__FILE__:在源文件中插入当前源文件名;
__DATE__:在源文件中插入当前的编译日期
__TIME__:在源文件中插入当前编译时间;
__STDC__:当程序严格遵循ANSI C标准时,该标识被赋值为1;
__cplusplus:当编写C++程序时该标识符被定义。
2.2.3 PRINT 可变参数

  参考snprintf函数类似

#define LOG(format, ...)\
	{\
		printf("%s, %d" format,   __FUNCTION__, __LINE__,  ##__VA_ARGS__);\
	}
其实 `__VA_ARGS__`     就是一个可变参数的宏,替代上面的...
    `##__VA_ARGS__`   就是当可变参数个数为0时,将参数列表中前面多余的,去掉.

如果不加##LOG("TEST") 会被替换成 printf("%s:%d" "TEST", func, LINE, ); ,从替换结果看多了一个 , 号。我们需要把这个 , 去掉所以得使用 ##去删除

3. 宏函数需要特别注意的地方

3.1 宏函数中的空格

#define f(x)  ((x)-1)
#define f (x)  ((x)-1)

上面第二种写法能够达到预期的效果吗?答案是不能。其表达的含义是f 代表 (x) ((x)-1).
但调用时f(3)f (3)都能达到预期的效果.

3.2 宏需要分号吗

  • 如果单纯是#define num 5,不要加分号,如果加了分号,做替换时会把分号也加上去;
  • 如果是宏函数,而这个函数在代码中需要分号,那就必须添加分号;
  • 宏函数包含多条语句时,中间的语句该加的就得加;

3.3 宏后的 \ 字符

宏是以什么作为结束的,是以回车。所以宏函数包含多条语句时,后面的中间语句必须加 \

3.4 为什么使用do while形式

在写if else的宏函数时,如果不包裹起来,很容易产生悬挂else的问题,影响了之前的if else逻辑.

if(x == 0)
	if( y== 0)
		error();
else
{
	z = x + y;
	f(&z);
}

其实际含义为:

if(x == 0)
{
	if( y== 0)
		error();
	else
	{
		z = x + y;
		f(&z);
	}
}

参考:
1、https://blog.csdn.net/sdoyuxuan/article/details/81948388
2、C陷阱和缺陷

  • 12
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值