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

现在开始学习《计算机程序的构造和解释》(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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值