Have you ever…


wasted a lot of time coding the wrong algorithm?


used a data structure that was much too complicated?


tested a program but missed an obvious problem?


spent a day looking for a bug you should have found in five minutes?


needed to make a program run three times faster and use less memory?


struggled to move a program from a workstation to a PC or viceversa?


tried to make a modest change in someone else’s program?


rewritten a program because you couldn’t understand it?


Was it fun?


These things happen to programmers all the time. But dealing with such problems is often harder than it should be because topics like testing,debugging, portability,performance, design altematives, and style–the practice of programming–are not usually the focus of computer science or programming courses. Most programmers learn them haphazardly as their experience grows, and a few never learn them at all .In a world of enormous and intricate interfaces,constantly changing tools and languages and systems, and relentless pressure for more of everything, one can lose sight of the basic principles–simplicity,clarity, generality–that form the bedrock of good software. One can also overlook the value of tooIs and notations that mechanize some of software creation and thus enlist the computer in its own programming.

    这些事发生在整个程序员的生涯过程中。但是处理类似问题经常比较困难,因为一些课题,像测试,调试,移植,性能,交互设计,和风格---编程实践---并不总是将焦点集中在计算机科学或者是教学上完成。有许多的程序员都是在,偶然的机会和杂乱的荆棘中前行,有人并未真正的学习过他们这些,都在野蛮生长。在一个庞杂瞬息万变的世界,工具,语言,系统都日新月异,还有更多周遭无情的压力。一个人可以忽略基本的原则---简单,明了,通用---构成了优秀软件的基石。 可以忽略用符号工具去机械性软件创造,驾驭计算机自我编程。

Our approach in this book is based on these underlying,interrelated principles,which apply at all levels of computing. These include simplicity, which keeps programs short and manageable; clarity, which makes sure they are easy to understand,for people as well as machines; generality,which means they work well in a broad range of situations and adapt well as new situations arise; and automation, which lets the machine do the work fOr us,freeing us from mundane tasks. By looking at computer programming in a variety of languages, from algorithms and data structures through design, debugging,testing, and performance improvement, we can illustrate universal engineering concepts that are independent of language, operating system, or program In ing paradigm.

    在这本书中我们的力图, 基于最根本的相关原则,适应于所有级别的处理。 包括简单, 保持程序的短小可管理,清晰, 确保他们容易理解, 不仅人还有机器。一般来说, 意味着在一个广泛的情况范围内可以很好的工作, 并可以适应新的情况发生。 并且自动化, 让机器完成我们的工作,让我们从事务性的工作中解放出来, 放眼看各种计算机语言,从算法和数据结构到设计,调试,测试,性能改进, 我们阐述的一般性工程概念不依赖于语言, 操作系统或是程序规范。 

This book comes from many years of experience writing and maintaining a lot of sotiware, teaching programming courses, and working with awide variety of programmers. We want to share lessons about practical issues,to pass on insights from our experience, and to suggest ways for progran1mers of a1I levels to be more proficient and productive.

    这本书源于许多年的写作经验和大量的软件维护,教授计算机课程,并且工作于广泛领域的程序员,我们要共享关于实践课题的课程。通过我们的经验的视角, 启发所有级别的程序员提高生产性(多产熟练),

We are writing for several killds of readers. If you are a student who has taken a programming course or two and would like to be a betterprogrammer, this book will expand on some of the topics fOr which there wasn’tenough time in school. If you write programs as part of your work. but in support of other activities rather than as the goal in itself, the informationwill help you to program more effectively. If you are a professional programmer who didn’t get enough exposure to such topics in school or who wotlId like are fresher, or if you are a software manager who wants to guide your staff inthe right direction, the material here should be of value.

     我们的受众多,书使用面积广泛, 如果你是学生,可以通过一两个编程课程成为更好的编程者,这本书扩展了很多学校没时间完成的主题。 如果写程序是你的工作, 但还有有其他的活动,而不单是目标本身(工作不是单纯的编程)。 这个信息可以让你的程序更高效。 如果你职业程序员, 没有吸收足够的在校课程, 或是像个初学者, 或者你是个软件经理,想指引你的雇员奔向真确的方面, 这里的材料都应该很有价值。

