您的位置:首页 > 其它

程序设计的基本元素、过程和计算---SICP学习笔记(1)

2017-01-16 12:38 302 查看
现在开始学习《计算机程序的构造和解释》(SICP)。

1.程序设计的基本元素:

三种机制:

1.基本表达式:语言所关心的个体

2.组合的方法:从简单的东西出发构造复合的元素

3.抽象的方法:为符合对象命名,并将它当作单元去操作

两类要素:

1.过程:有关操作数据的规则描述

2.数据:被操作的基本单位

2.基本表达式

Scheme中的最简单的组合式:

(+ 3 1)


组合式:用一对括号将表达式括起来,表示一个过程

Scheme用的是前缀表示的方法,其优点就是可以表示带有任意实参的过程:

(+ 1 2 3 4 6)


3.命名

Scheme使用define关键字来命名一个计算过程,将这个计算过程定义为一个变量

例如计算圆 的面积:

(define pi 3.14)
(define r 2)
(define space (* pi (* r r)))
space


4.过程定义

LISP中定义过程的一般形式:

(define (<name> <formal parameters>) <body>)


例如一下定义了一个平方的过程:

(define (square x) (* x x))


上表创建了一个复合过程,它还可以被用来构建其他的过程:

(define (sum-of-square x y) (+ (squre x) (squre y)) )


一个程序设计语言中必然包括:

1.数和算术运算是基本的数据和过程

2.组合式的嵌套提供了一种组织起多个操作的方法

3.定义是一种受限的抽象手段,它为名字关联相应的值

5.条件表达式和谓词

Scheme中使用cond来处理多分支的情况:

(define (abs x)
(cond
((> x 0) x)
((= x 0) 0)
((< x 0) (- x))))


这里使用cond来求得x的绝对值,由此可见cond条件表达式的基本形式:

(cond (<p1>,<e1>)
(<p2>,<e2>)
(<p3>,<e3>)
...
(<pn>,<en>)
)


cond后面的子句是一个表达式对偶,其中第一个表达式是谓词

同样,我们也可以加入else符号,类似于default的作用,将abs函数写成:

(define (abs x)
(cond ((< x 0) (- x))
(else x)))


注意else要写在和cond关键字一个括号内

另外,作为二值的条件分支,可以使用if子句:

(if <predicate> <consequent> <alternative>)


predicate 首先求值,如果得到真值,则计算consequent 的内容,否则计算alternative 中的内容。

所以abs函数可构造成if形式:

(define (abs x)
(if (< x 0)          ;<predicate>
(- x)                ; <consequent>
x))                  ;<alternative>


6.实例介绍:牛顿法求平方根

下面先给出代码:

(define (square x)(* x x))

(define (abs x)          ;条件if
(cond
((> x 0) x)
((= x 0) 0)
((< x 0) (- x))))

(define (enough iter x)     ;判断所迭代的数是否满足iter平方与x的差小于  0.01
(< (abs(- (square iter) x)) 0.01)
)

(define (average x y)       ;计算传入的两个数的平均值
(/ (+ x y) 2)
)

(define (improve iter x)       ;根据迭代的数和原数获得一个更加接近平方根的数
(average (/ x iter) iter)    ;先将原数x除以iter,然后求得该计算值与iter的平均值
)

(define (sqrt-iter iter x)
(if(enough iter x)          ;调用enough判断是否满足差足够小,满足则返回该迭代值
iter
(sqrt-iter (improve iter x) x))) ;否则使用递归的形式再次计算

(define (sqrt x)
(sqrt-iter 1.0 x)           ;隐去sqrt-iter的计算细节,形成一个黑箱,以1为起始迭代数字
)
(sqrt 5)


分析sqrt的计算过程,可以获得一个过程分解:



我们可以看到整个原问题分解到子问题的过程,同时可以看到过程的定义将实现的细节隐藏了起来,由此形成一个黑箱,调用者不必了解其中实现的细节。

现在我们可以着手将过程局部化:

(define (square x)(* x x))

(define (abs x)          ;条件if
(cond
((> x 0) x)
((= x 0) 0)
((< x 0) (- x))))

(define (average x y)       ;计算传入的两个数的平均值
(/ (+ x y) 2)
)
(define (sqrt x)
(
(define (enough iter)
(< (abs(- (square iter) x)) 0.01))
(define (improve iter)
(average (/ x iter) iter)
)
(define (sqrt-iter iter)
(if(enough iter)
iter
(sqrt-iter (improve iter))))
(sqrt-iter 1.0)
))


这样的嵌套定义称为块结构,同样由于局部化,我们的x也不必作为参数传入,x就是块内部的自由变量,这种方式称为词法作用域

块结构的设计思想可以做到函数直接分离互不影响,依赖,将子问题形成黑箱用于构建大的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: