C语言碎碎念02预处理define(连载)

define

#defined定义一个宏
宏替换在预处理阶段完成,宏替换为简单的值替换

总结在最后,不想仔细看就直接看最后面。。。

宏替换一般分为两种

  1. 无参的宏#define PI 3.14f
    那么程序中遇到PI就直接在编译阶段就全部替换为了3.14了
    2.带参的宏
#define MUL(a, b)  a*b

在遇到MUL(参数,参数)的时候直接替换为a*b。这样直接写感受不明显,下面用两道题来讲解

#if A == 3 
    #define B 3 
#else 
    #define B 5 
#endif 
  
int main() 
{ 
    printf("%d", B); 
    return 0; 
} 

这个输出是什么呢?好像一眼看去为printf("%d", B); ,这个B在宏定义中有,但是却在一个判断语句中。假如A==3那么B==?,但是在这里就会发现A也没有定义。可能有人会觉得在函数中A自始至终都没有出现过,所以编译不能够完成,其实不然。A没有被定义,默认值为0,0是固然不等于3,所以B被赋值5。
当A==0的时候,判定为真
当A!=0的时候判定为假

上面两个测试程序就可以看出来,对于宏定义的变量,没有赋值的话是等于0的。
下面这题

#include <stdio.h> 
#define ADD(x) x+x 
int main() 
{ 
  int x; 
  x = 100/ADD(10); 
  printf("%d", x); 
  return 0; 
}

宏函数为简单的值替换!这点要牢记
这一句x = 100/ADD(10);应当替换为x=100/10+10,并不是100/(10+10),这里就能看出“简单的值替换了”
结果为20.
再看一题:

# include <stdio.h> 
# define scanf  "%s Embedded Inn " 
int main() 
{ 
   printf(scanf, scanf); 
   return 0; 
} 

这题是在一个微信公众号上看到的
在预处理阶段,代码将会替换,一旦不小心就会出错!

printf(scanf, scanf);被替换为printf(“%s Embedded Inn”,“%s Embedded Inn”);
其实当替换到这里的时候,我还在觉得,会不会编译出错

但是,其实是可以的,这里需要提一下,**""这个双引号的作用,不仅可以代表是一个字符串,还可以对这个字符串取地址。**就像return一样,有多个功能。

那么printf(“%s Embedded Inn”,“%s Embedded Inn”);第一个%s输出的为第二个的字符串
输出的结果为:%s Embedded Inn Embedded Inn

所以在使用宏函数的时候,尽量使用()来保证参数的完整性

#define MUL(a, b) a*b
MUL(3+2, 4+2)==> 3+2*4+2  ==> 13

//使用括号,可以尽量保证参数的完整性,只是尽量哈
#define MUL(a, b) ((a) * (b))
MUL(3 + 2, 4 + 2) ==> ((3 + 2) * (4 + 2)) ==>30

看起来加上()能够正常计算,但是当使用++的时候还是不好使
看下面的代码

#define MAX(a,b) (((a)>(b))?(a)(b))

MAX(2+3,3+5);//这样的使用是没有毛病儿
//但是一旦牵扯到++,--运算
int x=3,y=5;
MAX(x,++y);
//(((x)>(++y))?(x)(++y))----->7
//这样就没有办法,括号也救不了哦,这就是宏替换的固有缺陷

总结:
1.在预处理阶段,实现宏展开 ,没有函数调用出入栈的开销 ,效率高 ,但空间消耗大(典型的空间换时间)。
2.宏函数,尽量包含简短的代码 ,尽量不要有大量判断、循环语句。
3.宏函数不能保证参数的完整性。我们之所以有这么关于宏函数的问题,都是因为它不能够保证参数的完整性,即使加上括号也难以避免。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值