Research Notes: 学 C 编程记

一、

从我大一的时候《计算概论》这门课(基本上相当于 C 语言初步)拿了 62 分之后,我就对 C 再也没有产生过兴趣。

我当然不认为自己缺乏编程的天赋。作为一个从小学数学的学生,编程纵然未必是强项,但是也不会给我带来任何心理压力。我只是单纯地不喜欢它。单单 #include 这一串字符就能让我心生厌恶,这也太违反思维的本性了。为什么仅仅为了计算一加一等于几,我就要以特定的顺序在键盘上敲入这样毫无意义的字母呢?

(如果用 Matlab 当然不会有这些烦恼,所以我很多年前就自然而然学会了 Matlab。但是 Matlab 毕竟不是严格意义上的编程语言。当然我们还有 Python,不过这些都是题外话了。)

每次看到诸如「你用 Perl 还是 Ruby」或者「C 和 Java 哪个有前途」这样的问题,我都会觉得深深地疲倦。所有这些语言,每一种都有它特定的语法习惯,都有它极为莫名其妙的别扭要求。逻辑变量是单字节还是四字节?条件语句是花括号还是无括号缩进?矩阵排列是行优先还是列优先?世界上有这么多优秀的头脑要拿出这么多时间和精力来训练自己熟悉和掌握所有这一切毫不直观并且随时有可能过时的知识,究竟有什么意义?法语或者日语已经够难学了,但是学会了至少可以让自己更容易念萨特和川端康成的书。学会 Fortran 或者 Lisp 能干什么呢?

所以我一直试图避免让自己去学习任何一种诸如此类的语言。在我念 Ph.D. 的第一年,一个学长告诉我,和 Matlab 这类工具相比,C 的学习曲线要陡峭得多,但是最终能达到的高度也会远远超出。我想他说的是对的,但是我还是没有学。

二、

直到上周,由于某个工作上的原因,我忽然觉得自己应该试着学一学 C。大多数我平时的研究用 Matlab 都可以胜任,但是有些计算会牵涉到无法实现为整块矩阵运算的单元素遍历,也有些大数据量的工作会要求非常经济地管理内存,这都是 Matlab 的弱项。我手头的研究中一两个子函数就属于这类情况,如果能用 C 来实现它们再由 Matlab 调用,效率会高很多。

于是我就下载了一本谭浩强的 C 语言教程,从头看起。我原先的 C 语言水平无法保证我能从零开始写出一个 Hello world! 而不出错。我手头的问题需要我实现一个特定的图像变分去噪算法,而我连条件语句里逻辑判断的写法都不知道。

但是另一方面,我从不怀疑我事实上「会」编程──我只是不会用 C 把它写出来而已。对于整个算法的数学框架我烂熟于心,手头还有一个我自己写过的 Matlab 代码可资验算。如果我按部就班地从冒泡算法开始写起,我一定会迅速地厌倦学 C 这件事。而现在有一个看起来既艰巨又不是遥不可及的目标摆在前面,反而带来极大的动力。不让自己真正跑起来是学不会走路的。

一开始很难,无数令人焦头烂额的困难开始浮现,任何一个愚蠢的错误都要让我 google 半天。有的时候是我自己愚蠢,但是更多时候──我不得不说──是这门语言本身愚蠢。写 C 程序的过程本质上是一个自己挖空心思去模仿乃至取悦 CPU 和内存的过程,它极度不自然,无论在算法层面还是语法层面都是如此。

但是渐渐地,这件事情开始显示出乐趣来,特别是从我能够得心应手地操纵指针开始。分配内存,传递参数,规划指针遍历的路径,这些事情里蕴藏着类似于手工艺活般地精巧和灵活性。最短的几个子函数正确完成之后,后面的工作就像水银泻地一样展开。我开始沉迷于这件事情,无论是吃饭还是坐车上班还是在别人的讨论班上听讲,满脑子想的都是程序的写法,或者换一种排序方式,或者增加一个索引变量。前天工作到深夜终于完成框架,昨天早上爬起来又迫不及待地要开始调试细节,昨天睡觉之前终于得到和我预期分毫不差的测试结果,今天忍不住又想要把整个算法推倒重来,因为我觉得我又想到了一种新的循环结构,可以减少两个条件判断语句的调用次数。我知道它已经很快了,我还想要它更快。

直到刚才,我最后做完一遍测试,保存,退出。这不眠不休的兴奋感终于像潮水一样退去了。

三、

我学到了很多东西。我可以从此不用再羞于承认我并不会在「真正意义上」编程,我可以在以后的研究里用更快的程序来实现算法,找工作也会稍微多一点底气──如果我真的不幸要找这样一份工作的话。

但是我并没因此改变我对编程这件事情的看法。掌握一种新工具所带来的新鲜感是令人眩惑乃至沉迷的,但是也仅限于此。设计一个好的图像去噪模型,和给出一个精巧的代码实现相比,后者「亲自动手」的感觉要强烈得多,面对漂亮结果的成就感也强烈得多。但是这并不能改变它更容易也更无聊的事实。

为什么会有人喜欢把这种事情作为职业呢?

无论如何,我也许应该感谢它帮助我度过了这本来也许很难熬的一周。事实证明,越是难过的时候,就越是适合学新东西的时候。前面还有一个漫长的冬季在等着我,没准我可以把上面提到的所有语言都学一遍。

38 Responses to “Research Notes: 学 C 编程记”

  1. Annie
    October 16th, 2010 15:20
    1

    遇到技术困难的时候,都会感慨要是我会编程就好了。。。可是接下来又会反问–为什么要把时间投入在这个看起来很无聊而又极少能用到的地方呢。。。
    你这篇文大概无疑把这个过程美好话了,至少看上去是那样。

    赞最后一段,越是难过就越是要学新东西。至少怀着这种精神,有了点那么熬过前方漫长艰难冬天的勇气。。。

  2. Lan
    October 16th, 2010 17:03
    2

    我一直觉得学数学的人跟学CS的比起来就是怪兽,学起编程来都易如反掌呢

  3. hayate
    October 16th, 2010 17:10
    3

    不要看谭浩强的呀,看TCPL就好了
    C本来就不是给人带来编程乐趣的语言,它就是在机器上面一个简单的抽象

  4. yzq
    October 16th, 2010 18:34
    4

    心有亲戚

  5. 枯藤昏鸦
    October 16th, 2010 18:37
    5

    压力和兴趣一样,都是最好的老师

  6. Lazy
    October 16th, 2010 19:00
    6

    作为CS专业的人,看一个数学专业的人学C语言感觉很有趣。

    至于为什么会觉得写代码很有趣,原因因人而异。
    不过最核心的乐趣我想都差不多:就如同搭积木一样,用仅仅图灵完备的简单部件就能搭建出一个精密的玩具甚至是整个世界。这样的乐趣我想并不亚于数学

  7. fooy
    October 16th, 2010 19:06
    7

    码农无比惭愧的路过

  8. Shannon
    October 16th, 2010 20:28
    8

    最近正筹划用寒假自学下C…… 怎么听上去那么不靠谱啊

  9. passby
    October 16th, 2010 22:03
    9

    实现一个小算法当然就那么回事,博主要是做过操作系统,搜索引擎这样的大系统就不会觉得编程无聊了。

  10. hello world
    October 16th, 2010 22:07
    10

    要是没有从事无聊编程的coder们,博主怕是没有matlab用了。

  11. eliw
    October 17th, 2010 12:41
    11

    无论你使用什么样的语言,它们只是你想去做的事的工具而已。没必要对工具本身有这么大的意见吧。不爽就换别的或着试着去改进它。

  12. 上海永久
    October 17th, 2010 17:05
    12

    兴趣是王道。。。

  13. bluegene_hao
    October 18th, 2010 01:20
    13

    CS专业绝不是仅仅学语言(这也是很多非CS专业对CS的一种误解,语言只是最基本的东西);程序开发也绝不仅仅只是写代码;CS专业也绝不仅仅等同于程序开发(要不也不会有后面的这个S了);系统、算法、模式、架构、各种原理、方法论还有很多数学方面的东西。。。有太多太多吸引你的了。如果你还处在关注语言特性本身的这个阶段,可能是很难理解或是有这样的感受的。

    还有,语言是工具,编程是手段,通过这样的工具和手段去解决问题,才是最有魅力的事情,而所要解决的问题就可能涵盖许许多多方面,比如你面对的,人们生活中需要解决的,以及CS专业本身涉及的问题,而解决这些问题的方法会牵扯出很多理论,这些理论构成了CS的内涵,所以学CS的绝不仅仅是你说的“代码实现”。
    希望我把我想说的表述清除了 :)

  14. wealk
    October 18th, 2010 11:01
    14

    编程语言是要调和抽象的计算和具体实现的矛盾的,比如你说的#include;所以说,语言的分化,完全是因为语言的分工。

  15. Sha
    October 19th, 2010 00:45
    15

    同赞最后一段,不谋而合阿,当然不是说要学编程,我想学日语了,有兴趣的话一起学?hoho

  16. ant
    October 19th, 2010 09:59
    16

    关键要选择对入门书籍:

    http://book.douban.com/doulist/22051/

  17. lileding
    October 19th, 2010 21:04
    17

    英语语法也反人类,不知道你是喜欢学还是被逼无奈。学编程就好比学写字,写字比写诗容易得多,但诗人没理由看不上书法家。各有一好而已。

  18. 88250
    October 19th, 2010 21:44
    18

    作为一个中国码农:”Code for Food“。

  19. feyan
    October 20th, 2010 10:37
    19

    1,喜欢的事情做为职业,是一件很幸福的事情。
    2,不会C的世界也很精彩

  20. zhiqiang
    October 20th, 2010 16:52
    20

    我手头的问题需要我实现一个特定的图像变分去噪算法,而我连条件语句里逻辑判断的写法都不知道。
    ——————————————————————
    这些基本东西,会了一种语言,其余都大同小异。你这次学C这么快,是因为有了Matlab的基础 :)

    之前这么讨厌C,为何没讨厌Matlab呢

  21. Leroy
    October 21st, 2010 08:01
    21

    C++才是真正和蔼可亲的语言
    CS里,只有做底层硬件设计才用C。

  22. tenabaumn
    October 21st, 2010 14:09
    22

    楼主在数学的世界里畅游过后对比编程的乐趣可能就不是那么强烈了,其实大多数人的世界哪有那么多的介质去体验艺术,想象力,所以有编程的存在对一些人来说也许就是生活的主要乐趣来源了.又可以赚生存费.想冯若依曼当初也是数学奇才,才思敏捷,他能提出最初的计算机架构也许也是他想象力的延展.

  23. zcq
    October 22nd, 2010 11:27
    23

    订阅了博客,一直放在最下面,没时间的时候就直接点击已阅读。
    今天看了真的觉得很不错的博客~原来是别人推荐,未在意,现在呢,是真的喜欢上了~谢谢

  24. wl
    October 23rd, 2010 13:06
    24

    数学也不是一个工具么 也不是cs的工具么
    完成了一个相当于undergrad的入门课程如何就能claim这是更简单又更无聊呢

  25. 韶关家园
    October 26th, 2010 11:55
    25

    以前也没学好C 现在做代码工人。

  26. yang
    October 26th, 2010 13:30
    26

    LS有人解释了CS和写代码是两件不同的事。事实上CS系里存在着很多从来不写代码的老板。但是写代码是CS的一部分,并且是重要的。对于CS而言,很多时候只有真的把一件事实现出来,你才会明白what’s going on, where it goes wrong, and why tons of papers are just garbage.对于做数学的人而言好的模型可能足够了,但是有时候一个非常fancy的模型是不可能被用到实际的系统里去的。这个判断的能力,是靠实现来培养的。

    然后其实想解释一下“为什么会有人喜欢把这种事情作为职业呢?”

    其实我觉得有必要把写代码的人分成两类,一类人写代码,因为写代码是工作的全部。另一类人写代码,因为写代码是工作的一部分。对于第一类人,其实我不觉得他们真的喜欢这个职业。但这个世界提供了很多这样的职位,并且,这个职业从收入和乐趣的角度而言好过一些别的职业。对于第二类人,参考第一段。

    两类人都可以称为程序员,于是程序员既是这个世界上不需要使用大脑的职业中相对overpaid一群人,同时也是这个世界上需要使用大脑的职业中相对underpaid的一群人。他们既不快乐,又快乐。:)

  27. yang
    October 26th, 2010 13:37
    27

    另外我觉得你从事不是数学,而是EE。显然对你来说数学已经是纯粹的工具,而不是你研究的对象。CS跟EE在这一点上是一样的,模型和实现,各自重要的都是工具。

  28. ikbear
    October 26th, 2010 18:07
    28

    木匠工干的是木匠活,程序员干的是程序活,你做数学做算法干的也是一份活而已。如果你在自己领域没有天才般的创意,没有被大众认可的划时代的贡献,那么在外人看来你的工作也应该很无聊吧。
    本科的上高数课的时候,我一直在想,如果这些老师天天起来都是上同一本高数书,没有一点点创新,他们会不会觉得无聊?反正上课的我一想到这些是很无聊的。

  29. lambda
    November 7th, 2010 12:03
    29

    yang 说得很中肯。 +1

  30. 与非
    November 8th, 2010 20:16
    30

    木遥用过Mathematics没?
    个人感觉这个工具比Matlab还要个弓虽。

  31. Jun Zhou
    November 19th, 2010 17:42
    31

    谭浩强毁了众多 C 语言初学者

  32. 雨燕
    May 17th, 2011 16:27
    32

    计算机可以重新发明一遍,按照国人的文字趣味!

  33. gear
    March 29th, 2012 21:25
    33

    我是学CS的本科生,第一门语言就是C。木遥把C语言看的太轻了。码农这种工作确实无趣,是有创造性的人难以忍受的。但是以C语言为生的人恰恰不是码农。一个算法就是聚焦在一点上解决一个问题,所以数学人的程序不过百余行。如果程序量再大,这些函数如何架构,各部分如何工作都会是问题。大程序像个社会,一个聪明人不能解决什么问题,要大家协作才行。
    令:我猜想你的变量名用的类似A,AA,AAA,A1,A2……不知道对不对?

  34. gordon
    April 22nd, 2013 18:06
    34

    木遥的直觉是正确的,

    写 C 程序的过程本质上是一个自己挖空心思去模仿乃至取悦 CPU 和内存的过程,它极度不自然。

    程序语言的形式限制了程序员对程序关键部分的理解。于是伪代码(pseudocode)产生了,它是一种算法描述语言。

  35. Definiter
    September 22nd, 2013 22:21
    35

    计算概论…我现在正在上这门课,几年了?

  36. Stephen
    October 2nd, 2013 18:29
    36

    不同的语言有不同的作用,用筷子喝汤有困难并不全是筷子的错
    C语言非常贴近CPU的真实运算过程,这正是这门语言的优点和缺点所在,缺点在于很多高层次的运算描述,C语言做不了或者很麻烦,但正是C语言对CPU的贴近,利用C语言进行速度优化也就变得很直接,而其他语言要做这样的事情就依赖非常复杂的编译器实现,以及语言习惯对编译技术的妥协,所谓有得必有失

  37. xavier
    July 26th, 2014 18:15
    37

    oh,你居然用谭浩强那本书,感觉不到乐趣是应该的。。

  38. fancy
    January 12th, 2016 18:50
    38

    “掌握一种新工具所带来的新鲜感是令人眩惑乃至沉迷的,但是也仅限于此。”
    –有时候为了做某事,掌握工具是前提啊~

Leave a Reply