- UID
- 1
- 斋米
-
- 斋豆
-
- 回帖
- 0
- 积分
- 65020
- 在线时间
- 小时
- 注册时间
- 2009-12-26
- 最后登录
- 1970-1-1
|
要写好C语言程序,最重要的当然是把要解决的问题分析清楚,设计好解决问题的方案和通过计算实现求解的过程,对问题的求解过程进行科学的结构化的分解。在此基础上进一步考虑如何写程序的时候,下面的建议可能有所帮助。
+ Q3 v1 d% r( Y3 L4 q7 s- Q3 t5 W这些建议中有些是一般性的,不仅仅对C语言程序设计有效;也有些是特别针对C语言程序设计的。这个表还会进一步修改和扩充,欢迎提出意见。 3 a1 A5 f: ]/ u3 f+ [) x
________________________________________ / W5 l# Z) q4 H5 A+ S
1)应该特别注意程序的书写格式,让它的形式反映出其内在的意义结构。 ' x; m/ w% p3 h" K3 u. e8 h
程序是最复杂的东西(虽然你开始写的程序很简单,但它们会逐渐变得复杂起来),是需要用智力去把握的智力产品。良好的格式能使程序结构一目了然,帮助你和别人理解它,帮助你的思维,也帮助你发现程序中不正常的地方,使程序中的错误更容易被发现。 m3 I" d& V; P
人们常用的格式形式是:逻辑上属于同一个层次的互相对齐;逻辑上属于内部层次的推到下一个对齐位置。请参考本课程的教科书或《C程序设计语言》(The C Programming Language,Brian W. Kernighan & Dennis M. Rirchie,清华大学出版社,大学计算机教育丛书(影印版,英文),1996。)
, `5 E: B8 a6 h8 V0 U$ J利用集成开发环境(IDE)或者其他程序编辑器的功能,可以很方便地维护好程序的良好格式。请注意下面这几个键,在写程序中应该经常用到它们:Enter键(换一行),Tab键(将输入光标移到下一个对齐位置——进入新的一个层次),Backspace键(回到前一个对齐位置——退到外面的一个层次)。
) u ?6 I5 ^ [# e+ }________________________________________ & J7 y1 ]4 G! [
2)用最规范的、最清晰的、最容易理解的方式写程序。注意人们在用C语言写程序的习惯写法,例如教科书中解决类似问题时所使用的写法,《C程序设计语言》一书中有许多极好的程序实例。在这里有一个关于程序模式的相关网页,里面也列出了一些常用的模式。 % E/ U6 ]( r5 R8 Q2 ?2 h2 `
C语言是一个非常灵活的语言,你可能在这里用许多非常隐晦的方式写程序,但这样写出的程序只能是作为一种玩意儿,就像谜语或者智力游戏。这些东西可以用于消磨时间,但通常与实际无缘。在我们的C语言讨论组里提到过这种东西。
; k( u* T2 E$ l________________________________________ ; q+ l5 ^! {7 r& F1 w' U' |
3)在编程中,应仔细研究编译程序给出的错误信息和警告信息,弄清楚每条信息的确切根源并予以解决。特别是,不要忽略那些警告信息,许多警告信息源自隐含的严重错误。我们有许多办法去欺骗编译程序,使它不能发现我们程序中的错误,但这样做最终受到伤害的只能是自己。
N' _# D1 @ K* A1 S( B________________________________________
" ?- M. c# Z! x1 j4)随时注意表达式计算过程和类型。注意运算符的优先级和结合顺序,不同类型的运算对象将怎样转换,运算的结果是什么类型的,等等。在必要的时候加上括号或显式的类型强制转换。
: M6 Y$ t! j, Z% ~: EC语言的运算符很多,优先级定义也不尽合理,很难完全记清楚,因此要特别注意。需要时查一查(不要怕麻烦,相关网页有运算符表),或者直接按照自己的需要加上几个括号。 . Z G2 L. |. C! a
________________________________________
- h( @' g& R$ ]8 l9 C! F$ T5 v5)绝不去写依赖于运算对象求值顺序的表达式。对于普通二元运算符的运算对象,函数调用的各个实际参数,C语言都没有规定特定求值顺序。因此,我们不应该写那种依赖于特定求值顺序的表达式,因为不能保证它一定得到什么结果。例如下面的表达式和函数调用都是不合适的,很可能产生你预料不到的结果: 9 b" o% A/ g- R" T
scanf("%d %d", i++, a[i ]);;
) a' S) }3 k+ D7 R$ W' H" xm = n * n++;
) [ } B& x S" @! j6 G4 ^-------------------------------------------------------------------------
2 E k7 y3 A0 o1 z: e6)总保证一个函数的定义点和它的所有使用点都能看到同一个完整的函数原型说明。参看《从问题到程序》第103-107页。 . n( N0 h6 d, h5 n0 _
________________________________________ 3 K7 Q; a }, F: _% y) h
7)总注意检查数组的界限和字符串(也以数组的方式存放)的结束。C语言内部根本不检查数组下标表达式的取值是否在合法范围内,也不检查指向数组元素的指针是不是移出了数组的合法区域。写程序的人需要自己保证对数组使用的合法性。越界访问可能造成灾难性的后果。 0 C- q- }$ s# \8 M. {( G- ]6 R
例:在写处理数组的函数时一般应该有一个范围参数;处理字符串时总检查是否遇到空字符'\0'。
. T7 C$ c+ y! H X' C, x' K________________________________________ 6 @5 Q9 s1 u& D& |: Q3 u
8)绝不对空指针或者悬空的指针做间接访问。这种访问的后果不可预料,可能造成系统的破坏,也可能造成操作系统发现这个程序执行非法操作而强制将它终止。 4 C3 f1 N4 b$ Q
________________________________________
8 G2 h4 k4 t1 s9)对于所有通过返回值报告运行情况或者出错信息的库函数,都应该检查其执行是否正常完成。如果库函数没有完成操作(可能因为各种原因),随后的操作有可能就是非法的。这种错误也可能在程序运行中隐藏很长时间,到很后来才暴露出来,检查错误非常困难。 ' m+ N( G; |; K6 ]3 ^5 d! e, r
________________________________________ 4 W1 s7 ]- [" l2 A( w ?
10)在带参数宏的定义字符串中,一般应该给整个字符串和其中出现的每个参数都加括号。
( V, w1 R8 I% Q; G) b/ h+ _4 F7 I- CC语言预处理程序是个简单的文本替换程序,它根本不知道C语言的语法结构、优先级规则等。不写括号有时会产生我们不希望的代换结果。
8 s. T9 ~7 {1 }; G" f1 Y________________________________________ 6 r" H$ ^1 G: p, {5 Z
11)所有外部变量名字、所有函数名字,应该只靠前6个字符就能够互相区分。因为有些老的编译程序只关注这些名字的前6个字符。如果不注意这个问题,就可能引起隐含的连接错误。 + G" o1 R0 N3 A! ^% d* V: v' A/ h7 ^
________________________________________
6 \) U. U1 a, a4 @- G/ ~( M有关如何写好程序,如何将自己发展成为一个高水平的计算机工作者(真正的高级程序工作者,而不是那种拿证书的所谓“高级程序员”)还需要进一步学习和实践。如果希望向这个方向努力,一本书可能对你有所帮助:
3 E& g q- I& S《程序设计实践》,(The Practice Of Programming, Brian W. Kernighan & Bob Pike 1999)。机械工业出版社2000。这本书讨论了程序设计的许多重要的实践性问题,值得每个学过一个程序设计语言,有些程序设计经验,热爱或梦想在计算机领域工作的人阅读参考。 |
|