當你開始學習程式設計的時候,很容易碰到問題讓你很奇怪一個人如何處理來寫一個電腦程式,但事實是,學程式的人都會有那樣的經驗,當他們開始學習的時候都會碰到同樣的問題,我教過幾堂基礎介紹的程式課程,有些問題幾乎絆倒了每個學生—從開始學習到處理程式設計等等的問題。
我會做好準備幫助你度過這些挑戰—沒有一個問題是不可克服的。
安裝設定
學習程式設計已經夠難的,甚至很容易在你開使前就碰到障礙,首先你需要選一個程式語言(我推薦C++),接著你需要編譯器跟一份程式設計教學可以涵蓋你所選的程式語言,以及可以跟你設定的編譯器運作良好,這全都很複雜,而且全都會在你開始有趣的地方前碰到。
如果你還在奮鬥初始化的設定,那麼看看工作達人上設定編譯器跟開發環境的文章(Code::Blocks跟MINGW),裡頭用了很多螢幕截圖引導你設定編譯器,並讓你前進到可以實際執行程式的地步。
要有程式設計師的思維
你有看過State Farm的電視廣告中洗車公司把車送回給客戶時車上還有肥皂泡沫?公司洗車卻沒有沖洗掉,這是電腦成是的最好比喻,電腦就像洗車公司是非常非常的貼切,他們做的很徹底,只做你告訴他們要做的事;他們不瞭解含蓄的意思,一開始所需資料的層次可能令人氣餒因為它需要全部考慮每個單一的步驟,確認沒有一個步驟是錯的。
一開始這會讓程式設計看起來似乎很難的樣子,但是不要絕望,不是所有的東西都需要指定—只有不是電腦可以做的事才要,編譯器有的標頭檔跟函式庫(例如, iostream標頭檔允許你跟使用者互動)提供很多預存的功能,你可以使用網站像是http://www.cppreference.com 或是Cprogramming.com 的函式參考來找到這些預存的功能函式庫,在使用前,你可以只專注在確切地說明你的程式獨特的地方,甚至一旦你這樣做,你將開始看到模式可以被轉成函式,這些函式可以包覆一堆步驟到一個單一的函式,這樣你就可以到處呼叫,突然複雜的問題會開始變得簡單,之間的差異就是:
向前走十英呎 移動你的手到牆上 移動你的手到右邊直到碰到障礙 ... 按正面朝上的凹陷
然後
走到門前 找電燈開關 打開電燈
程式設計神奇的事就是你可以將一個複雜的行為打包進一個簡單的子程序中(通常是一個函式)這樣你可以再使用,有時候很難一開始就子程序做的正確,但是一旦你懂了,就不再需要擔心了。
你可以到這裡閱讀更多關於如何有程式設計的思維,這是寫給初學者的。
編譯器錯誤訊息
這似乎事件小事情,但因為大部分的初學者不熟悉程式嚴格的格式(語法),初學者往往會碰到編譯器產生的很多抱怨,編譯器錯誤是出了名的隱晦跟囉唆,絕對不是寫給想要看的新手。
那就是說,有一些基本的原則你可以使用來航行於訊息堆中,首先,很多時候一個單一的錯誤會造成編譯器搞亂而產生幾十個訊息—要以第一個錯誤訊息開始,第二,行號是謊言,嗯,可能也不會是,但是你不可以完全相信它,編譯器在它第一次瞭解到有問題時就會抱怨,而不是在問題真正發生的地方抱怨,然而,行號顯示錯誤可能發生的最後一行—真正的錯誤可能在較前面,絕對不會是在後面。
最後,有希望!你最終真的真的可以搞懂編譯器真正的意思,今天有些錯誤訊息似乎非常地隱晦難懂,一旦你知道真正的問題是什麼,在短短幾個月的時間你會像認識一個老朋友那樣,我過去就寫了很多這樣的資料,如果你想獲得更多幫助,可以檢查Alex Allain的deciphering compiler and linker errors 這篇文章。
除錯
除錯是一個重要的技能,但大部分的人天生就無法掌握它,除錯很難有些原因;第一,這會讓人沮喪,你只是寫了一些程式碼,即使你相當有把握可以執行,它就不是沒辦法執行,該死!第二,這很乏味;除錯通常需要很多努力才能縮小問題,而且除非你有經驗了,否則很難有效地縮小問題,一種問題,記憶體區段錯誤,就是一個特別好的範例—很多程式設計師試著增加print敘述來顯示程式會在多遠之前當機以縮小其問題,即使除錯器可以正確地告訴他們問題發生在什麼地方,而這的確也會引發最後的問題—除錯器也是另一個讓人搞混的東西,很難設定的工具,就像編譯器一樣,如果你想要的是你的程式可以執行,最後一件要做的事就是去設定另一個工具來找出原因。
要學習更多除錯的技術,檢查這篇文章:debugging strategies.
設計一個程式
當你剛開始設計程式時,設計是一個真正的挑戰,知道程式設計的思維是一回事,知道如何把程式放在一起的方式使它稍後可以容易的修改他們又是另一回事,像’註解你的程式碼’、’封裝跟資料隱藏’跟’繼承’這樣的想法沒有什麼意義,只有在你感覺沒有他們的時候才會痛苦,問題是程式設計就像是吃蔬菜一樣,可以讓你未來的生活更加容易一樣,不好的設計會因未來的改變,或是在你寫了之後無法瞭解而造成程式沒有彈性,通常情況下,糟糕的設計暴露出太多事情如何執行的細節,所以程式的每個部份必須知道程式其他部份每個地方所有的細節。.
一個很棒的例子就是寫一個跳棋遊戲,你需要一些方法來表達棋盤—讓你挑一個,一個固定大小的全域陣列:int checkers_board[8][8],你的存取棋盤全都直接透過陣列來進行:checkers_board[x][y] = ….; 這個方法有什麼不對嗎?完全正確,注意我寫的你的存取棋盤全都直接透過陣列來進行,棋盤是一個概念的實體—你所關心的事情,這個陣列恰好在這個特殊的時刻發生,你如何實作這個棋盤,再說一次,兩件事情:你表達的東西,跟你表達東吸的方法,藉著所有存取齊盤是直接使用陣列,你把兩個概念糾纏在一起,當你決定改變表達棋盤的方法時會發生什麼事?你有非常多的程式碼要改,但是解決的方法是什麼?
如果你建了一個函式可以執行這一種的基本操作,讓你在跳棋棋盤上執行(可能是一個get_piece_on_square()方法跟set_piece_to_square()方法),每次的存取棋盤就可以透過這個介面來進行,假如你改變了實作,介面還是一樣,而這就是我們說的”封裝”跟”資料隱藏”的觀念,很多方面的程式設計,像是繼承,允許你隱藏特定介面或概念(棋盤)實作的細節(陣列)。
現在就來吃你的波菜吧! 🙂
接下來要學習更多關於這個議題的資訊可以閱讀programming design and style。
關於這個主題更多進接的文章,可以到object oriented class design這裡閱讀。
另一個使你的程式更容易地在未來修改可以讀clearly comment。
接下來的幾天我也會寫一些學習程式的文章,所以使用RSS、訂閱工作達人、或是用twitter來追蹤我的文章更新。
1 則留言