文章出處

本書簡介

《計算機程序的構造與解釋》這本書是MIT計算機科學學科的入門課程,
大部分學生在學這門課程前都沒有接觸過程序設計,也就是說這本書是針對編程新手寫的。
雖然是入門課程,但起點比較高,看懂里面的知識需要比較扎實的數學功底,
最起碼要有高中數學水平,如果高中數學沒學好,看起來會比較吃力。

當然,這本書的目標不是教你去做數學分析,或者讓你學會使用LISP,他的目標我理解如下

  • 學會使用編程的一些基本元素,以編程的方式思考問題
  • 學會如何使用抽象和創造抽象來解決復雜問題
  • 學會如何良好的組織代碼來編寫大型軟件系統,控制其中的復雜性
  • 是識別出好的程序設計和差的程序設計

以數學來示范各種編程原理是因為數學問題比較普遍,好多概念大家都有所接觸,
沒有二義性,不需要把時間花在問題描述和需求分析上。以LISP來進行編程原理解
說是因為LISP語法非常簡單,不需要把時間花在講解語法上。

程序設計的基本要素

表達式

LISP可能不好安裝,我們就用Javascript來練習第一章的示范吧,打開Chrome瀏覽器,
按F12打開開發人員工具,在Console標簽里就可以寫代碼了。

如果你還不知道編程能干什么,Javascript是啥東西,沒關系,
我們可以先來實現一些簡單的數學計算,在Chrome的Console里輸入如下代碼

>128
128
>128 + 12
140
>128 / 16
8
>128 - 28
100
>50 * 2
100
>3 + 2 * 10
23
>2 * 10 * 3.14
62.800000000000004

上面代碼的大于號不用輸,表示輸入提示符,可以看到輸入一些數學式子后Console會自動打印出
這個式子的求值結果。暫時先不用管背后的原理是什么,你現在已經開始在編程了。

上面你輸入的式子就叫做表達式,里面的數就是普通的數字,+,-,*,/這些叫操作符,
操作符可以操作數,他操作的是自己兩邊的數。

命名和環境

像上面的例子里2 * 10 * 3.14其實就是在計算一個半徑為10的圓的周長,3.14就是圓周率π,
計算圓的周長的公式不是2πr嗎?

如果我們要計算好多圓的周長,那么每次都要把3.14打出來嗎?能不能給3.14起個名字呢?
能,肯定能。能給某些計算對象命名是所有編程語言里最重要的一個功能,如下。

>var pi = 3.14
undefined
>2 * pi * 10
62.800000000000004
>2 * pi * 5
31.400000000000002
>2 * pi * 8
50.24

上面的第一句var pi = 3.14就相當于給3.14起了個名字pi,后面計算周長的表達式都可以用pi來代替3.14。

這就是一個最簡單的抽象手段,你不需要記住pi的值具體是多少,只需要記住pi就表示圓周率就行了。
這個思路很關鍵,以后寫代碼寫多了,你會發現你寫的代碼越來越復雜,能夠給你寫的部分代碼進行命名,
然后使用的時候不用關心復雜的細節,就可以控制住這種復雜性,寫出復雜的大程序來。

組合式的求值

3 + 2 * 10這個式子,*會先把2和10進行乘法計算,得到20,然后+會把3和20進行相加,
得到23,整個過程和數學里的加減乘除運算規律是一樣的。如果你想執行(3 + 2) * 10的結果,
也可以直接把這個式子在Console里輸入,也能正確的執行。

你在寫2 * pi * 10時,pi會自動替換成3.14,這說明Javascript解釋器幫你存儲了pi到3.14
的對應,這種存儲我們叫環境,每個環境里都存儲了一些名字和計算對象的對應關系。
環境是個普遍的概念,它為求值的過程提供了一種上下文,對于我們理解程序
的執行起著很重要的作用。

比如你要執行(3 + 2 + 5) * (2 * (1 + 2)),這個表達式的求值過程就稍微復雜點了。
總體來看呢,這個式子分成兩個部分,一個是(3 + 2 + 5),一個是(2 * (1 + 2)),然后
這兩個部分進行想乘。要想得到這兩個部分的相乘呢,又要先得到這兩個部分的結果,怎么得到呢?
我們發現這兩個部分其實也是表達式,比如(2 * (1 + 2)),其實也有兩部分組成,一個
2,一個是(1 + 2),這兩個部分相乘。這樣從外到里分析,肯定會分析出最簡單的不
能再分的表達式,可以直接求出結果。

這個過程就叫做遞歸,先不用計較復雜的解釋,就先理解復雜表達式的求值需要先對子表
達式進行求值,子表達式的求值需要對子表達式的子表達式求值,這個過程就叫遞歸

遞歸是個剛開始不太好理解的概念,但掌握后用它來理解很多問題就很輕松了,以后會經常
遇到,加深印象。需要提的就是遞歸要有幾個注意的地方。

  1. 遞歸分成好多個步驟
  2. 每個步驟要把整個事情向前推進,每次推進都向最終點更近一步。
  3. 整個遞歸過程要有個最終點,否則整個過程就無法終止了。

比如復雜表達式的求值過程就分成多個步驟,每個步驟就是把復雜表達式拆成多個子表達式
,然后每次拆呢,肯定是拆的越來越小,把整個過程向終點推進一步,然后呢如果拆的不能
再拆了,比如1 + 2直接就能得到結果了,這就到最重點了。

以上說的這些規則,就叫做編程的語法,慢慢你會發現有的編程語言的語法特別多,需要記住的東西特別多,比如各種括號,特殊字符,關鍵字。
而有的編程語言的語法特別少,基本上不用記,一大屏代碼看到的都差不多的格式。剛學編程的時候建議選擇后面一種的編程語言,如Javascript, Python,盡量學習一些編程的本質,而不是各種語法。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()