跳到主要內容

發表文章

不可思議: for (i = 0; i < 10; i++) 停不下來 !?

其實這是一個真實事件... 某一天上班時,我從一早就三不五時的聽到坐在我背後的同事低聲的哇哇叫。幾次下來,我也忍不住好奇的湊過去看看到底是怎麼一回事。結果他Demo了這麼一個不可思議的for迴圈給我看,難怪他一整個早上都在哇哇叫。這位同事因為整個陷入在這個不可思議的for迴圈裡而跳不出來,找不到問題的所在。但當局者迷,我當下眉頭一皺發覺事情並不單純,問題肯定不是出在這個for迴圈上面,再怎麼去看也是白癈力氣。這種奇奇怪怪的問題,很有可能是和記憶體的使用有關係,這個不可思議的for迴圈只不過是因為其它地方的Bug,所產生的現象。我把我的想法告訴了我這位同事後,過了不了多久,果然在其它地方找到了真正的問題所在,的確是因為記憶體的使用不當造成的現象。 ; 底下在VC2003寫支小程式,立刻就能摸擬出這樣的現象。 int main() { int i, a[1]; for (i = 0; i a[i] = 0; } } 如上所示,我宣告了一個只有一個元素的陣列a,然後用一個for迴圈去填a的內容。這裡所要示範的一個概念是:會產生這樣的問題,是因為i的值被其它人動到了。而在這個簡單的例子,就是利用這個概念,想辨法讓在填a的內容時,因為填寫錯誤(超出範圍),而去覆寫了i的值,而造成for迴圈停不下來的奇妙現象。 如圖在除錯模式中,在Watch裡加上檢視i和陣列a的位址和內容,然後一步步執行看看。可以發現i的位址和a[3]重疊了,但問題是a只宣告了一個元素,而這個迴圈卻打算存取10個元素。在這樣的情況下,i的值果然被覆寫了,所以這個for迴圈就這樣成為無窮迴圈而永遠跳不出來。 ; PS: 這個實驗是在VC2003和2005上作的,在其它Compiler也許會有不一樣的結果。

關於最佳化

過早作最佳化是萬惡的根源 (Premature optimization is the root of all evil.) 最佳化守則 別作! (Don't do it!) 高手專用:先別作! (For experts only: Don't do it yet!)

用Java寫一個簡單的Web Server

Java的生產力很高,拿它來寫個簡單的Web Server只需要不到200行的程式碼,底下就用Java一步一步實作一個簡單的HTTP網頁伺服器。 ; 在開始前,需要對 HTTP協定 有一個基本的認識,在我們這個例子裡面,只需要知道GET請求(Request)即可。 當我們在瀏覽器的網址列輸入一個位址時,瀏覽器會送出一個GET請求到位址欄裡指定的網頁伺服器,去跟這個網頁伺服器取得網頁或檔案的內容。 例如,我們在網址列輸入 http://www.google.com.tw/ ,就是向www.google.com.tw這台伺服器要求一個檔案,而要求的檔案就是首頁(/)。 這個動作,瀏覽器會送出如下的HTTP請求命令到伺服器去 (以Chrome為例): GET / HTTP/1.1 Host: www.google.com.tw Connection: keep-alive Cache-Control: max-age=0 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,i mage/png,*/*;q=0.5 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 ( KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10 Accept-Encoding: gzip,deflate,sdch Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: Big5,utf-8;q=0.7,*;q=0.3 這裡的重點是第一行和最後一行。 由第一行,伺服器可以知道Client作的是那一種類的請求,這裡可以明顯的看到Client(Chrome)作了一個GET請求。同時,在第一行裡面也可以知道Client請求的是什麼。在此例中,可以看到Client請求的是/這個檔案。在第一行最後的部份,則是註明HTTP協定的版本號。 而最後一行,是一個空行,表示請求包的結束。伺服器在收到一個請求時,從第一行的請求命令開始,一直讀取到一個空行為止,為一個完整的封包。除了...

非同步的寶石方塊

