走出C语言教与学的误区--Written By My Teacher黄放明
走出C语言教与学的误区
前言
笔者从事软件开发已26年,用C语言编写有实际用途的程序(绝不是教科书或技术手册上的例子)也有20年了。进入高校讲授C程序设计10年以来,起初感觉有些不太对劲,随后,越来越觉得国内高校C语言教与学存在着许多问题。早就萌发写篇文章,以表己见的念头。但因终日忙于学习、探索,并将所学所教理论付诸实践,以求印证,进而真正理解,以利于教学,力免误人子弟,而无暇于笔砚之间。今逢C语言精品课程建设之际,又受领导指派,故斗胆提笔,不妥之处,望方家斧正。 此处要声明三点。
其一:笔者从未有想过,通过发表本文为本人捞取某种资本。那么,笔者在干扰了自己正常学习、研究的情况下,写此文章的目的到底是什么?一为完成任务,二为一吐心声!
其二:本文是写给那些讲授或学习C语言,但对C语言又不甚了解的人群的。故,对于真正了解C语言者,本文中大部分内容就是一堆废话。
其三:本文提及了某“权威”教材的一些诟病,并非有意批判。笔者与文中提及“权威”教材的作者,素不相识,更无厉害冲突。软件开发领域有许多重要的新知识新技术,笔者还需学习并实践,以利于教学。还有许多有意义的事情等着笔者去做。何来闲暇与人口水争斗?实因此教材影响太大,当然也影响了笔者正常教学,影响了笔者的学生正确地理解标准C语言。笔者讲课或辅导学生上机时,经常须花时间“拨乱反正”,以“正”学生“视听”。否则,就是对学生的不负责任,愧对良心。当然,选用此“权威”教材,属官方钦定,非笔者意愿。
一、C语言教与学中的误区和盲区
随着计算机技术的飞速发展,新的程序设计语言如雨后春笋,不断涌现。如:Java、C#、PHP、Python、Ruby、Lua、D、Erlang、Javascript等各领风骚。而“古老”C语言因其自身的特点,一直被世界各国大学作为最重要的程序设计语言课程。TIOBE程序设计社区的程序设计语言排行榜上,C语言几年来稳居第二,仍是现今最流行的程序设计语言之一。然而,在国内,C语言的教与学,存在着种种误区和盲区,严重影响了C语言教与学的实际效果,以致许多人对C语言是否能够真正用于实际软件开发产生了怀疑(除嵌入式系统外,因人们对于C语言用于该领域开发深信不疑),从而引发了C语言是否应该死亡的网络大讨论。这些误区和盲区主要表现为如下几个方面:
(一)缺乏对C语言的正确认识
1.对C语言标准及其重要性认识不足
众所周知,C语言是Bell-Labs在1972年,为设计UNIX操作系统而开发的。由于C语言小巧灵活、功能强大且通用,很快在全世界流行。然而,不久后,不同编译器厂商对C语言的实
现之间,存在着一些微妙的差异,这些差异形成了不同编译器厂商的“方言”。各种“方言”损害了C语言的主要优势(或重要特点)——可移植性,同时也给C程序员带来麻烦。为了解决这些问题,ANSI于1983年成立了一个委员会,以确定C语言的标准定义。经过多次修订,C语言标准于1988年完成,并于1989年12月正式通过,成为ANSI标准X3.159-1989(称为ANSI C)。1990年ISO通过此项标准,将其作为ISO/IEC 9899:1990国际标准,称为标准C(1989)或简称C89。其后,WG14(C语言国际标准化工作组)对C89进行了适当的修订或增补,于1995年发布了C95标准。自1995年起,WG14对C语言标准作了更大的修订,于1999年完成并通过,形成了C语言的最新正式标准,即ISO/IEC 9899:1999或称C99。
制定C语言标准的目的有三:
1.消除差异:尽量消除不同编译器厂商对C语言实现上的“方言”; 2.修正缺点:规范已存在的编程习惯,以弥补C语言中的明显缺陷; 3.增强可移植性:以标准来力保C程序的可移植性。 当然,制定C99标准还有两个目的: 4.支持国际开发(支持国际字符集)
5.改进C语言对科学和工程中关键数值计算的适应能力
通常,业界把C89以前的C语言实现称为传统C(Traditional C),而把遵循或支持C89、C99,特别是C99的C语言实现称为现代C(Modern C)。
在国内,最流行的编译器莫过于Turbo C 2.0和Visual C/C++ 6.0。那么,这两种编译器究竟属于哪种?是传统C还是现代C?看看它们的诞生年代和语言特性就知道了。Turbo C 2.0诞生于1987年,在当时是最好的C编译器和IDE。显然,Turbo C属于传统C再加Borland实现的“方言”。Visual C++ 6.0虽然是1998年左右的产品(笔者记不太清了),但其中充斥着大量的宏(Macro)和不标准的语法。
对于教授和学习C语言,应该以标准C为主还是以“方言”,笔者想:无须争论。就如同幼儿园教小孩语言,应以普通话为主还是以方言为主一样。
然而,直至2009年,国内出版的有些C语言书籍仍然是“基于Turbo C 2.0环境”。有些书的作者还这样写道:对于C语言的标准,不同厂商表现出不同的兴趣(一句话就轻轻地将标准的重要性淡化或抹杀,还为后句话打下“理论基础”。厉害!),因此,本书的内容仍基于Turbo C……。有些“权威”教材虽声称其内容是讲授ANSI C,可书中内容和标准相去远矣!例题中,许多是C标准所不允许的。
由于对C语言标准的不了解,以及不正确的认识,使得在许多人心目中,C就是Turbo C,C++就是VC,Turbo C就是C,VC就是C++。大有非Turbo C、VC不教,非Turbo C、VC不学之势。常见于国内各类技术论坛上关于C语言的帖子,就足以看出:许多人对于什么是标准?什么是“方言”分不清楚!比如:许多人把getch()函数误以为是标准函数(当然也把conio.h头文件以为是标准头文件),为把含有void foo()这样函数原型的源程序在VC6.0以上版本或在现代C编译器(如:GCC、Digital Mars C/C++、Pelles C)中编译通不过而大喊大叫。类似例子实在举不胜举。
以上说明:许多C语言的教授者和学习者,对C语言标准及其重要性认识不足。
2.对C语言的缺陷认识不足
国内许多教科书,只告诉读者:C语言有多么多么好,功能有多么多么强大,但却从不提C语言有哪些缺陷,以及如何才能规避这些缺陷。甚至将一些缺陷而导致的不良编程习惯,当成C语言的特点而渲染。{举例}从而导致许多人不了解C语言的缺陷,以及规避缺陷的有效方法。关于C语言的缺陷,以及如何规避缺陷,有关书籍和资料中有详尽叙述。
3.将编译器与IDE混为一谈
众所周知,程序设计使用的主要工具有: l 编辑器:书写源程序的工具
l 编译器:将源程序翻译成目标程序的工具
l 连接器:连接目标程序、库代码、启动代码的工具 l 调试器:分析可执行程序错误的工具
l 集成化开发环境(IDE):集成编辑器、编译器、调试器、工程管理于一体
这样就可以,IDE用CodeBlock,而编译器配置MinGW或VC2003等;也可IDE用Eclipse或NetBeans,而编译器配置GCC或Digital Mars C/C++;还可编辑器用EditPlus或UltraEdit或Geany等,而编译器配置Borland C/C++5.5.1、Pelles C、Watcom C/C++、TinyC等,总之,相当灵活,随心所欲。
然而,许多人将编译器与IDE混为一谈。这些人一般只会用IDE,离开了IDE将不会写程序。究其原因:都是初学时直接用Turbo C或Visual C这两种IDE给害的(参见“IDE综合症”)。
(二)教学内容轻重失当
1.程序设计思想没有真正得到应有的重视
程序设计语言教学,应以语言为主还是以程序设计思想为主,曾有过争论。笔者想从用计算机解决实际问题的过程,来分析程序设计思想和程序设计语言在其中所起的作用,从而明了两者在解决问题时所占的分量。
众所周知,模型是对客观世界中复杂事物的抽象描述,算法是求解模型的方法,程序设计语言则是对算法的实现手段。算法是解决问题的具体步骤,从程序设计角度看,就是程序逻辑。程序设计思想既包括了算法,当然还包括程序的组织(如模块及其职责的划分),以及设计策略(如:自
顶向下,逐步求精;测试驱动;小步迭代等)。由此可见,程序设计思想在解决问题是所占的分量远远大于程序设计语言。
当然,C语言作为程序设计的入门课程,不可能,也没有必要大讲特讲程序设计思想。然而,比语言元素和特征更为重要的程序设计思想,不能因为C语言是程序设计的入门课程,而忽略或忽视对它的教授与训练。
尽管许多教科书上也提及软件工程、算法等程序设计思想内容,有些也强调了它的重要性,但轻描淡写有余,贯彻落实不足。
2.八股式的死扣语法
说到对语法的讲授与训练,不是为应用而讲语法,而是为语法而语法。甚至八股式的死扣语法,比如:int a=21, b=11;printf( \等。
3.为算法而算法
http://www.ioccc.org
(三)教材选取或盲目崇拜“权威”或低水平抄袭
笔者以叙述如下一段事情来作为本段的开场白:
Herbert Schildt是ANSI/ISO中C语言标准化委员会的委员,若在我们国内,该算是权威了吧。他编写了《C The Complete Reference》(有中译本)这本书,按我们国内的逻辑,这本书出自权威之手,应该很好,理应推崇。可是,国外读者,特别是西方发达国家的读者,并不买他的帐。他的这本书在C语言社团中广为人诟病,在西方许多C/C++推荐书籍列表上(如http://www.iso-9899.info/wiki/Books ), 赫然写着不应该购买此书(还可参见:可怜的Herbert Schildt,兼谈我的C语言书籍阅读
http://blog.chinaunix.net/u/12391/showart_118977.html )。
言归正传,笔者要说的是:我们对C语言的理解、掌握和运用远不如西方发达国家,如美国甚至巴西等国。美国就不用说了,许多原创性技术出至美国大学,就连巴西的大学也有许多原创性技术被业界认可(如Lua-开发“魔兽”游戏的程序设计语言,其解释器用标准C写就,跨绝大多数平台)。迄今为止,我们泱泱大国的大学,没有任何运用C语言而研发的被业界认可的原创性技术。但我们对所谓“权威”的盲目崇拜或迷信却远远超过了西方发达国家。笔者只能用一句前人的话结束这个话题:盲目崇拜或迷信的代名词是无知和愚昧!
国内C语言教材有500多种,可谓是“品种丰富”,“一片繁荣”。随便拿来几本看看,许多相互低水平抄袭。比如:有“权威”教材中关于描述算法的N-S图,这样叙述到:这种流程图适于结构化程序设计,因而很受欢迎。果真如此吗?此书作者能否找到一本2000年以后出版的、受到好评的关于算法或程序设计的国外教材或书籍,其中还用N-S图描述算法?笔者读过的、受到好评的国外教材书籍(近20本)中,从未见过用N-S图描述算法,何来很受欢迎一说?尽管如此,可N-S图在国内的确“很受欢迎”。烦请在教材中用N-S图描述算法的作者,在实际软

