追求神乎其技的程式設計之道(一)

July 5th, 2008 by vgod | 瀏覽:29,232人次

最近有讀者問到我學寫程式的方法和經驗,讓我一下掉入時光隧道回想起當初用VB寫出自己第一個遊戲時的成就感,但當初沒料到的是我真的就此迷上了電腦和寫程式的快感,不知不覺也過了10年的光陰…。在這篇文章中,我想寫出我對程式設計的看法和我一路學習上來的歷程和經驗。寫程式是一條無止境的道路,不只是科學和工程,更是一種藝術。而我還在追求「神乎其技」的半路上,雖然還有很多要學的,但我也希望能讓初學者更容易看清楚這條路是什麼樣子,避免陷入盲目追求新技術的死巷中。

一切的開始

如果是從DOS時代開始玩電腦的玩家,應該都知道當初DOS有兩個內建的QBASIC小遊戲:貪食蛇和猩猩丟香蕉。這兩個小遊戲是許多人兒時共同的回憶,我還記得我國小時曾有幾堂電腦課,當時老師在台上嘰哩瓜啦的不知道在教什麼,而台下每台電腦都是貪食蛇或丟香蕉的畫面(老師對不起,其實我就是帶頭做亂的罪魁禍首…)。

微軟把這兩個QBASIC遊戲附在DOS內對我產生了莫大的影響,那是我第一次發現到原來QBASIC和不只是像PE2能打打字而已,QBASIC竟然能把一堆看起來像咒語的文字變成遊戲!幸運的是我家剛好有本第三波的QBASIC入門書,沒事我就自己拿起來翻著看,雖然當時太小,即使把整本都看完了還是搞不懂貪食蛇是怎麼寫出來的,但也誤打誤撞知道了原來這就是程式設計,原來我能直接把貪食蛇檔案內的一個數字改掉就能有幾百條命可以死,原來學寫程式就能做出電腦遊戲…。對小孩子而言,知道這些事就像告訴他魔術師袖子裡的秘密一樣,我一天到晚興奮地要老爸帶我去書局看電腦書,彷彿真的可以搞懂電腦螢幕背後的一切魔法一樣,我也夢想著有一天能寫出自己的遊戲。但當時我沒想到的是,我還真的花了十幾年的時間在探索電腦的魔法…。

MUD與黑白棋

升上國中後,家裡裝了一台28.8kbps的modem,當時的internet還沒完全成形,在沒有Google的時代internet是沒什麼價值的。當時的modem最常被我拿來上一些撥接式的BBS,那時候的撥接BBS站台還不少,最棒的是還能從站上抓到很多軟體和各式各樣的教學文章,像是如何用組合語言寫電腦病毒,如何破解大富翁2之類的文章。這些文章對當時的我就像武林密籍一樣,雖然沒辦法完全看懂,但我也是從中得到很多零碎的概念,像是16進位的換算、組合語言、中斷向量、常駐程式….。

在國二時,我還不小心迷上當時一個超熱門的MUD – 萬王之王(KK),每天放學回家都急著連上線,讓家裡電話整晚都忙線中,玩到每個月電話費都是上千元,搞得我媽數次警告要把modem收起來再也不讓我上網了。(還好她沒真的這麼做,不然我現在就沒辦法寫這篇文章了。)

MUD是現在MMORPG的純文字版,整個虛擬世界都用文字描述,並且只要用telnet就可以連上去玩了。但內行的玩家都知道,玩MUD應該要用zMud或是UNIX下的tintin++,因為這兩個軟體可以設定所謂的trigger,偵測到某些事件的發生,就能自動採取事先指定好的動作。因為一切的訊息都是由文字呈現,所以偵測事件非常簡單,只要看看有沒有特定字串出現就可以了;而要做特定的動作也很簡單,就是送出文字指令而已。(眼尖的人一定會發現,這其實就是現在MMORPG外掛的最原始形式。)嚴格說起來,zMud是我首次寫「實用程式」的平台,我學會透過trigger在MUD的世界中寫自動化的機器人,自動在迷宮中遊走,自動換裝備打怪練功..。這時的我突然體會到,會寫程式真是太棒了,我在MUD中簡直跟神一樣。其實當時我也不過只會用最基本的變數、if、迴圈而已,但透過在虛擬世界中寫機器人的練習,讓我的邏輯思考概念有飛快的進步,也給我了非常強烈的動力想好好學一個正統的程式語言。