我一直很喜歡 這類型的小遊戲 。這類方塊遊戲的一個主要的特點是在於它可以在不中斷的情況下,不斷的接受你的輸入,不斷的去消去方塊,這讓整個遊戲變的非常有節奏感。有些同類型的遊戲就少了這樣的設計設計,當有方塊在消除時,一定要等這些方塊全部消除完畢,才能再繼續接受你的輸入,這等於硬生生的把遊戲給中斷,玩起來非常的不舒服,整個就遜掉了。 最近因為我的 N73 電池似乎有點問題(有陣子沒用後又拿出來用),所以又再換回 A3100 。為了紀念又換回A3100,所以就順便把寫好的一支寶石方塊小遊戲移植上去(完全 GDI ),看看效果。 等改天有空再改版到Good裡當作新的範例。 不過話說回來,換回A3100沒多久我就換成 野火機 。從某種角度來看,我也算是另一種全機制霸了(主要,幾乎)...不管如何,有空時又可以再多玩些不一樣的東西了...

Good Game Editor 1.2 Beta

* 新增Good.KillAllChild * 關卡編輯器(Level Editor)支援按住Alt鍵以滑鼠拖曳物件作複製。 * 修正在關卡編輯器中拖曳物件過程中按ESC鍵的處理錯誤。 * AboutBox中,zlib及yardparser文字位置對調。 * 關卡編輯器新增使用方向鍵移動物件。 * 關卡編輯器中(Name|Visible|Rot|Scale|Repeat|Script)等屬性可以undo/redo。 * 關卡編輯器支援按住Shift鍵以方向鍵作色塊及貼圖物件縮放。 * 關卡編輯器支援以Tab鍵切換選取物件。 * 修正Good模組API傳入物件Id(0)的錯誤。 * 去掉Good模組中物件類別常數的前綴詞TYPES_。 * 去掉Input模組中按鍵常數的前綴詞KEYS_。 * 以Good.SetBgColor設定關卡物件BgColor等同於設定關卡背景清除顏色(ClearColor)。 * 新增範例lvlbg。 * 新增範例動態選單(menu)。 * 工具列新增一個可以開關ResourceView及一個開關OutputView的按鈕。 * AboutBox的連結(又)改成按鈕型式。 * 修正一個新增關卡的小問題,將HasClearColor初始為false。 * 將範例程式中使用的一些BMP圖形格式轉為PNG。 * 新增單人撲克牌遊戲:蒙地卡羅。 * AboutBox添加Wiki連結。 * 編輯器(Editors)的縮放比例最大可到800%。 * 修正一個新件貼圖物件大小計算錯誤的問題。 * 新增Good.GetTexId/SetMapId/SetTexId API。 * 新增檢查是否有新版本編輯器的功能(Help\Check for Update...)。 * 新增一個sample,簡單的示範縮放及旋轉(scalerot)。 * 移除AboutBox裡的waync's smallworld連結。 * 修正Good.GetDim在讀取貼圖物件時沒有正確回傳寬高的問題。 * 修正時間控制的問題,這樣在某些電腦上不會一執行遊戲時就失速。 * 新版本也能在iPhone上通過編譯執行。 * 增加對物件作縮放(xScale,yScale)及旋轉(Rotate)的支援。 * 把25940m改版一下支援iPhone,當作測試。 * 除了可以在Dependen...

25940p for PSP

自從上次更新過 DevkitPSP 之後,PSP版的 25940p 就無法編譯,其實是環境設定問題,不過當時沒有仔細去看是怎麼回事,直接就丟著不管。直到前天又突然想到,把DevkitPSP更新到目前R14後,試編譯一下,結果又可以編譯了,只不過這次是編譯問題,編譯不成功。既然可以編譯,所以花了點時間修正一下,順便作一些修正。 下載

單人撲克牌遊戲 - 蒙地卡羅

更多可在網頁玩的 單人撲克牌遊戲 ; 新增一個簡單的單人撲克牌遊戲: 蒙地卡羅 ,簡單介紹一下玩法。 下載 事先排列好5x5張牌。 每次移動一張可以配對的牌,並消除這對牌。在上下、左右及斜向相隣的二張牌,只要擁有同樣數字(不計花色),即可配對。 消除二張配對的牌後,剩餘的牌以往左往上的方式補滿空隙,接著在發新牌補滿後面的空格。 重覆步驟2~3,直到沒有牌可以配對及發完所有牌為止。 結果有二種。一個是勝利,成功的消除掉所有牌。另一個是Gameover沒有牌可以再作配對。