一、前言
C语言真的是学无止境的感觉,大部分同学大学都会开设C语言课程。很多人把C语言二级过了就感觉入门了;对于那些在做嵌入式开发的工程师,几乎每天都要接触C语言,很多人会感觉自己C语言学得很溜了。那好,咱们用一道C语言面试题来测试一下。
二、面试题
首先给出题目:
定义一个宏,求两个数中的最大数
OK,很多人应该能很快写出
#define MAX(x,y) x > y ? x : y
接下来我们写一个测试程序
#define MAX(x,y) x > y ? x : y
int main(void)
{
printf("max=%d",MAX(1,3)); //测试通过
printf("max=%d",MAX(4,1));//测试通过
printf("max=%d",MAX(2,2));//测试通过
printf("max=%d",MAX(3!=3,1!=2)); //好像不是我们要的结果
return 0;
}
我们会发现第四个测试不是我们的要结果了。这是因为宏展开后,就变成了这个样子:
printf("max=%d",3!=3>1!=2?3!=3:1!=2);
这个时候大于号(>)的优先级更高,所以就出现了问题了。
优化上面的代码
可能很多人已经想到了解决方法了,比较有经验的工程师基本也比较少犯上面的错误。
加上括号就可以解决上面的问题了。
#define MAX(x,y) (x) > (y) ? (x) : (y)
OK,接下来我们再写一个测试程序
#define MAX(x,y) (x) > (y) ? (x) : (y)
int main(void)
{
printf("sum =%d", 7 + MAX(3,4));
return 0;
}
运行结果:
并不是我们所期望的11。我们将其展开后为:
7 + (3) > (4) ? (3) : (4);
这个时候加号(+)的优先级又比大于号(>)高,所以就出现了这种结果。
那我们就继续加个括号
#define MAX(x,y) ((x) > (y) ? (x) : (y))
到这里算是比较完整的了,在面试中要是能写出这个,那算基本功还是比较扎实的了。
那我们再写一个测试程序
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main(void)
{
int i = 3;
int j = 4;
printf("max=%d",MAX(i++,j++));
return 0;
}
运行结果:
这里面的j会做两次自增运算, 所以打印出来的结果是做了一次自增后的结果。
继续优化
#define MAX(type,x,y)({ \
type _x = x; \
type _y = y; \
_x > _y ? _x : _y; \
})
int main(void)
{
int i = 4;
int j = 5;
printf("max=%d\n",MAX(int,i++,j++));
printf("max=%f\n",MAX(float,3.2,3.4));
return 0;
}
到这里基本算比较完美了!是不是很折腾, 程序的bug就是这样一步一步修复的过程。
三、总结
如果你能一下就写出最后的代码,那说明你确实是666了,通过上面的一步一步分析是为了告诉大家,C语言真的有很多东西可以让我们去琢磨!我们也还有很长的路要走。