转载

C的那些事儿

C语言于我,主要是一门学习性的语言,这或许也是大多数人第一门接触到的计算机语言。当然时代在变,现在的学生也不一定要从C语言学起啦。C语言在Linux的世界有着举足轻重的地位。Linux内核是用C写的,Linux上的大部分应用也是用C写的。关键是,它们都是开源的!于是,如果你想进一步提高C语言的品味,Linux开源世界真的是海阔凭鱼跃,天高任鸟飞了。

C语言应该是最接近硬件底层的高级语言,可以很透明地操作任何硬件资源,如CPU/IO/内存等等,这使得它成为最理想的系统编程语言,包括对系统性能要求很苛刻的产品,如各种操作系统,数据库,播放器等等。

Linux无疑是谈论C语言的最佳场合。学过操作系统的人对Linux的C函数接口应该都不会陌生,如各种open, printf, pipe, fork, memset等等。我手头就有一本Linux C函数手册,不厚就两三百页,每个函数后面都有一个小例子演示其用法,它真是编写Linux上C程序的居家必备参考手册。

或许还应该提一下阅读C代码的一个利器,Source In Sight。它支持很多功能,如代码跳转,多功能搜索,函数、类、变量之间的各种关系图,文件列表等众多功能。Source In Sight给自己的一个自画像如下:

C的那些事儿

在Linux世界浩瀚的代码中,Source In Sight会让你少迷失点方向。

当然,Source In Sight给你的,也只是对代码的一个静态理解,里面有太多自己对代码运行的一厢情愿的假设,还有对代码运行的未知的迷惑。我更推荐的,当然是在代码运行时,生成各种函数之间真实的调用图,最好再明白告诉每个函数被调用的次数及执行时所占时间的百分比。这就是Linux下的一个很出名的工具:gprof。为了在一个程序上使用 gprof, 必须在编译程序时加上 -pg 选项 ,在程序运行时产生gmon.out文件。假设程序名为test。则执行下面语句,gprof ./test gmon.out,生成的输出会列出这个程序中每个函数被调用的次数、所花费的时间等各方面信息,当然还有函数之间的调用关系。

不过,gprof的输出是文本的,不大直观,可使用另一个工具对gprof的输出结果进行处理,形成函数调用关系图。这个工具就是cgprof。执行cgprof -Tps gprof.out > result.ps,再利用如Acrobat Distiller之类的工具,加工result.ps就可以得到函数调用图result.pdf文件。当然,cgprof也提供选项以直接在X Winow下面生成调用图。下图就是一个生成的函数调用关系图的例子:

C的那些事儿

C语言的可读性与维护性历来得不到什么好评,但由它所写成的程序却流传广泛,深入人心,如各种视频编解码模块,文本处理工具awk/sed等等。这或许应该得益于Linux平台的优雅的设计。这里最想提到的,就是Linux的管道功能,管道使得多个应用程序间可以无缝衔接,从而达到代码复用的目的。代码复用的第一个层次应该是C语言语句级的复用,如很多开源项目都是建立在更多的开源项目基础上;而代码利用的第二个层次就是二进制的复用,包括以类库的形式和以可执行文件的形式。Linux神奇的地方在于可以让以可执行文件形式的复用神不知鬼不觉地进行。比如,如果想实现对输出文件的压缩,只要把输出文件指定为FIFO管道文件,让程序往FIFO文件里写,再启动一些gzip进程,从管道中进行读取,边压缩边写回文件系统就行了。还比如,平常通过用grep,awk,xargs等等命令通过管道符|串起来的那一长串命令。想想在GUI环境下的一个单一程序中实现这些功能会是多么艰难的事情啊!

正文到此结束
Loading...