第六章 局部變量

2018-02-24 15:45 更新

6.1?簡(jiǎn)介

在前面的章節(jié)中,我已經(jīng)講述了如何定義函數(shù)。在本節(jié)中,我講介紹局部變量,這將會(huì)使定義函數(shù)變得更加容易。

6.2?let表達(dá)式

使用let表達(dá)式可以定義局部變量。格式如下:

(let binds body)

變量在binds定義的形式中被聲明并初始化。body由任意多個(gè)S-表達(dá)式構(gòu)成。binds的格式如下:

[binds] → ((p1 v1) (p2 v2) ...)

聲明了變量p1、p2,并分別為它們賦初值v1、v2。變量的作用域(Scope)body體,也就是說變量只在body中有效。

例1:聲明局部變量ij,將它們與1、2綁定,然后求二者的和。

(let ((i 1) (j 2))
  (+ i j))
;Value: 3

let表達(dá)式可以嵌套使用。

例2:聲明局部變量ij,并將分別將它們與1i+2綁定,然后求它們的乘積。

(let ((i 1))
  (let ((j (+ i 2)))
    (* i j)))
;Value: 3

由于變量的作用域僅在body中,下列代碼會(huì)產(chǎn)生錯(cuò)誤,因?yàn)樵谧兞?code>j的作用域中沒有變量i的定義。

(let ((i 1) (j (+ i 2)))
  (* i j))
;Error

let*表達(dá)式可以用于引用定義在同一個(gè)綁定中的變量。實(shí)際上,let*只是嵌套的let表達(dá)式的語(yǔ)法糖而已。

(let* ((i 1) (j (+ i 2)))
  (* i j))
;Value: 3

例3:函數(shù)quadric-equation用于計(jì)算二次方程。它需要三個(gè)代表系數(shù)的參數(shù):a、bc?(ax^2 + bx + c = 0),返回一個(gè)存放答案的實(shí)數(shù)表。通過逐步地使用let表達(dá)式,可以避免不必要的計(jì)算。

;;;The scopes of variables d,e, and f are the regions with the same background colors.

(define (quadric-equation a b c)
  (if (zero? a)      
      'error                                      ; 1
      (let ((d (- (* b b) (* 4 a c))))            ; 2
        (if (negative? d)
            '()                                      ; 3
            (let ((e (/ b a -2)))                    ; 4
              (if (zero? d)
              (list e)
              (let ((f (/ (sqrt d) a 2)))        ; 5
                (list (+ e f) (- e f)))))))))

(quadric-equation 3 5 2)  ; solution of 3x^2+5x+2=0
;Value 12: (-2/3 -1)

這個(gè)函數(shù)的行為如下:

  1. 如果二次項(xiàng)系數(shù)a0,函數(shù)返回'error。
  2. 如果a ≠ 0,則將變量d與判別式(b^2 - 4ac)的值綁定。
  3. 如果d為負(fù)數(shù),則返回'()
  4. 如果d不為負(fù)數(shù),則將變量e-b/2a綁定。
  5. 如果d0,則返回一個(gè)包含e的表。
  6. 如果d是正數(shù),則將變量f√(d/2a)綁定,并返回由(+ e f)(- e f)> 構(gòu)成的表。

實(shí)際上,let表達(dá)式只是lambda表達(dá)式的一個(gè)語(yǔ)法糖:

(let ((p1 v1) (p2 v2) ...) exp1 exp2 ...)
;?
((lambda (p1 p2 ...)
    exp1 exp2 ...) v1 v2)

這是因?yàn)?code>lambda表達(dá)式用于定義函數(shù),它為變量建立了一個(gè)作用域。

練習(xí)1

編寫一個(gè)解決第四章練習(xí)1的函數(shù),該函數(shù)旨在通過一個(gè)初始速度v和與水平面所成夾角a來計(jì)算飛行距離。

6.3?總結(jié)

本節(jié)中,我介紹了let表達(dá)式,let表達(dá)式是lambda表達(dá)式的一個(gè)語(yǔ)法糖。變量的作用域通過使用let表達(dá)式或lambda表達(dá)式來確定。在Scheme中,這個(gè)有效域由源代碼的編寫決定,這叫做詞法閉包(lexical closure)

6.4?習(xí)題解答

6.4.1?答案1

(define (throw v a)
  (let ((r (/ (* 4 a (atan 1.0)) 180)))
    (/ (* 2 v v (cos r) (sin r)) 9.8)))
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)