大家好,我是轩哥。
今天我们通过一个 C语言中的宏定义来看一看,不同段位的程序员都是怎么样来写代码的。这个宏定义是我在面试过程中习惯性使用的第一个问题,然而很多面试者的回答都停留在了比较初级的写法上,至少说明经验尚浅,踩的坑太少啊。
我们先来看一下题目:请定义一个宏函数,函数的功能是返回两个参数中较大的值。
青铜写法:
#define MAX (x,y) x > y? x: y
这是遇到的最多的写法,对于这个答案,我想学过谭浩强版 C语言的程序员大概都能闭着眼写出来。测试一下:
#define MAX (x,y) x > y? x: y
int result = MAX(1!= 1,1!= 2);
按照宏定义规则,在编译器进行展开后,可以考虑一下,表达式是不是就乱掉了?你不知道使用者传进来的是个数还是表达式,所以有必要改进一下。
白银答案:
#define MAX(x,y) (x) > (y)? (x): (y)
这个答案还是中规中矩的,一般有个两三年编码经验的人都应该写出这样的答案,否则我认为你可能连 ctrl + c 和 ctrl + v 还没整熟练。
不过还是有些情况下调用会产生意想不到的效果,因为高优先级的运算符会闯进来哦。
测试一下:
#define MAX(x,y) (x) > (y)? (x) : (y)
int result = 3 + MAX(1,2);
上面的调用在编译前展开后为:
int result = 3 + (1) > (2) ? (1) : (2)
所以,我们有必要去查一查 运算符 “+” 、 “>” 以及 “?:” 哪个优先级更高一些了。
可以看到,加减乘除的运算优先级是遥遥领先的。
黄金答案:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
嗯,为了避免运算符的问题,我们再加一层括号,码程序不是耍技巧,拿不准的情况下,我多加括号就可以了。我们再测试一下:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int result = 3 + MAX(i++,j++);
上面的调用案例是不是让你反应过来了,这里面的 i++是被直接展开的,因此在我们的代码里实际上是被调用了两次哦!
int result = 3 + ((i++) > (j++) ? (i++) : (j++));
这样你计算出的结果总是大一点
铂金答案:
#define MAX(x,y) ({
int _x = x;
int _y = y;
_x > _y ? _x : _y;
})
好,既然你输入的参数能变换莫测,我就定义一个变量把他先放寄存器里,中间不让你再打扰我,全处理完我再返回给你。
新来个搞算法的程序员,调用测试一下吧
MAX(3.65,3.68);
赋值错误!,你这函数写的兼容性也太差了,到底支持什么样的类型也没说清楚,我以为是万能的呢
钻石答案:
#define MAX(type, x, y) ({
type _x = x;
type _y = y;
_x > _y ? _x : _y;
})
老子成全你,我把类型也搞成个参数,你自己定某天公司来了个 Python 程序员一起 review 代码逻辑。这是什么鬼。。。。。。