升上國三後,很幸運的透過推薦甄試提早上了台中一中,升學壓力解除後,老師和父母就完全不管我要幹麻了。這時我終於有了一段完整的時間可以好好的再把BASIC重新學過,無奈的是在我國三時QBASIC已經快滅絕了,取而代之的是Windows上的Visual Basic,我只好硬著頭皮買本新書來從頭學起VB。當時我看的是王國榮的VB 5入門書,整本書有六七百頁吧,比我國三所有課本疊起來都還厚,現在想想小時候真的有點不知天高地厚竟然相信自己能看完這麼厚的磚頭書。那時候我每天上課就帶著這本磚頭去學校,這樣看了幾個禮拜下來,沒想到我這時突然都看得懂了,很多原本不知道有什麼用途的概念突然都相互連結起來了。(多虧了在MUD裡的訓練!)就這樣,某天突然有種打通任督二脈的感覺,我發現我全搞懂了,迴圈、陣列、Windows GUI控制項、去背貼圖…,我突然想通要怎麼用程式語言寫出遊戲了。

從那之後,每天回家就是打開VB寫程式,我想寫個黑白棋來檢驗自己的想法,我把自己知道的所有概念都放進去,有GUI元件、有貼圖、有動畫、有音效..,這是我第一個完整的程式,從頭到尾每一行都是自己寫出來的。(以現在的眼光來說只能說是一個期末project規模的小程式,但對當時的我可是意義非凡)

這個黑白棋讓我印象最深的其實是debug的痛苦經驗。我花了一個禮拜把程式的核心部分完成,但在吃子的時候卻跑出一個不明的bug會打亂整個盤面。為了找這個bug,我又花了一個禮拜,每天從早到晚都在想哪裡寫錯了,後來慢慢trace了好久,才發現竟然只是一個變數忘了歸零!!!

這種bug很常見,不過只是programmer最容易犯的無心之過之一,但這件事對我的影響非常大,它讓我花了很長時間在想以後要怎麼避免犯同樣的錯。我後來才知道一個普通的programmer和厲害的programmer從這裡就會分出高下:普通programmer犯了這種錯會覺得很平常,並提醒自己下次別再這麼笨了,但實際上不久後一定又會再犯同樣的錯;厲害的programmer會反省自己寫程式的方法,並改變原有的方法或習慣來避免以後再度產生同樣的bug。

古老的程式設計教材(尤其是C語言),都說要把變數宣告在函式的一開頭,並且因為變數宣告完還得經過初始化,所以很多人習慣是在函式開頭宣告並初始化所有變數。這不是錯的,可是,這其實就是會導致bug的元兇。
因為變數在開頭就被初始化,這樣在真正要用到它的時候就能直接拿來用,但是如果這個變數需要被歸零(也就是重新初始化)並在迴圈中重複利用,就很容易會忘記要再多做這一步。(在多層迴圈中更容易發生)

我為這個bug苦惱了幾天,後來才意識到這是coding style的問題,只要改變宣告變數的習慣,就能避免犯這種錯誤。如果一開始就在迴圈內宣告並給定變數的初始值,而不是在函式開頭宣告,就不會有這種bug跑出來了。有了這個經驗後,我歸納出一個原則:「永遠在變數需要被用到的最內層區塊才宣告並初始化該變數。」這種原則很重要,我日後一直放在心裡,它也幫助我避免掉未來再犯同樣錯誤的可能。(事實上,我後來再寫了十年的程式,再也沒有比這更痛苦更長久的debug經驗了…)

(待續)

