<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC=2] ## 5.1?簡介 上一章中,我講解了如何定義函數。本章中,我會講解如何通過條件編寫過程。這個是編寫使用程序很重要的一步。 ## 5.2?if表達式 `if`表達式將過程分為兩個部分。`if`的格式如下: ~~~ (if predicate then_value else_value) ~~~ 如果`predicate`部分為真,那么`then_value`部分被求值,否則`else_value`部分被求值,并且求得的值會返回給`if`語句的括號外。`true`是除`false`以外的任意值,`true`使用`#t`表示,`false`用`#f`表示。 在R5RS中,`false`(`#f`)和空表`(’())`是兩個不同的對象。然而,在MIT-Scheme中,這兩個為同一對象。這個不同可能是歷史遺留問題,在以前的標準——R4RS中,`#f`和`’()`被定義為同一對象。 因此,從兼容性角度考慮,你不應該使用表目錄作為謂詞。使用函數`null?`來判斷表是否為空。 ~~~ (null? '()) ;Value: #t (null? '(a b c)) ;Value: () ;#f ~~~ 函數`not`可用于對謂詞取反。此函數只有一個參數且如果參數值為`#f`則返回`#t`,反之,參數值為`#t`則返回`#f`。`if`表達式是一個特殊形式,因為它不對所有的參數求值。因為如果`predicate`為真,則只有`then_value`部分被求值。另一方面,如果`predicate`為假,只有`else_value`部分被求值。 例:首項為`a0`,增長率`r`,項數為`n`的幾何增長(geometric progression)數列之和 ~~~ (define (sum-gp a0 r n) (* a0 (if (= r 1) n (/ (- 1 (expt r n)) (- 1 r))))) ; !! ~~~ 通常來說,幾何增長數列的求和公式如下: ~~~ a0 * (1 - r^n) / (1 - r) (r ≠ 1) a0 * n (r = 1) ~~~ 如果`if`表達式對所有參數求值的話,那么有`;!!`注釋的那行就算在`r=1`時也會被求值,這將導致產生一個“除數為0”的錯誤。 你也可以省去`else_value`項。這樣的話,當`predicate`為假時,返回值就沒有被指定。如果你希望當`predicate`為假時返回`#f`,那么就要明確地將它寫出來。 `then_value`和`else_value`都應該是S-表達式。如果你需要副作用,那么就應該使用`begin`表達式。我們將在下一章討論`begin`表達式。 > 練習1 > > 編寫下面的函數。閱讀第五節了解如何編寫謂詞。 > > * 返回一個實數絕對值的函數。 > * 返回一個實數的倒數的函數。如果參數為`0`,則返回`#f`。 > * 將一個整數轉化為ASCII碼字符的函數。整數可以被轉化為33-126號之間的ASCII碼。使用`integer->char`可以將整數轉化為字符。如果給定的整數不能夠轉化為字符,那么就返回`#f`。 ## 5.3?and和or `and`和`or`是用于組合條件的兩個特殊形式。Scheme中的`and`和`or`不同于C語言中的約定。它們不返回一個布爾值(`#t`或`#f`),而是返回給定的參數之一。`and`和`or`可以使你的代碼更加短小。 ### 5.3.1?and `and`具有任意個數的參數,并從左到右對它們求值。如果某一參數為`#f`,那么它就返回`#f`,而不對剩余參數求值。反過來說,如果所有的參數都不是`#f`,那么就返回最后一個參數的值。 ~~~ (and #f 0) ;Value: () (and 1 2 3) ;Value: 3 (and 1 2 3 #f) ;Value: () ~~~ ### 5.3.2?or `or`具有可變個數的參數,并從左到右對它們求值。它返回第一個不是值`#f`的參數,而余下的參數不會被求值。如果所有的參數的值都是`#f`的話,則返回最后一個參數的值。 ~~~ (or #f 0) ;Value: 0 (or 1 2 3) ;Value: 1 (or #f 1 2 3) ;Value: 1 (or #f #f #f) ;Value: () ~~~ > 練習2 > > 編寫下面的函數。 > > * 一個接受三個實數作為參數的函數,若參數皆為正數則返回它們的乘積。 > * 一個接受三個實數作為參數的函數,若參數至少一個為負數則返回它們的乘積。 ## 5.4?cond表達式 盡管所有的分支都可以用`if`表達式表達,但當條件有更多的可能性時,你就需要使用嵌套的`if`表達式了,這將使代碼變得復雜。處理這種情況可以使用`cond`表達式。`cond`表達式的格式如下: ~~~ (cond (predicate_1 clauses_1) (predicate_2 clauses_2) ...... (predicate_n clauses_n) (else clauses_else)) ~~~ 在`cond`表達式中,`predicates_i`是按照從上到下的順序求值,而當`predicates_i`為真時,`clause_i`會被求值并返回。`i`之后的`predicates`和`clauses`不會被求值。如果所有的`predicates_i`都是假的話,則返回`cluase_else`。在一個子句中,你可以寫數條S-表達式,而`clause`的值是最后一條S-表達式。 > 例:城市游泳池的收費。 > > Foo市的城市游泳池按照顧客的年齡收費: > > 如果?age?≤ 3 或者?age?≥ 65 則 免費; > 如果 介于 4 ≤?age?≤ 6 則 0.5美元; > 如果 介于 7 ≤?age?≤ 12 則 1.0美元; > 如果 介于 13 ≤?age?≤ 15 則 1.5美元; > 如果 介于 16 ≤?age?≤ 18 則 1.8美元; > 其它 則 2.0美元; > > 那么,一個返回城市游泳池收費的函數如下: ~~~ (define (fee age) (cond ((or (<= age 3) (>= age 65)) 0) ((<= 4 age 6) 0.5) ((<= 7 age 12) 1.0) ((<= 13 age 15) 1.5) ((<= 16 age 18) 1.8) (else 2.0))) ~~~ > 練習 3 > > 編寫下列函數。 > > 成績(A-D)是由分數決定的。編寫一個將分數映射為成績的函數,映射規則如下: > + A 如果?score?≥ 80 > + B 如果 60 ≤?score?≤ 79 > + C 如果 40 ≤?score?≤ 59 > + D 如果?score?< 40 ## 5.5?做出判斷的函數 我將介紹一些用于做判斷的函數。這些函數的名字都以`'?'`結尾。 ### eq?、eqv?和equal? 基本函數`eq?`、`eqv?`、`equal?`具有兩個參數,用于檢查這兩個參數是否“一致”。這三個函數之間略微有些區別。 > `eq?` > 該函數比較兩個對象的地址,如果相同的話就返回`#t`。例如,`(eq? str str)`返回`#t`,因為`str`本身的地址是一致的。與此相對的,因為字符串`”hello”`和`”hello”`被儲存在了不同的地址中,函數將返回`#f`。不要使用`eq?`來比較數字,因為不僅在R5RS中,甚至在MIT-Scheme實現中,它都沒有指定返回值。使用`eqv?`或者`=`替代。 ~~~ (define str "hello") ;Value: str (eq? str str) ;Value: #t (eq? "hello" "hello") ;Value: () ← It should be #f in R5RS ;;; comparing numbers depends on implementations (eq? 1 1) ;Value: #t (eq? 1.0 1.0) ;Value: () ~~~ > `eqv?` > 該函數比較兩個存儲在內存中的對象的類型和值。如果類型和值都一致的話就返回`#t`。對于過程(`lambda`表達式)的比較依賴于具體的實現。這個函數不能用于類似于表和字符串一類的序列比較,因為盡管這些序列看起來是一致的,但它們的值是存儲在不同的地址中。 ~~~ (eqv? 1.0 1.0) ;Value: #t (eqv? 1 1.0) ;Value: () ;;; don't use it to compare sequences (eqv? (list 1 2 3) (list 1 2 3)) ;Value: () (eqv? "hello" "hello") ;Value: () ;;; the following depends on implementations (eqv? (lambda(x) x) (lambda (x) x)) ;Value: () ~~~ > `equal?` > 該函數用于比較類似于表或者字符串一類的序列。 ~~~ (equal? (list 1 2 3) (list 1 2 3)) ;Value: #t (equal? "hello" "hello") ;Value: #t ~~~ ### 5.5.2?用于檢查數據類型的函數 下面列舉了幾個用于檢查類型的函數。這些函數都只有一個參數。 * `pair?`?如果對象為序對則返回`#t`; * `list?`?如果對象是一個表則返回`#t`。要小心的是空表`’()`是一個表但是不是一個序對。 * `null?`?如果對象是空表’()的話就返回#t。 * `symbol?`?如果對象是一個符號則返回#t。 * `char?`?如果對象是一個字符則返回#t。 * `string?`?如果對象是一個字符串則返回#t。 * `number?`?如果對象是一個數字則返回#t。 * `complex?`?如果對象是一個復數則返回#t。 * `real?`?如果對象是一個實數則返回#t。 * `rational?`?如果對象是一個有理數則返回#t。 * `integer?`?如果對象是一個整數則返回#t。 * `exact?`?如果對象不是一個浮點數的話則返回#t。 * `inexact?`?如果對象是一個浮點數的話則返回#t。 ### 5.5.3?用于比較數的函數 > `=`、`>`、`<`、`<=`、`>=` > 這些函數都有任意個數的參數。如果參數是按照這些函數的名字排序的話,函數就返回`#t`。 ~~~ (= 1 1 1.0) ;Value: #t (< 1 2 3) ;Value: #t (< 1) ;Value: #t (<) ;Value: #t (= 2 2 2) ;Value: #t (< 2 3 3.1) ;Value: #t (> 4 1 -0.2) ;Value: #t (<= 1 1 1.1) ;Value: #t (>= 2 1 1.0) ;Value: #t (< 3 4 3.9) ;Value: () ~~~ > `odd?`、`even?`、`positive?`、`negative?`、`zero?` > 這些函數僅有一個參數,如果這些參數滿足函數名所指示的條件話就返回`#t`。 ### 5.5.4?用于比較符號的函數 在比較字符的時候可以使用`char=?`、`char<?`、`char>?`、`char<=?`以及`char>=?`函數。具體的細節請參見R5RS。 ### 5.5.5?用于比較字符串的函數 比較字符串時,可以使用`string=?`和`string-ci=?`等函數。具體細節請參見R5RS。 ## 5.6?總結 在這一章中,我總結了關于分支的知識點。編寫分支程序可以使用`if`表達式和`cond`表達式。 下一章我將講解局部變量。 ## 5.7?習題解答 ### 5.7.1?答案1 ~~~ ; 1 (define (my-abs n) (* n (if (positive? n) 1 -1))) ; 2 (define (inv n) (if (not (zero? n)) (/ n) #f)) ; 3 (define (i2a n) (if (<= 33 n 126) (integer->char n) #f)) ~~~ ### 5.7.2?答案2 ~~~ ; 1 (define (pro3and a b c) (and (positive? a) (positive? b) (positive? c) (* a b c))) ; 2 (define (pro3or a b c) (if (or (negative? a) (negative? b) (negative? c)) (* a b c))) ~~~ ### 5.7.3?答案3 ~~~ (define (score n) (cond ((>= n 80) 'A) ((<= 60 n 79) 'B) ((<= 40 n 59) 'C) (else 'D))) ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看