用一个宏实现求两个数中的最大数
用一个宏实现求两个数中的最大数
在面试或者笔试中,经常会碰到“用一个宏实现求两个数中的最大数”这个题目,一般情况下,大家看到这个问题,觉得很容易实现,这有什么难度呢,随手就是一个:
#define MAX(x, y) \ ((x) > (y) ? (x) : (y))
注:用括号将宏定义整个括起来,在任何时候,都是一个好习惯。
如果能写出上边这个宏,你这道题的考试就能交差了,然后觉得对自己来说就是随手一写的事儿,那可就大错特错了。因为以上写法的宏定义,虽然也能拿到分数,但是在面试者或者笔试阅卷者看来,你也不过如此,你也只是茫茫人海中平凡的一员。那么对于这道平淡无奇的题目来说,如何给考官一个眼前一亮,豁然开朗的印象,可以尝试下使用下边几种方法来实现。
上边那个宏定义,一般情况下,是可以满足需求的,但是对于一些参数具有副作用的情况,就很容易出现意想不到的结果了。比如:
int a = 1; int b = 10; int max = MAX(a++, b++); // 宏定义展开: ((a++) > (b++) ? (a++) : (b++));
以上例子,结果会根据编译器的差异,产生一些意外的结果,这些绝对不会是程序开发者想要的结果,自己可以思考下...
为了防止宏定义的两个参数存在副作用的情况,可以将传递给宏定义的参数,在对比之前,保留一份备份,用备份参数来进行对比,总不会错了吧,并且这样实现,参数的副作用仅计算一次,不会影响对比的结果,实现方式如下MAX_2:
#define MAX_2(x, y) ({\ int _x = (x); \ int _y = (y); \ _x > _y ? _x : _y; \ })
然而,很快就发现,以上MAX_2宏定义,仅仅是用在对比两个int型参数时,实际情况可能对比的是unsigned char,或者其他的类型,那么这个宏定义也不能很好地实现预期效果。
那么,继续改进,将要对比的参数类型以一个参数的形式传递给宏定义,比如下面MAX_3:
#define MAX_3(type, x, y) ({\ type _x = (x); \ type _y = (y); \ _x > _y ? _x : _y; \ })
这样,宏定义要对比的两个参数的参数类型,以参数的形式传递给宏定义,在宏定义中,type参数,将是宏定义中传递的那个参数类型,使用方法如下:
unsigned char c = 'A'; unsigned char d = 'B' MAX_3(unsigned char, c, d);
MAX_3宏定义,很好地实现了对于不同类型的两个参数求最大值的功能,但是先不要太高兴,因为MAX_3还是存在些缺点的,比如,对于一些粗心大意,导致传递的两个参数,存在和第一个参数类型不一致的情况,如下:
int a = 100; unsigned char c = 'H'; MAX_3(unsigned char, a, c);
以上情况,可能只是手误,但是这个意外确实存在了,而MAX_3宏定义也确实会正常执行,但是结果可能就不是实现者的本意,而在代码中也很难被查出来,大家应该都有花费大量时间查Bug,最后发现是一个小符号错误的情况,太无奈,不再多说...
以上情况,也是有方法的,比如下面这个MAX_4宏定义:
#define MAX_4(x, y) ({\ typeof(x) _x = (x); \ typeof(y) _y = (y); \ (void)(&_x == &_y); \ _x > _y ? _x : _y; \ })
MAX_4宏定义,通过typeof关键字,来获取参数的类型,并保存参数的一份拷贝,防止参数副作用影响对比结果,再通过(void)(&_x == &_y);来对比两个参数类型,如果不是同一种类型,在编译阶段就会报出warning,引起开发者注意,提前消灭隐患。
综上所述,如果应试者能够在笔试中很快地写出MAX_4宏定义的实现方式,我相信绝对会给考官们眼前一亮,甚至是惊艳的效果。
如果以上四种方式都达不到你需要的效果,那么我也没办法了,因为MAX_4宏定义可以说是我的认知范围内,最安全的实现“宏定义求两个数中的最大值”的方法了。随时欢迎朋友们有更好的实现方法来学习。
- linux shell实现求一个多维数组中的最大和最小值
- 作业题:输入4个整数,找出其中最大的数。用一个函数来实现. 分别使用结构化方法和函数嵌套的方法。
- 经典面试题:求数组的最大子序列和;实现函数 :判断一个自负喜欢是否是另一个字符串旋转所得;杨氏矩阵中查找一个数。
- java实现求两个数的最大公约数
- 求数组中的最大值--分别用非类,类,带一个参数的类模板,带2个参数的类模版实现
- 用JavaScript脚本语言设计并实现一个函数,将三位数重新排列输出最大值
- 实现一个可限制最大连接数的Proactor服务器
- 实现一个Add函数,让两个数相加,但是不能使用+、-、*、/等四则运算符。
- mysql插入一行数据,其中一个值为当前该列的最大值,怎么实现?
- 用c语言实现 计算两个数的最大公约数
- 1. 请用C#的面向对象语言 实现 一个计算器控制台程序,要求输入两个数和运算符号,得到结果
- 实现一个Add函数,让两个数相加,但是不能使用+、-、*、/等四则运算符。ps:也不能用++、--等等
- 设计一个栈实现最大值函数
- 5*5的矩阵中最大的元素放在中心,写一个函数实现
- C语言实现: 求两个数的最大公约数
- 用递归二分法实现同时获得一个数组内的最大最小值
- 面试题,求一个整数数组中和最大的连续子数组,例如:[1, 2, -4, 4, 10, -3, 4, -5, 1]的最大连续子数组是[4, 10, -3, 4](需写明思路,并编程实现)
- 算法之 求两个数的最大公约数 C++实现
- Java实现-一行代码求两个数的最大公约数
- Java程序实现欧几里得算法-计算两个数的最大公约数