We hope that the advice will help you to write better programs. The only prerequisite is that you have done some programming, preferably in C, C++or Java. Of course the more experience you have, the easier it will be; nothing can take you from neophyte to expert in 21 days. Unix and Linux programmers will find some of the examples more famiIiar than will those who have used only Windows and Macintosh systems, but programmers from any environrnent shou1d discover things to make their lives easier.


The presentation is organized in to nine chapters, each focusing on one major aspect of programming practice.


Chapter 1 discusses programming style. Good style is so important to good programming that we have chosen to cover it first. Well-written programs are better than badly–written ones–they have fewer errors and are easier to debug and to modify-so it is important to think about style from the beginning. This chapter aIso introduces an important theme in good programming,the use of idioms appropriate to the language being used.


Algorithms and data structures, the topics of Chapter 2. are the core of the computer science curriculum and a rnajor part of programming courses. Since most readers will aIready be familiar with this material, our treatment is intended as a brief review of the handful of algorithms and datastructures that show up in almost every program. More complex algorithms anddata structures usually evolve from these building blocks, so one shouId master the basics.

    第二章节讲的是算法和数据结构,是计算机科学的核心部分,也是编程课程的主要部分。因为大多书的读者已经熟悉这些材料,我们的处理方针是,概要性的回顾少数的算法和数据结构, 这几乎出现在每个程序中,而更复杂的算法和数据结构,通常也是有这些发展构筑而成,应该作为基础掌握。

Chapter 3 describes the design and implementation of a smallprogram that illus-trates algorithm and data structure issues in a realistic setting. The program is implemented in five languages; cornparing the versions shows how the same data structures are handled in each, and how expressiveness and pertbrmance vary across a spectrum of languages.    Interfaces between users, programs, and parts of programs are fundamentaI in programming and much of the success of software is determined by how well interfaces are designed and implemented.

    第三章描述的是设计和实现一个小的程序,举例说明现实中的算法和数据结构的课题。 程序用了五种语言实现,比较展示了不同版本的语言是如何的处理相同的数据结构的, 如何表现不同语言的程序表达能力。在用户和程序之间是界面,是程序编写的基础部分。很多软件的是否成功,也取决于如何设计更好的设计界面,并将其实现的。

Chapter 4 shows the evolution of a small library for parsing a widely used data format. Even though the example is small, it illustrates many of the concerns of interface design f abstraction, information hiding, resource management, and error handling. Much as we try to write programs correctly the first time, bugs, and therefore debugging, are inevitable.

    第四章,展示了一个广泛被使用的数据格式的解析库的演化过程,这个例子非常小,阐述了很多用户界面设计的抽象观点, 信息隐藏,资源管理,还有错误处理 。更多的时候我倾向于在第一时间写出正确的程序,不过出现bug和调试bug又在所难免的。

Chapter 5 gives strategies and tactics for systematic and effective debugging. Among the topics are the signatures of common bugs and the importance of “numerology,” where patterns in debugging output often indicate where a problem lies.Testing is an attempt to deve1op a reasonable assurance that a program is working correctly and that it stays correct as it evolves.

    第五章是系统化高效调试的战术战略。 话题围绕着鲜明常见的bug和重要的“命理学”, 调试的模式输出,经常是直接指向问题所在行。测试是合理的确保开发的程序可以工作的正确,并且正确的演变。

The emphasis in Chapter 6 is on systematic testing by hand and machine. Boundary condition tests probe at potential weak spots. Mechanization and test scaffolds make it easy to do extensive testing with modest effort. Stress tests provide a different kind of testing than typical users do and ferret out a different class of bugs.Computers are so fast and cornpilers are so good that many programs are fast enough the day they are written. But others are too slow, or they use too much memory, or both.

    重点是在第六章,是手动和机器的系统测试。 边界测试探寻潜在的薄弱点。机械化和测试脚手架是大量的测试变得简单合理有效。压力测试提供了和典型的用户测试不一样的测试,可以刺探出不同类别的bug. 计算机神速,编译器优秀,他们写的很多的许多程序都足够的快,但是其他方面却很慢,或者是他们使用了很多的内存,或者两者共存。

Chapter 7 presents an orderly way to approach the task of making a program use resources effcientIy, so that the program remains correct and sound as it is made more efficient.


    Chapter 8 covers portability. Successful programs live long enough that their environment changes, or they must be moved to new systems or new hardware or new countries. The goal of portability is to reduce the mainntenance of a program by minimizing the amount of change necessary to adapt it to a new environment.   Computing is rich in languages, not just the general-purpose ones that we use for the bulk of programming, but also many specialized languages that focus on narrow domains.

    第八章涵盖的是可移植性。成功的程序生命力强,以至于他们的环境改变,哪怕是他们必须迁移到新的系统或是新的硬件,或是新的国家语言。全球化和可移植性,能减少程序维护量,做最小的变动,适应新的环境变化。 计算语言丰富, 我们使用的大部分程序都是多用途的。但也有很多特殊的语言聚集在窄领域。

    Chapter 9 presents several examples of the importance of notation in computing, and shows how we can use it to simplify programs, to guide implementations,and even tO help us write programs that write programs.

    第九章提出了一些重要的计算“记法”的例子, 展示我们可以使用其使编程简单, 引导实现, 甚至是助我们编程一臂之力。

To talk about programming, we have to show a lot of code. Most of the examples were written expressly for the book, although some small ones were adapted from other sources. We’ve tried hard to write our own code we1l, and have tested it on half a dozen systems directly from the machine-readable text.More information is available at the web site f Or The

    讨论编程, 我们有大量的代码, 大多数的程序都明确写在了书上,虽然其中一些源于她源。 我们努力把我们的代码写好, 并经过测试,在半打系统上可直接处理这些文本,更多的可用信息在网站上。

    Practice Of Programming:

    http: //tpop. aw1. com


The majority of the programs are in C, with a number of examples inC++ and Java and some brief excursions into scripting languages. At the lowest level, C and C++ are almost identical and our C programs are valid C++ programs as well. Cand Java are lineal descendants of C, sharing more than a little of its syntax and much of its efficiency and expressiveness, while adding richer type systems and libraries.In our own work, we routinely use aIl three of these languages, and many others. The choice of language depends on the problem: operating systems are best writt Cn in an efficient and unrestrictive language like C or C, quick prototypes are often easiest in a command interpreter or a scripting language like Awk or Perl; for user interfaces, Visual Basic and Tcl/Tk are strong contenders, along with Java.

    主要的编程语言还是C, 还有一定数量的C++和Java程序,还有一些脚本语言的摘要。 在底层 C和C++几乎是相同的,C和C++都很好,C++和JAVA都是C的衍生语言, 共享了一些小的语法和更多有效的表达式, 又添加了丰富的系统库, 在我们的工作中, 三种语言通常都使用, 许多其他方面, 选择语言依赖于面向的问题,操作系统最好用C写更高效,并且不受约束,就像C,C++,完成快速原型经常使用最简单的命令解释型或是脚本语言,像Awk或是Perl, 完成用户界面就用,VB和Tcl/T ,是JAVA非常强劲的竞争对手。

There is an important pedagogical issue in choosing a language for our examples.Just as no language soIves all problems equal1y well, no single language is best for presenting aIl topics. Higher-level languages preempt some design decisions. lf we use a lower-level language, we get to consider alternative answers to the questions, by exposing more of the detaiIs, we can talk about them better. Experience shows that even when we use the facilities of high-Ievel languages, it’s invaluable to know how they relate to lower-level issues, without that insight, it’s easy to run into performance problems and mysterious behavior. So we will often use C for our examples, even though in practice we might choose something else.

    最重要的一个课题就是选择语言,对于我们就是个例子。 没有任何语言可以很好的解决所有的问题。没有一个单独的语言能最好的表述所有主题。高级语言取代了一些设计决策。我们使用低级语言,要知其然,并知其所以然。通过引出很多的细节,更便于讨论。 经验显示,甚至是当我们使用了高级语言或设备, 知道底层原理也大有裨益,如果这些含混了, 很容易陷入性能问题和对莫名其妙,诡异行为的不解。 所以我们经常使用C做例子, 尽管在实践过程中还有其他的选择。

For the most part, however, the lessons are independent of any particular programming language. The choice of data structure is affected by the language at hand; there may be few options in some languages while others might support a variety of alternatives. But the way to approach making the choice will be the same. The details of how to test and debug are different in different languages, but strategies and tactics are similar in all. Most of the techniques for making a program efficient can be applied in any language.


Whatever language you write in. your task as a programmer iis to do the best you can with the tools at hand. A good programmer can overcome a poor language or a clumsy operating system, but even a great programming environment will not rescue a bad programmer. We hope that, no matter what your current experience and skill, this book will help you to prograhi better and enjoy it more. We are deepIy grateful to friends and colleagues who read drafts of the manuscript and gave us many helpful comments. Jon Bentley, Russ Cox, JohnLakos, John Linderman, Peter Memishian, Ian Lance Taylor, Howard Trickey, andChris Van Wyk read the manuscript, some more than once, with exceptional care and thoroughness.

    无论你用什么语言写,程序员都用手中最好的工具去完成任务。一个好的程序员可以克服差劲的语言和糟糕的操作系统,但是好的开发环境也无法拯救一个坏的编程者。我们希望的是,无关你当前的水平程度, 这本书将会更好的帮助你编程,并乐在其中。我们深深的感谢朋友和同事们,阅读草稿和原稿,给了我们很多妙语良言的点拨,从而受益匪浅。Jon Bentley, Russ Cox, JohnLakos, John Linderman, Peter Memishian, Ian Lance Taylor, Howard Trickey, andChris Van Wyk 阅读了原稿,如琢如磨,反复推敲。

We are indebted to Tom Cargi1l, Chris Cleeland, Steve Dewhurst, EricGrosse,Andrew Herron, Gerard Holzmann, Doug Mcllroy, Paul McNamee, PeterNelson,Dennis Ritchie, Rich Stevens, Tom Szymanski, Kentaro Toyama, John Wait,DanielC. Wang, Peter Weinberger, Margaret Wright, and Cliff Young forinvaluable comments on drafts at various stages. We also appreciate good adviceand thoughtful suggestions from Al Aho, Ken Arnold, Chuck Bigelow, JoshuaB1och, Bill Coughran,Bob Flandrena, Renee French, Mark Kernighan, Andy Koenig,Sape Mullender, Evi Nemeth, Marty Rabinowitz, Mark V. Shaney, BjarneStroustrup, Ken Thompson, and Phil Wadler. Thank you all.

   我们要感谢Tom Cargi1l, Chris Cleeland, Steve Dewhurst, EricGrosse,Andrew Herron, Gerard Holzmann, Doug Mcllroy, Paul McNamee, PeterNelson,Dennis Ritchie, Rich Stevens, Tom Szymanski, Kentaro Toyama, John Wait,DanielC. Wang, Peter Weinberger, Margaret Wright, 和Cliff Young forinvaluable comments on drafts at various stages. We also appreciate good advice和 thoughtful suggestions from Al Aho, Ken Arnold, Chuck Bigelow, JoshuaB1och, Bill Coughran,Bob Flandrena, Renee French, Mark Kernighan, Andy Koenig,Sape Mullender, Evi Nemeth, Marty Rabinowitz, Mark V. Shaney, BjarneStroustrup, Ken Thompson 和 Phil Wadler,谢谢你们!

Brian W Kernighan

Rob Pike

本文译自Brian W. Kernighan和Rob Pike的《程序设计实践》一书的前言部分。