赞
踩
我们偶尔会在代码里看到这样的用法:
- int Flower = 1;
- int Fruit = 2;
- int Vegetables = 3;
- int GetFlowerId()
- {
- return Flower;
- }
- int GetFruitId()
- {
- return Fruit;
- }
- int GetVegetablesId()
- {
- return Vegetables;
- }
三个函数在其他地方有调用,find一下声明又find不到。找来找去找到个类似声明的写法:
- DeclareGetNameId(Flower);
- DeclareGetNameId(Fruit);
- DeclareGetNameId(Vegetables);
其宏函数的定义有可能是长这样的:
#define DeclareGetNameId(name) int Get##name##Id()
宏定义中,##表示字符串拼接,一般用于消除大面积的结构性重复比如上面的例子。
什么?你想把函数定义里的重复也消掉?也可以:
- #define DefineGetNameId(name)
- int Get##name##id()
- {
- return name;
- }
-
- DefineGetNameId(Flower)
- DefineGetNameId(Fruit)
- DefineGetNameId(Vegetables)
这段代码还有重复,好吧定义里有一行可以直接用声明替换,再改改:
- #define DefineGetNameId(name)
- DeclareGetNameId(name)
- {
- return name;
- }
什么?调用点也想用这种花里胡哨的方法?行,给你一个:
#define GetNameId(name) Get##name##Id()
又重复了,好吧调用点用的宏和声明用的宏里面Get##name##Id出现了两次,看来得为这个东西单独写个宏了:
- #define NameFactory(name) Get##name##Id
- #define GetNameId(name) NameFactory(name)()
-
- #define DeclareGetNameId(name) int GetNameId(name)
- #define DefineGetNameId(name)
- DeclareGetNameId(name)
- {
- return name;
- }
上面这段代码可以作为你的工具库,走到哪儿带到哪儿。什么?名字不通用?同时你还想返回别的类型?好吧我们改改:
- #define NameFactory(name) Get##name
- #define GetNameInst(name) NameFactory(name)()
-
- #define DeclareGetNameInst(type, name) type GetNameInst(name)
- #define DefineGetNameInst(type, name)
- DeclareGetNameInst(type, name)
- {
- return name;
- }
这段代码已经做了非常多的消除重复的动作,终于可以作为程序员必备了吧?
下面我们验证一下。使用gcc -E x.c可以生成预处理文件,也就是把宏展开后生成一个文件,默认打在terminal,通过gcc -E x.c > x.i打印到x.i里,代码如下:
- DeclareGetNameInst(int, Flower);
- DefineGetNameInst(int, Flower)
展开如下:
- int GetFlower();
- int GetFlower() { return Flower; }
下面我们总结一下这个写法的优缺点:优点已经体现得比较清楚了,代码整洁,重复度低;缺点在本文开头也说过了,无法通过IDE的find定义、声明、调用功能进行代码阅读,代码阅读是无法流畅的。
下面谈一下具体工作中应该怎么选:宏函数这个东西,能不用则不用,毕竟安全性不太行。但凡事有个例外,假如3个同质函数可以忍,30个300个呢?太多就用吧。
延伸阅读(例子来源于多个帖子):
我们已经知道了##是用来进行拼接的。下面还有几个小知识点:
1、#表示字符串替换。网上常见的例子是这样
#define example(instr) printf("the input string is:t%sn",#instr);
example(abc);展开之后:
printf("the input string is:t%sn","abc");
2、#@表示字符替换。看两个小例子:
- #define ToChar(x) #@x
- #define ToString(x) #x
char a = ToChar(1);结果就是a='1';
char* str = ToString(123132);就成了str="123132";
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。