12 Responses to “追求神乎其技的程式設計之道(一)”

  1. MyAvatars 0.2 小高一 Says:

    真是太感動了!我等了好久呢!
    也很期盼下一篇的到來,謝謝囉!

    - 回覆留言(Reply)

  2. MyAvatars 0.2 hcc Says:

    謝謝你!給現在的我一些省思~

    學習東西就是要有個目標,才會學得快又好
    不過你那時玩mud怎麼沒去學lpc咧?

    我也很期待下集!加油~

    - 回覆留言(Reply)

  3. MyAvatars 0.2 vgod Says:

    hcc:
    那時候我根本沒聽過LPC呢,其實連C語言都還不會..XD

    - 回覆留言(Reply)

  4. MyAvatars 0.2 祖母綠菜園 Says:

    寫程式的壞習慣…

    剛剛看了vgod長輩的追求神乎其技的程式設計之道(一)一文,默默覺得予兒平常寫程式的習慣還真是糟糕呀。引用其文章中的一段話:…

  5. MyAvatars 0.2 walkingice Says:

    太感人了,沒想到還可以看見 KK 這個詞

    - 回覆留言(Reply)

  6. MyAvatars 0.2 追求神乎其技的程式設計之道(六) | vgod’s blog Says:

    [...] 追求神乎其技的程式設計之道系列:一 二 三 四 五 [...]

  7. MyAvatars 0.2 SD Says:

    冒昧打擾~從”鳥毅的Blog”那看到你的文章真是有感而發
    因為我也是qbsic出身+1996台灣北區第三名 比賽內容就是用qbasic 做很多項目 包含”3D”,
    QBASIC國內書籍很少 要靠各方面資訊不斷 研究出可行的功能 很多數學函式才建構成3D函式.
    因該你也還記得svga下畫面 不再是單張畫面 而是程式運行下的動畫 的感動..
    mode當然要搞個bbs交流哈啦唯一途徑.
    當初我記得並沒有ioi…………..有話要更努力.
    寫程式真的要有興趣,想當初我成績是放牛班而且是倒數前三名+還好有個肯欣賞有用氣的老師提拔.
    想當初熱血少年程式語法過目不忘書都可以不用翻…現在都翻書比較快
    當屆北區(1.開南+2.大安+3.開平)如果可以我也想出國阿~~~~~~~~~~(窮 英文又爛 下輩子吧)
    感覺自己不孤單了 至少還有個類似我一樣的心路歷程(所有同好一起努力的都沒再摸程式了..一堆mis++剩小弟孤軍)
    打擾啦~(國文很差+請見諒)

    - 回覆留言(Reply)

  8. MyAvatars 0.2 追求神乎其技的程式設計之道(七) | vgod’s blog Says:

    [...] 追求神乎其技的程式設計之道系列:一 二 三 四 五 六 [...]

  9. MyAvatars 0.2 追求神乎其技的程式設計之道(八) | vgod’s blog Says:

    [...] 追求神乎其技的程式設計之道系列:一 二 三 四 五 六 七 [...]

  10. MyAvatars 0.2 ginnyhuang Says:

    Vgod先生 您好:
    最近剛學C(學校課程),從別的網站連結到這篇文章,剛看完第一篇忍不住有問題想請教一下^^”

    文章中有提到”古老的程式設計教材(尤其是C語言),都說要把變數宣告在函式的一開頭”、”我歸納出一個原則:「永遠在變數需要被用到的最內層區塊才宣告並初始化該變數。」”

    一開始老師介紹C語言時,有提到一個程式分為兩個區塊:”資料宣告定義”和”執行程式碼”(傳統C是分開的,不過C++是可以混的)。
    所以我不太懂”在變數需要被用到的最內層區塊才宣告並初始化該變數”的意思。是說可以在程式碼裡再定義變數嗎?還是指一個程式裡有很多function,每個function有用到的變數在function裡定義而不要在程式最初定義?

    剛巧前不久碰到的小習題也是需要初始化變數。不過那時候function剛教,還不是很熟悉(雖然距現在沒多久也不是很熟XD),所以我是把輸入、處理、輸出全寫在同一個程式裡(後來老師有強調程式應該清楚分這三部分,其中只有輸入輸出在主程式,處理要用function)。而我選擇的方式正是在最後(迴圈之前)讓它初始化,所以看到這篇真的是心有戚戚焉^^”

    這篇文章真的喚起很多記憶,從DOS(不過我沒看過貪食蛇,也許有,不過印象深刻的是一堆英文字(指令)、非常大的磁碟片和三國的格鬥遊戲、泡泡龍XD)、蘋果、windows系列,還有網頁的純文字RPG冒險遊戲。不過那時還小,每個時期都是眼巴巴地看著哥哥們在玩XD。小五、六還是國中時也曾有雄心壯志想學程設,結果VB自學沒多久就放棄了。後來又因為哥哥讀資工,想說不要走同一條路。沒想到大學有這門必修,也幸好有^^
    嗯,廢話不多說,繼續往下看^^”

    - 回覆留言(Reply)

  11. MyAvatars 0.2 vgod Says:

    Hi ginny,

    C的變數宣告位置有兩種, 一個是function外的global variable,一種是任何block(也就是上面講的區塊)內的local variable。一般會被忽略的是,所謂的block是指任何由大括號{}包起來的範圍,而不是只有function而已。所以,不管是for、if、while的大括號開頭其實都能宣告變數。我所說的在最內層的區塊需告也就是在你真的需要用那個變數的最內層大括號裡在宣告就好。

::...
免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com


点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

订阅 substack 体验古早写作:


关注公众号, 持续获得相关各种嗯哼:
zoomquiet


自怼圈/年度番新

DU22.4
关于 ~ DebugUself with DAMA ;-)
粤ICP备18025058号-1
公安备案号: 44049002000656 ...::