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

来源:互联网 发布:淘宝女鞋店铺介绍范文 编辑:程序博客网 时间:2024/06/08 05:28

现在开始学习《计算机程序的构造和解释》(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就是块内部的自由变量,这种方式称为词法作用域
块结构的设计思想可以做到函数直接分离互不影响,依赖,将子问题形成黑箱用于构建大的问题。

0 0
原创粉丝点击