`
civili
  • 浏览: 23979 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[译]如何设计程序-第一部分

阅读更多
 

第一部分   处理简单的数据形式

 

 

 

第一节  学生,教师和计算机

 

 

 

在很小的时候我们就学习计算。一开始我们仅仅会加法和减法。像:

 

一加一等于二。五减二等于三。

 

更大一些的时候我们学习更多的数学运算,像求幂和正弦,我们也学习描述计算的规则。像:

 

给出一个半径为r的圆,它的周长等于r乘以2乘以pi.最低工资保障劳动者工作N小时的工资等于N乘以5.35美元。

 

这显示了这样一个事实,那就是教师把我们变成一台计算机并且给我们编程去执行简单的计算机程序。

 

于是,秘密揭开了。计算机程序只不过是非常快速的学生。在我们辛苦的计算一次加法的时候它们已经完成了上百万次。而且计算机程序不仅仅能做数值运算。它们还能引导飞机,能玩游戏,能查找电话号码,能为大公司打印工资单。总之,计算机处理一切信息。

 

 

 

人们用英语表示信息和指令。

 

35摄氏度,转换为华氏温度。一辆汽车从0加速到100公里每小时需要35秒,请问20秒它可以加速到多少公里每小时。

 

然而,计算机不能理解基本的英语更不能理解用英语表示的复杂指令。所以我们必须学习计算机语言和计算机交流信息和指令。

 

指令和信息的计算机语言叫编程语言。在编程语言中信息叫做数据。有许多种数据,数是其中一种。数列是复合数据,因为每个数列由其他一些被称为数的更小数据片段组成。为了区分这两种数据,我们称数字为原子数据。字母也是原子数据;家谱是复合数据。

 

数据表示信息,但是具体的解释由我们给出。比如:37.51可能表示温度,时间,或距离。字母"A"可能表示年级,鸡蛋的质量标志,或者地址的一部分

 

像数据一样,指令(也叫操作),也有好几种。每一类数据带着一堆原始操作集合。对于数,我们很自然的+-,*,等等。程序员把原始操作编写进程序。因此,我们可以认为原始操作是一门外语的单词,程序是由这种语言写成的。

 

一些程序就像文章那么小,其它的则像的集合那么大。写好的文章和书需要小心的计划,写好的程序一样。不管是小的或大的,一个好的程序不能被建立 。它必须被小心的设计。每一片都需要大量的关注;合并程序到大的单元必须遵循一个计划良好的策略。设计程序我们编程的第一天。

 

在本书中,我们将学习怎样设计计算机程序,同时我们还将学会理解他们的功能。成为一个程序员是快乐的,但是那并不容易。作为一个程序员,最好的部分就是看到我们的产品慢慢成长并最终成功。观察一个计算机程序玩游戏是很有趣的。看到一个计算机程序帮助人们是很 。为了达到这点,我们必须练习许多技能。

 

给一台计算机编程需要耐心和专心。仅仅是关注微小的细节就能避免犯很多错误。

 

让我们开始吧!

 

 

 

 

第二节 数,表达式,简单的程序

 

最初,人们仅仅把计算机当成数字计算器。确实,计算机做数字工作做的非常好。因为教师以算数开始他们的第一课,我们也从数开始。一旦我们知道计算机如何处理数字,我们就能不花时间的开发简单的程序。我们仅仅翻译一般语句到我们的程序记号。仍然,甚至开发如此简单的程序也需要理论,所以我们介绍最基础设计理论的大纲,以及基本编程向导在本节结尾。

 

2.1 数字和算术

 

数字有许多不同的种类:自然数和正整数,分数(也叫有理数),和实数是被最广泛了解的数字种类:

 

5 -5 2/3 17/3 #i1.4142135623731

 

第一个是整数,第二个是负整数,接下来的两个是分数,最后一个是实数

 

和便携式计算器一样,最简单的计算机,Scheme允许程序员做加,减,乘和除数:

 

(+ 5 5) (+ -5 5) (+ 5 -5) (- 5 5) (* 3 4) (/ 8 12)

 

头三个要求Scheme执行加法;后三个做一个减法,一个乘法,一个除法。所有的算术表达式 操作符在前;数字紧跟操作符并由空分隔。

 

像在算术或代数中一样,我们可能嵌套表达式:

 

(* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2))

 

Scheme求值这些表达式就像我们一样。

 

因为每个Scheme表达式有下列形式:

 

(operation A ... B)

 

所以绝不会有任何问题关于哪个部分被首先求值。

 

练习2.1.1 找出DrScheme是否有计算平方根的操作;计算角度的正弦,决定两个数中最大的一个。

 

练习2.1.2 DrScheme中求值(sqrt 4), (sqrt 2),和(sqrt -1)。然后,找出DrScheme是否有操作知道决定角度的正切。

 

2.2 变量和程序

 

在代数里面我们学习规定两个量之间的依赖使用变量表达式。变量时一个表示一个未知量的占位符。例如,一个半径为r的盘有面积

3.14 * r 2

 

练习 2.2.1. 定义程序Fahrenheit->Celsius

 

2.3 文字描述的问题

 

程序员一般得不到处理好的数学表达式可以直接转换成程序。相反,他们接受特别的非形式化的问题描述 经常包含 有时 信息。程序

 

这里是一个特别的例子:

 

XYZ&Co.公司给每个雇员支付每小时12美元的工资。典型的雇员每周工作2065小时。开发一个程序决定一个雇员的工资,从他的工作小时数。

 

最后的句子首先 确定的任务:写一个程序决定一个量基于其他的一些量。更特别的,程序一个量,工作小时数,并且产生两一个量,以美元记的工资。第一个句子如何计算结果,但是。在这个例子里, 没有问题。如果一个雇员工作h小时,工资是

 

12*h

 

现在我们有一个规则了,我们能公式化一个Scheme程序:

 

(define (wage h)

(* 12 h))

 

这个程序被称为wage;它的参数h容纳一个雇员的工作小时数;它的结果是(* 12 h), 正确的工资。

 

练习 2.3.1 Utopia的税务总是使用程序计算所得税 税率是固定的,绝不改变15%。定义程序tax,决定所得税。

也定义netpay。这个程序决定净收入一个雇员 工作小时数。假设每小时12美元。

 

练习 2.3.2 本地超市需要一个程序能计算一包硬币的值。定义程序sum-coins。它四个数:便士数, 在包里的;它产生 包里的钱数。

 

练习 2.3.3. 一个老电影有一个简单的 函数。每个顾客支付5美元每。每个 话费 20美元,加.50美元每。开发函数total-prof它 数 产生 收入。

 

2.4 错误

 

当我们写Scheme程序时,我们必须小心的遵循设计规则, 计算机的能力和人类行为。 Scheme定义和表达式。表达式要么是原子的,比如,数和变量;要么是组合表达式,以"("开头,紧跟着一个操作,一些表达式,以“)”终结。在复合表达式中的每个表达式最后一个未知;行中断,有时增强可读性。

 

定义具有以下的形式:

 

(define (f x ... y)

an-expression)

 

那就是,一个定义是几个单词和表达式的序列:“(”,单词“define,“(”,一个非空名字序列,被空格分隔,“)”,一个表达式,和一个关闭“)”。嵌套的名字序列,f x ... y,介绍名字给程序和它的参数的名字。

 

语法错误:不是所有的 表达式都是Scheme表达式。例如:(10)是一个表达式,但是Scheme不接受它作为一个合法的Scheme表达式因为数字不能被包含。相似的,一个语句像(10 + 20)也是错误的形式;Scheme的规则操作符 。最后

 

 

练习 2.4.1. Scheme中求值一些的句子,一次一个:

 

(+ (10) 20)

(10 + 20)

(+ +)

 

阅读和理解错误消息。

 

练习 2.4.2. 输入以下的句子,一个接一个,到DrScheme的定义窗口然后点击执行:

 

(define (f 1)

(+ x 10))

 

(define (g x)

+ x 10)

 

(define h(x)

(+ x 10))

 

阅读错误消息,修正定义 重复知道定义合法。

 

运行时错误:Scheme表达式的求值 代数和算术定律。当我们 新的操作,我们扩展这些定律,第一个。现在,更重要的是理解不是所有合法的Scheme表达式有结果。一个例子是(/ 1 0).同样的,如果我们定义

 

(define (f n)

(+ (/ n 3) 2))

 

我们不能要求DrScheme求值(f 5 8).

 

当求值一个合法的Scheme表达式被0除或同样的算术运算,或者当程序应用到错如的输入数,DrScheme停止求值并且发送一个RUN-TIME ERROR

 

练习 2.4.3. 求值以下的 合法Scheme表达式在DrScheme的交互式窗口:

 

(+ 5 (/ 1 0))

 

(sin 10 20)

 

(somef 10)

 

读错误消息。

 

 

逻辑错误:一个好的编程环境帮助程序员发现语法和运行时错误。本节的练习展示DrScheme如何捕捉语法和运行时错误。然而,程序员也可能犯逻辑错误。逻辑错误不会触发任何错误消息;反而,程序计算出错误的结果。考虑来自前面章节的wage程序。

 

2.5 设计程序

 

前面的章节展示了开发一个程序需要许多步骤。我们需要决定什么 在程序语句和我们能忽略。我们需要理解程序,产生什么,以及它如何关联输入和输出。我们必须知道,或者找出,是否Scheme提供 基本运算 对 我们程序处理的数据。如果不,我们可能不得不开发程序 实现这些运算。最后,一旦我们有一个程序,我们必须检查是否它确实执行计算。这可能 语法错误,运行时问题,或甚至逻辑错误。

 

带来一些秩序到混沌,最好是 设计方法,那就是,一个一步一步

 

 

理解程序的目的:设计一个程序的目标是去建立一个机制 产生数据。我们因此开始每个程序开发 通过给出程序一个有意义的名字以及开始 何种信息 它和产生。我们称之为契约。

 

这里是我们如何写契约为area-of-ring,我们的第一个程序:

 

;; area-of-ring : number number -> number

 

分毫 这行是注释。契约包含两部分。第一部分,分号左边程序名。第二部分,分号右边,制定什么种类的数据程序 和产生;输入和输出被箭头分隔。

 

一旦我们有一个契约,我们能增加头。它 程序的名字和给出每个输入一个 不同的名字。这些名字是(代数的)变量和是

 

提示:如果程序语句提供一个数学公式,不同的变量数在公式中 建议多少个输入 到程序。

 

对其他的单词问题,我们必须 问题 分离 事实 计算。如果给出的是一个固定的数,

 

程序例子:去获得更好的理解 程序将计算什么,我们 制造 输入例子决定什么输出将产生。例如:

 

主体:最后,我们必须公式化程序的主体。那就是,我们必须替换在我们的头 用一个表达式。表达式计算答案从参数,使用基本的Scheme运算 Scheme程序我们已经定义 或 去定义。

 

我们能紧紧公式化程序的主体如果我们理解程序如何计算输出从给出的输入。如果输入-输出关系由数学公式给出,我们仅仅翻译数学到Scheme。如果,相反,我们被给出一个文字问题,我们必须小心的表达式。到这个结束,它是有帮助的 再看这例子来自第二步的去理解我们如何计算输出 为特定的输入。

 

在我们正在运行的例子,

 

测试:在我们完成程序定义之后,我们必须仍然测试程序。最少,我们将确保程序计算 输出 来自例子的。

 

 

 

描述 目标 活动

契约目的和 命名函数,指定输入

头 输出数据的类型

描述目的

 

 

领域知识:公式化程序主体经常需要关于领域的知识,也叫领域。 这种形式的知识称为领域知识。

 

 

 

第三节

 

 

程序是函数加变量定义

 

一般地,一个程序不仅仅包含一个而是很多定义。例如:area-of-ring程序,包含两个定义:第一个是area-of-ring另外一个是area-of-disk

 

3.1 组合函数

 

考虑下面的问题:

 

3.2 变量定义

 

当一个数在我们的程序中多次出现时,我们通过变量定义给它一个名字,也就是把一个名字和一个值关联起来。一个例子是3.14,我们用pi来代替。这里展示了我们如何给这个数一个名字:

 

(define PI 3.14)

 

现在,每次我们引用PIDrSchme314代替它。

 

给常量使用一个名字比用不同的值代替它更容易。假设我们的程序包含PI的定义,我们决定需要PI的更好的精度在整个程序中。通过改变定义:

 

(define PI 3.14159)

 

这改变被使用在任何我们使用PI的地方。如果我们不给PI一个名字,我们不得不找遍整个程序把所有的3.143.14159代替。

 

让我们规定这个 作为我们的第二个指导;

 

变量定义指导

给经常 被使用的常量一个名字 并且在程序中使用这个名字代替常量。

 

最初,我们不使用许多常量定义,因为我们的程序很小,但是,当我们学着去写更大的程序时,我们将更多地使用变量定义。然后
我们将看到,在单个控制点改变的能力对变量定义和函数定义是重要的。

 

练习 3.2.1。提供变量定义给所有出现在图5 profit程序中的常量。然后用名字替代这些变量。

 

3.3 Finger练习在复合函数

 

练习 3.3.1 美国使用英制度量衡系统。世界上的其他地方使用米制系统。以,在国外和外地旅游的人们外国合作伙伴经常需

 

这儿是一个表展示了六个主要的英制系统长度单位。

 

英制 米制

c

1 inch =2.54cm

1 foot = 12in

 

开发函数inches->cm, feet->inches, yards->feet, rods->yards, furlongs->rods,miles->furlongs.

开发函数feet->cm, yards->cm, rods->inches, miles->feet.

 

注意:尽可能重用函数。使用变量定义对特别的常量。

 

练习 3.3.2. 开发程序volumn-cylinder.

 

第四节 条件表达式和函数

 

对许多问题来说,计算机程序必须处理不同的 在不同的方式。游戏程序可能需要决定是否一个对象的速度在一定范围或者它处于屏幕的制定区域。对一个引擎控制程序,条件可能描述为是否或 合适一个 valve打开。要处理条件,我们需要有一个方式说条件是真是假,我们需要一类新的值,简单来说,被称为布尔值BOOLEAN(或真值)。本节介绍布尔值,布尔表达式,和依赖布尔表达式结果的表达式。

 

4.1 布尔和关系

 

考虑下面的问题描述:

 

XYZ&Co.公司支付它所有的雇员12美元一小时。一个特定的雇员工作2065小时每周。开发一个程序决定一个雇员的工资,根据他工作的小时数。如果这数在程序定义的范围里。

 

斜体字

 

条件的概念并不新。在数学中我们 真和假,是条件。例如,一个数可能等于,小于或大于一些别的数。

 

如果xy是输,我们

 

1. x=y : x等于y

2. x<y x小于y

3. x>y : x大于y

 

对任何特定的实数对,

 

4.2 测试条件的函数

 

这儿是一个简单的测试一个数的一些条件的函数:

;; is-5? : number -> boolean

;; to determine whether n is equal to 5

(define (is-5? n)

(= n 5))

 

函数产生真,当且仅当输入为5时。它的契约包含一个

 

 

4.3 条件和条件函数

 

一些银行支付不同等级的利息对存款。客户存得越多,银行付得越多。

 

 

4.4 设计条件函数

 

开发条件函数比设计普通函数更困难。关键是 问题语句列表和标识不同的情况。

 

.数据分析和定义:一旦我们决定

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics