从一道面试题看不同编程语言的表述能力
很多人都不明白,不同的编程语言具有不同的表述能力,这就是我们为什么有了汇编之后还需要更高级的编程语言。在软件规模愈发庞大的现在,C 和 C++ 语言表述能力的不足越发的明显了。我们应该尽可能的选用高级的编程语言完成我们的任务,在需要性能的地方,使用 Profiling,而不是在一开始就选用 C/C++ 这样的语言去工作。
最近一段时间,突然看到一个很吸引眼球的题,而这道题貌似 ThoughtWorks 也考过类似的内容。题目很简单,但是怎么写都让我觉得很别扭,知道有一天我用 DrRacket 写了一下,才恍然大悟。在没有模式匹配的语言中,这道题就是怎么写怎么别扭,没办法的。下面我们来分别比较一下 C 语言和 Scheme 这两种古老的语言的实现。
题目描述(大意):
依序遍历 0 到 100 闭区间内所有的正整数,如果该数字能被 3 整除,则输出该数字及 ‘*’ 标记;如果该数字能被 5 整除,则输出该数字及 ‘#’ 标记;如果该数字既能被 3 整除又能被 5 整除,则输出该数字及 ‘*#’ 标记。
首先先看看 C 语言的常规实现:
for (int i = 1; i <= 100; i++) { |
省略了 main
函数等关系不是很大的部分。我选择逻辑最清晰的两层 if-else
的方式,比起其他“聪明”的方法,可读性最高,逻辑最清晰,最省计算量,同时也最容易添加、修改程序逻辑。
我们再来看看 Scheme 的实现:
#lang racket |
经过对比我们发现,Scheme 语言由于具备(由库提供)模式匹配功能,从而使得程序的逻辑较 C 语言清晰不止一筹。仔细的总结一下 Scheme 实现的优点:
- 有意义明确的方法来产生一个闭区间的所有数字:
range-closed
; - 无需手工确定闭区间的左右边界:
for
循环; - 有意义明确的方法表示整除:
divides?
; - 有一致的命名规则表示返回布尔值的方法:后缀
?
; - 通过模式匹配,判断了被 3 和 5 整除的所有情况,和该种情况下对应的动作:
'(#t, #t) '(#t, #f) '(#f, #t) else
。
我甚至还没有说 Scheme 中可以在方法中定义方法,而 C 语言不可以(GNU 扩展可以);C 语言其他类型可以被直接当做布尔值使用,以至于发明出了 NULL == ptr
这样扭曲的表达方式(但是我估计这里没有人想用 if (i % 3)
吧?)。
这只是非常简单的一道练习题,就能够暴露出了 C/C++ 语言的诸多弱点。我不是说 C/C++ 语言一点好处都没有,但是绝大多数情况下,我们应该选用其他具有更强表达能力的语言。
珍爱生命,远离低级语言!