优雅的代码总是让人赏心悦目,比如下面有两段代码,都是实现了相同的功能,当你看完代码A再来看代码B时,你是否也有一种身心愉畅的感觉呢。
代码A:
1 //如果用户输入的是偶数,就直接输出,否则就+1之后再输出。 2 int a; 3 printf("请输入一个数字:"); 4 fflush(stdin); 5 scanf("%d", &a); 6 7 //判断情况再输出 8 if (a % 2 == 0) 9 { 10 printf("结果是:%d ", a); 11 } 12 else 13 { 14 a = a + 1; 15 printf("结果是:%d ", a); 16 }
代码B:
1 //如果用户输入的是偶数,就直接输出,否则就+1之后再输出。 2 int a; 3 printf("请输入一个数字:"); 4 fflush(stdin); 5 scanf("%d", &a); 6 7 //输出结果 8 printf("结果是:%d ", a + a % 2);
让9行代码变成1行代码,却依然能实现相同的功能,有着四两拨千斤的味道,优雅感也就这么产生了。
然而,是否代码越少就越优雅呢?大部分情况下是的,但并不绝对,盲目的追求往往适得其反,最显而意见的例子就是下面这段代码。
1 //请问以下代码会输出什么结果 2 int a = 0; 3 int i = 2; 4 a = (++i) + (++i) + (++i); 5 printf("%d ", a);
其实今天主要就是想聊聊上面这段代码,不少企业的面试题中就经常会出现类似这样子的题目,我个人认为在面试题中出现这种题目的企业他们有着一个不负责任、不作为的人事部或者技术部。
为什么要考这种题目,我认为有三个原因:
1.在我们公司,这种代码被认为是优雅的、高效的代码,公司现有的程序中编写了此类代码,我们要求新加入的成员能阅读这种代码,甚至是在将来加入公司后,新成员也能写出这种代码。
2.在我们公司,我们认为这种浓缩代码是晦涩难懂的,所以并不优雅,或者说是伪优雅。虽然我们并不会在实际的项目中编写此类代码,也不会要求新员工在加入公司之后来编写此类代码,但我们依然将它加入到面试题中,因为我们希望新员工是一名技能好手,烂熟于胸的掌握操作符的优先顺序或许能一定程度上的说明部分问题。
3.在我们公司,面试题都是下载来的,或者历史遗留下来的,那种题目看起来就很高大上,可以显得我们公司也高大上,就留着吧。
遗憾的是,大部分企业是第三个原因吧。
代码变少,却依然能实现相同功能,自然是很棒。但真的依然能实现相同功能吗?经过试验发现,上面的这段代码,在不同的编译器下得到的结果是不同的。
l 在VS2010中新建VC++控制台项目,运行的结果为:15
先让三个++i执行,i就变成了5,然后5+5+5=15
l 在VC++6.0中新建Win32控制台项目,运行的结果为:13
为什么结果是13,我也没理解,求大神科普
l 在VS2010中新建C#控制台项目,运行的结果为:12
先++i就得到3,再++i就得到4,再++i就得到5
然后3+4+5=12
在VC++6.0的时代,出现这种面试题,无可厚非。但时代在变化,当今还考(++i)+(++i)+(++i)就显得不太合适了,因为在不同的编译器下,将会得到不同的结果。
如果是因为第2个原因,想找技能好手而将此类题目加入面试题中,那这得是一个多么好的好手,才能准确的回答出此题呢?我想标准答案应该是这样的:“此题在VC++6.0中输出13;在VS2010中用C++输出15;用C#输出:12;”,然后再附上各种结果的计算过程。我想这种好手应该很少,如果真在面试题中加入这个题目,企业不但找不到顶尖好手,反而会错过很多一般般、还可以的好手。
如果是因为第1个原因,想找到能写出优雅代码的小伙伴,那就更加不靠谱了,因为首先,这种代码并不是优雅的,因为它根本没有“实现相同功能”,在不同编译器下结果是不同的。
结论:将代码浓缩的更少,却依然能实现相同的功能,大部分情况下这是优雅的做法,但要考虑两点,一是不能让代码变得特别晦涩难懂,二是要避免在不同编译器下出现不同的结果。
PS:或许有些偏题了,水平有限,不吝赐教。