跳到主要內容

發表文章

How to debugger? (1)

許多人都說:不懂debugger的人,不會寫程式。身為一個會寫程式的程序員,我也是十分同意這句話的。想當初我也是渾渾噩噩的寫了一陣子程式之後,才知道什麼是debugger,之後果然就好像打通任督二脈一樣,突飛猛進。所以說,要會寫程式,一定要會debugger。礙於有許多新手程序員還是不懂什麼叫作debugger,所以就寫了這篇文,對debugger作一個基本的介紹,希望能對大家有所幫忙,可以像我一樣勇猛精進。 首先,由寫一個小小的測試程式開始,慢慢的再進入主題。 #include <iostream> using namespace std; int mul2(int a) {   return 3 * a; } int main(void) {   if (20 == mul2(10))     cout << "debugger讚!\n";   else     cout << "奇怪ㄋㄟ\n";   return 0; } 下面是程式執行的結果。 真是奇怪ㄋㄟ,應該是要顯示"debugger讚!"才對吧!?這個時候只好來debugger一下下了,看看問題出在那裡。 第一招,小紅點 下小紅點,也就是所謂的下斷點,也有人說中斷,或說breakpoint。在程式裡面放個小紅點,當程式跑到有小紅點的地方的時候就會停下來,這時候我們就抓到機會,可以去檢查看看各個可疑的地方,也可以偷偷竄改一些資料,無所不用其極的就是要把程式裡面的虫抓出來搞定它。 下小紅點的方法有很多種,這裡我可以告訴你四種方法。 __debugbreak(); __asm int 3 __asm _emit 0xCC 以上的方法都是手動在程式裡面放入小紅點,也就是在程式裡面塞進一個0xCC。那到底0xCC是什麼東西。去查一下x86指令集,原來0xCC就是int3。你又要問:什麼是int3?答案是:int3是個中斷,由x86硬體支援,軟體觸發。 當CPU執行指令的時候,如果執行到的指令是0xCC,也就是int3的時候,它會發出一個中斷,也就是interrupt。中斷...

mutable關鍵字的用法

mutable關鍵字總是會和const關鍵字扯上關係,所以要使用mutable關鍵字前,你先要知道const關鍵字的用法。const關鍵字的使用方法這裡就不提了,這是閱讀本文的基礎知識。 關鍵字const的用途很廣,這裡我們只需專注在和mutable有關係的部份即可,那就是const member function。 ; 範例1 class Sprite { public: ... int getWidth() const; int getHeight() const; ... }; 如範例所示,Sprite的getWidth和getHeight函式都是const,表示說呼叫到這二個函式的時候不會變動到任何這個Sprite物件內的資料。這是一般的情況。可是有時候我們所設計的介面,雖然在語意上它是const,但在實作上我們又不得不去變動到物件內部的某些資料。 ; 範例2 class ResourceManager { public: ... bool loadResource(string const& resName, ResourceItemHandle& item) const; ... }; 在範例中ResourceManager提供的loadResource函式,依照原始的設計,這個函式它會載入指定名稱的ResourceItem,而這個動作不會對ResourceManager內部產生任何變更。可是為了增加效率,我們在實作時在ResourceManager內部作了一個Cache的動作,把載入的ResourceItem快取起來,這樣下次再載入時就可以直接用比較快的速度完成載作動作。 這個時候就會產生如上所提到的和const衝突的情形,所以我們就只好把const修飾拿掉。拿掉const修飾字是一種解決的方法,但長遠來看這實在不是個好主意。解決的辨法是使用mutable關鍵字。 ; 範例3 class ResourceManager { public: ... bool loadResource(string const& resName, ResourceItemHandle& item) const; ... private: mutable Resourc...

不可思議: 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沒多久我就換成 野火機 。從某種角度來看,我也算是另一種全機制霸了(主要,幾乎)...不管如何,有空時又可以再多玩些不一樣的東西了...