<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Team Programming Dragon．編程龍</title>
	<atom:link href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/feed/" rel="self" type="application/rss+xml" />
	<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd</link>
	<description>Programming Art、C++、Python、Django、LinuxDev、HCI、Graphics、Web2.0。讓我們成為編程界的朝田龍太郎吧。</description>
	<pubDate>Sat, 04 Apr 2009 04:35:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>G++ 尚未支援 extern template？</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/gcc-extern-template/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/gcc-extern-template/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 09:00:17 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[G++]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=59</guid>
		<description><![CDATA[在用別人實作的 Graph Cuts 的時候，後知後覺的發現原來 g++ 並不支援 template function 的 linking：如果 template function 的定義跟宣告拆開來的話，會出現 undefined reference error。

解決方式很簡單，把所有定義丟到 header file 裡面去就行了。

不過還是希望早日有高手寫出這個功能。


]]></description>
			<content:encoded><![CDATA[<p>在用<a href="http://www.adastral.ucl.ac.uk/~vladkolm/software.html" target="_blank">別人實作的 Graph Cuts</a> 的時候，發現原來 g++（以 4.3.1 實測）似乎尚未支援 extern template：如果 function template 的定義跟宣告拆開來的話，會出現 undefined reference error。儘管按照這份 <a href="http://gcc.gnu.org/projects/cxx0x.html" target="_blank">spec</a> 應該是 OK 的。或許中間出了什麼差錯，晚點再試試。</p>
<p>暫時的解決方式很簡單，把所有定義丟到 header file 裡面去就行了。</p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/gcc-extern-template/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Conditional Break in GDB</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/conditional-break-in-gdb/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/conditional-break-in-gdb/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 08:42:19 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Debug]]></category>

		<category><![CDATA[gdb]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=58</guid>
		<description><![CDATA[在 gdb 之中，要作 conditional break，首先，我們可能會先查一下現在有哪幾個 breakpoint 在作用中：
[code lang="bash"]
$ info br
[/code]

假設我們要設的是第二個 break point，在某變數 x 大於 3 時停下，就這樣下指令：
[code lang="bash"]
$ cond 2 x > 3
[/code]

如果要改設別的 condition，可以這樣下取消
[code lang="bash"]
$ cond 2
[/code]

或者直接改設別的條件也可以
[code lang="bash"]
$ cond 2 y == 77
[/code]

附帶一提，continue (cont) 也滿好用的。在 for-loop 之中常常會想要一次跳個 100, 1000 個 iteration 之類的。那可以這樣下：
[code lang="bash"]
cont 1000
[/code]

下次再按 enter 會重複上一個指令，於是就會以 1000 個 iteration 為單位作 break。

我很久沒用 VC，不過可以想見這在 VC 之中應該是選單拉來拉去才能完成。gdb 的學習曲線較陡一些，但上手之後會不少人都會喜歡上這簡潔明快的節奏感。其實 gvim 啦、gcc 等等也是如此，算是 opensource 工具很常見的一個共通點。



]]></description>
			<content:encoded><![CDATA[<p>在 gdb 之中，要作 conditional break，首先，我們可能會先查一下現在有哪幾個 breakpoint 在作用中：</p>
<div class="codesnip-container" >
<div class="codesnip">$ info br</div>
</div>
<p>假設我們要設的是第二個 break point，在某變數 x 大於 3 時停下，就這樣下指令：</p>
<div class="codesnip-container" >
<div class="codesnip">$ cond <span class="nu0">2</span> x &amp;gt; <span class="nu0">3</span></div>
</div>
<p>如果要改設別的 condition，可以這樣下取消</p>
<div class="codesnip-container" >
<div class="codesnip">$ cond <span class="nu0">2</span></div>
</div>
<p>或者直接改設別的條件也可以</p>
<div class="codesnip-container" >
<div class="codesnip">$ cond <span class="nu0">2</span> y == <span class="nu0">77</span></div>
</div>
<p>附帶一提，continue (cont) 也滿好用的。在 for-loop 之中常常會想要一次跳個 100, 1000 個 iteration 之類的。那可以這樣下：</p>
<div class="codesnip-container" >
<div class="codesnip">cont <span class="nu0">1000</span></div>
</div>
<p>下次再按 enter 會重複上一個指令，於是就會以 1000 個 iteration 為單位作 break。</p>
<p>我很久沒用 VC，不過可以想見這在 VC 之中應該是選單拉來拉去才能完成。gdb 的學習曲線較陡一些，但上手之後會不少人都會喜歡上這簡潔明快的節奏感。其實 gvim 啦、gcc 等等也是如此，算是 opensource 工具很常見的一個共通點。</p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/11/conditional-break-in-gdb/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SVN 30 秒就上手</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/svn-create-project/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/svn-create-project/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 05:24:41 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[SVN]]></category>

		<category><![CDATA[VersionControl]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=57</guid>
		<description><![CDATA[Subversion，通稱 SVN，是個很好用的版本控制系統，在這邊寫一下 import 一個 project 時最常用的幾個指令。

如果沒有 svn 的話可以下一行指令就裝好（Ubuntu, Debian）：
[code lang="bash"]
sudo apt-get install subversion
[/code]

最先要作的是在 svn 裡面開一個存放 svn 所需檔案的地方：
[code lang="bash"]
svnadmin create /home/user-name/svn/project-name
[/code]

切到打算要匯入的 project 路徑下，用這行指令 import 進去：
[code lang="bash"]
import . file:///home/user-name/svn/project-name
[/code]
路徑前面要加 file:// 因為偶爾我們會用不同的協定如 http:// 等等

接下來可以大膽的把原來的 directory 刪掉，再 checkout 一份有 svn 加持過的：
[code lang="bash"]
cd ..
rm -rf project-name
svn co file:///home/user-name/svn/project-name
[/code]

這樣就搞定了。在 svn 加持過的這個 workspace 裡面就有完整的 svn 功能。之後如果有改就用 svn ci, svn up 等等去 update。到此為止應該很簡單，最後附上一份 manual 給大家參考。]]></description>
			<content:encoded><![CDATA[<p>Subversion，通稱 SVN，是個很好用的版本控制系統，在這邊寫一下 create 一個 project 時最常用的幾個指令。</p>
<p>如果沒有 svn 的話可以下一行指令就裝好（Ubuntu, Debian）：</p>
<div class="codesnip-container" >
<div class="codesnip">sudo apt-get install subversion</div>
</div>
<p>首先要作的是開一個存放 svn 所需檔案的地方：</p>
<div class="codesnip-container" >
<div class="codesnip">svnadmin create /home/user-name/svn/project-name</div>
</div>
<p>切到打算要匯入的 project 路徑下，用這行指令 import 進去：</p>
<div class="codesnip-container" >
<div class="codesnip">svn import . file:///home/user-name/svn/project-name</div>
</div>
<p>路徑前面要加 file:// 因為偶爾我們會用不同的協定如 http:// 等等</p>
<p>接下來可以大膽的把原來的 directory 刪掉，再 checkout 一份有 svn 加持過的：</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="kw3">cd</span> ..<br />
rm -rf project-name<br />
svn co file:///home/user-name/svn/project-name</div>
</div>
<p>這樣就搞定了。在 svn 加持過的這個 workspace 裡面就有完整的 svn 功能。之後如果有改就用 svn ci, svn up 等等去 update。到此為止應該很簡單，最後附上一份 <a href="http://svnbook.red-bean.com/en/1.5/index.html" target="_blank">manual</a> 給大家參考。</p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/svn-create-project/feed/</wfw:commentRss>
		</item>
		<item>
		<title>半瓶醋的 C++ 教學（第六章）：開源流萬世一系不敗經典 Hello World 實作</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/cpp-tutorial-ch06/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/cpp-tutorial-ch06/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 11:20:02 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[APT]]></category>

		<category><![CDATA[G++]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Makefile]]></category>

		<category><![CDATA[ProgrammingArt]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=56</guid>
		<description><![CDATA[基本上到目前為止好像都在閒聊（汗），還是讓我們進入實際操作吧，在這邊我們寫一支編程界的經典 Hello World 出來。

Hello World 本質上是一支連玩具都稱不上的程式，但透過寫作，她可以讓我們了解編程的最基本流程，並確認環境設定無誤。我記得自己剛開始編程的時候對環境的設定反而比較苦手，不知道什麼部分該用什麼，不然就是知道該用什麼卻必需一直辜狗；相較之下，語法的部分一開始超簡單，看看書沒兩下就懂了，所以在這邊，如同第零章所述，我想補的是一邊書籍的不足，語法部分就請大家在第一章的推薦書籍之中自修一下。

首先在第四章我們提過了編程環境的選擇，當中我推薦用開源環境來編程，所以在這邊我介紹的是開源流的編程方式，M$ 流的也不難，基本上就是想辦法搞到一片 VC（到底有多少人用正版的？科科），打上 Hello World 再按某個鈕就好了，非常簡單，兩者的差異大致上就像自排車手排車一樣。自排車好開，但要充份享受駕馭極速機器的快感唯有手排，沒有人開藍寶基尼在開自排的吧？

OK，咱們開始吧。

首先你必需要準備的是作業系統。我個人建議想辦法弄台機器灌 *nix，純灌或是雙重開機都可以。*nix 的系統要求並不高，你家如果有舊機器應該就很可以勝任。distro 的話，初學者推 Ubuntu，每半年會升級一次，本文寫就時的版本是 8.04（即 2008 Apr. 發行，8.10 也快出了），可在這裡下載，而這裡有份 step by step 的 installation guide，裝起來非常簡單，下一步下一步就好，甚至比 Windows 還簡單，因為不必準備認證碼 :p。如果不打算自己灌也可用 ssh 連工作站，或是在 Windows 上灌 cygwin 或是 VMware 等等，方法很多。

灌完之後我們分三個階段來介紹：編輯、編譯、執行。

首先是編輯，我們需要 text editor。*nix 系統中應該內建有 gedit 等等的麻瓜 editor，但如果真有心要學編程的話，建議還是用真正巫師在用的 editor 如 vim 或 emacs。我自己是較慣用 vim 的圖形化版本 gvim，因此這邊用 gvim 來介紹。

Ubuntu 為 Debian 系 distro，安裝軟體非常簡便，一行指令就可以完成，package 間的 dependencies 會自動幫你 handle（當然其他 distro 應該也很簡單，最起碼會比 M$ 系簡單很多，連下一步下一步都不必）。以 gvim 為例，下這行指令就可以幫你裝好：
[code lang="bash"]
sudo apt-get install vim-gnome
[/code]
Ubuntu 的套件安裝、管理是用 apt 在做的，有興趣可以看這份 tutorial。其他也有圖形介面，或是 aptitude 可用。圖形介面較麻瓜，aptitude 較適合上級者，apt 則介於兩者之間。

接著我們就可以來「寫程式」了。下這行指令作編輯：
[code lang="bash"]
gvim HelloWorld.cpp
[/code]

gvim 的視窗會被開起來。巫師的 editor 把移動跟編輯分開了，所以一開始用起來可能沒那麼直覺。這份中文 tutorial 很不錯，可以邊看邊玩玩看，現在 vi 的操作並不是我們的重點，之後我可能會寫但這邊先略過，我們輸入下面幾行：
[code lang="c++"]
#include〈stdio.h〉

int main()
{
printf( "Hello World!\n" ) ;
return 0 ;
}
[/code]
如同之前所說的，各符碼所代表的意義就請自己查書。 XD 簡而言之我們是在第 7 行的部分 print 出了一個訊息。其餘主要是 C++ 這個語言所要求的一些形式。

接著是編譯的部分。C++ 在 *nix 上的編譯是用 g++ 這個 compiler 來完成。這裡有一份 tutorial 對他作了簡介。要編譯剛剛寫好的程式，我們下這行指令：
[code lang="bash"]
g++ HelloWorld.cpp -o HelloWorld
[/code]
這樣就會以 HelloWorld.cpp 為 source file 編譯出 HelloWorld 這個可執行檔。g++ 可下各種參數作出不同取向的編譯，比方說 -O2 是對程式效能作最佳化，-g 是把 debugging info 編進去，-Wall 是輸出最多的 warning 訊息等等（這很重要，bug 常常出現在這裡，如果將來有一天你 debug 卡住可以試著用看看這個參數）。更完整的 g++ manual 可以在這裡找。
另外，每次編譯都要打這麼多字好像很煩，所以我們可以用 Makefile 來自動化編譯流程，這裡有一份 tutorial，有空我也會寫寫自己對 Makefile 的心得。

最後就是執行了。我們的執行檔通常直接下就可以了，不必給路徑，比方說 ls 就直接 ls 不必 /bin/ls。那是因為我們有把 /bin 加入 PATH 這個環境變數的原因。但通常我們存放自己寫的 program 的 path 並沒有 include 在 PATH 當中。所以必須給路徑，一般來說相對路徑即可，所以我們下：
[code lang="bash"]
./HelloWorld
[/code]
應該會得到
[code lang="bash"]
Hello World!
[/code]
這樣的 output，那就大功告成了！這便是萬世一系的不敗經典 Hello World 是也！

其他還有 gdb 可作一般性質 debug，valgrind 可作 memory debug，gprof 可作程式效能分析，暫且打住，改天再提吧。 :)]]></description>
			<content:encoded><![CDATA[<p>基本上到目前為止好像都在閒聊（汗），還是讓我們進入實際操作吧，在這邊我們寫一支編程界的經典 Hello World 出來。</p>
<p>Hello World 本質上是一支連玩具都稱不上的程式，但透過寫作，她可以讓我們了解編程的最基本流程，並確認環境設定無誤。我記得自己剛開始編程的時候對環境的設定反而比較苦手，不知道什麼部分該用什麼，不然就是知道該用什麼卻必須一直辜狗；相較之下，語法的部分一開始超簡單，看看書沒兩下就懂了，所以在這邊，如同<a href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/05/cpp-tutorial-ch00/" target="_blank">第零章</a>所述，我想補的是一般書籍的不足，語法部分就請大家在<a href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/05/cpp-tutorial-ch01/" target="_blank">第一章</a>的推薦書籍之中自修一下。</p>
<p>首先在<a href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/cpp-tutorial-ch04/" target="_blank">第四章</a>我們提過了編程環境的選擇，當中我推薦用開源環境來編程，所以在這邊我介紹的是開源流的編程方式，M$ 流的也不難，基本上就是想辦法搞到一片 VC（到底有多少人用正版的？科科），打上 Hello World 再按某個鈕就好了，非常簡單，兩者的差異大致上就像自排車手排車一樣。自排車好開，但要充份享受駕馭極速機器的快感唯有手排，沒有人開<a href="http://www.lamborghini.com/" target="_blank">藍寶基尼</a>在開自排的吧？</p>
<p>OK，咱們開始吧。</p>
<p><span id="more-56"></span></p>
<p>首先你必需要準備的是作業系統。我個人建議想辦法弄台機器灌 *nix，純灌或是雙重開機都可以。*nix 的系統要求並不高，你家如果有舊機器應該就很可以勝任。distro 的話，初學者推 <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a>，每半年會升級一次，本文寫就時的版本是 8.04（即 2008 Apr. 發行，8.10 也快出了），可在<a href="http://www.ubuntu.com/getubuntu" target="_blank">這裡</a>下載，而這裡有份 step by step 的 <a href="https://help.ubuntu.com/community/GraphicalInstall" target="_blank">installation guide</a>，裝起來非常簡單，下一步下一步就好，甚至比 Windows 還簡單，因為不必準備認證碼 :p。如果不打算自己灌也可用 ssh 連工作站，或是在 Windows 上灌 <a href="http://www.cygwin.com/" target="_blank">cygwin</a> 或是 <a href="http://www.vmware.com/" target="_blank">VMware</a> 等等，方法很多。</p>
<p>灌完之後我們分三個階段來介紹：編輯、編譯、執行。</p>
<p>首先是編輯，我們需要 text editor。*nix 系統中應該內建有 <a href="http://www.gnome.org/projects/gedit/" target="_blank">gedit</a> 等等的麻瓜 editor，但如果真有心要學編程的話，建議還是用真正巫師在用的 editor 如 vim 或 <a href="http://www.gnu.org/software/emacs/" target="_blank">emacs</a>。我自己是較慣用 vim 的圖形化版本 <a href="http://www.vim.org/" target="_blank">gvim</a>，因此這邊用 gvim 來介紹。</p>
<p>Ubuntu 為 Debian 系 distro，安裝軟體非常簡便，一行指令就可以完成，package 間的 dependencies 會自動幫你 handle（當然其他 distro 應該也很簡單，最起碼會比 M$ 系簡單很多，連下一步下一步都不必）。以 gvim 為例，下這行指令就可以幫你裝好：</p>
<div class="codesnip-container" >
<div class="codesnip">sudo apt-get install vim-gnome</div>
</div>
<p>Ubuntu 的套件安裝、管理是用 apt 在做的，有興趣可以看<a href="http://wiki.freespire.org/index.php/Using_Apt" target="_blank">這份 tutorial</a>。其他也有圖形介面，或是 aptitude 可用。圖形介面較麻瓜，aptitude 較適合上級者，apt 則介於兩者之間。</p>
<p>接著我們就可以來「寫程式」了。下這行指令作編輯：</p>
<div class="codesnip-container" >
<div class="codesnip">gvim HelloWorld.cpp</div>
</div>
<p>gvim 的視窗會被開起來。巫師的 editor 把移動跟編輯分開了，所以一開始用起來可能沒那麼直覺。<a href="http://edt1023.sayya.org/vim/node1.html" target="_blank">這份中文 tutorial</a> 很不錯，可以邊看邊玩玩看，現在 vi 的操作並不是我們的重點，之後我可能會寫但這邊先略過，我們輸入下面幾行：</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="co2">#include〈stdio.h〉</span></p>
<p><span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span> <span class="st0">&#8220;Hello World!<span class="es0">\n</span>&#8220;</span> <span class="br0">&#41;</span> ;<br />
<span class="kw1">return</span> <span class="nu0">0</span> ;<br />
<span class="br0">&#125;</span></div>
</div>
<p>如同之前所說的，各符碼所代表的意義就請自己查書。 XD 簡而言之我們是在 printf 那一行 print 出了一個訊息。其餘主要是 C++ 這個語言所要求的一些形式。</p>
<p>接著是編譯的部分。C++ 在 *nix 上的編譯是用 g++ 這個 compiler 來完成。<a href="http://web.wm.edu/computerscience/computing/gpp.php" target="_blank">這裡</a>有一份 tutorial 對他作了簡介。要編譯剛剛寫好的程式，我們下這行指令：</p>
<div class="codesnip-container" >
<div class="codesnip">g++ HelloWorld.cpp -o HelloWorld</div>
</div>
<p>這樣就會以 HelloWorld.cpp 為 source file 編譯出 HelloWorld 這個可執行檔。g++ 可下各種參數作出不同取向的編譯，比方說 -O2 是對程式效能作最佳化，-g 是把 debugging info 編進去，-Wall 是輸出最多的 warning 訊息等等（這很重要，bug 常常出現在這裡，如果將來有一天你 debug 卡住可以試著用看看這個參數）。更完整的 g++ manual 可以在<a href="http://gcc.gnu.org/onlinedocs/" target="_blank">這裡</a>找。<br />
另外，每次編譯都要打這麼多字好像很煩，所以我們可以用 <a href="http://www.gnu.org/software/make/manual/make.html" target="_blank">Makefile</a> 來自動化編譯流程，這裡有一份 <a href="http://www.hsrl.rutgers.edu/ug/make_help.html" target="_blank">tutorial</a>，有空我也會寫寫自己對 Makefile 的心得。</p>
<p>最後就是執行了。許多系統內建的執行檔通常直接下就可以了，不必給路徑，比方說 ls 就直接 ls 不必 /bin/ls。那是因為我們有把 /bin 加入 PATH 這個環境變數的原因。但通常我們存放自己寫的 program 的 path 並沒有 include 在 PATH 當中，所以必須給路徑。一般來說相對路徑即可，所以我們下：</p>
<div class="codesnip-container" >
<div class="codesnip">./HelloWorld</div>
</div>
<p>應該會得到</p>
<div class="codesnip-container" >
<div class="codesnip">Hello World!</div>
</div>
<p>這樣的 output，那就大功告成了！這便是萬世一系的不敗經典 Hello World 是也！</p>
<p>其他還有 <a href="http://www.gnu.org/software/gdb/" target="_blank">gdb</a> 可作一般性質 debug，<a href="http://valgrind.org/" target="_blank">valgrind</a> 可作 memory debug，<a href="http://www.cs.utah.edu/dept/old/texinfo/as/gprof_toc.html" target="_blank">gprof</a> 可作程式效能分析，<a href="http://subversion.tigris.org/" target="_blank">subversion</a> 可作源碼版本控制…等等。暫且打住，改天再提吧。 <img src='http://graphics.csie.ntu.edu.tw/~jonathan/tpd/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/cpp-tutorial-ch06/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 下 rmvb 沒聲音</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/rmvb-no-soun/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/rmvb-no-soun/#comments</comments>
		<pubDate>Sat, 11 Oct 2008 02:34:03 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[rmvb]]></category>

		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=55</guid>
		<description><![CDATA[有時候播 rmvb 會沒聲音，不需要灌 plugin，只要調一下參數就可以。編輯 ~/.xine/catalog.cache，找到 [/usr/lib/xine/plugins/1.1.4/xineplug_decode_real_audio.so] 這段，將 decoder_priority 調高為 10 即可：

[code lang="bash"]

[/usr/lib/xine/plugins/1.1.4/xineplug_decode_real_audio.so]
size=11300
mtime=1171041406
type=131
api=15
id=realadec
version=10104
supported_types=52494336 52559872 52756480
decoder_priority=10
[/code]

參考資料：
argh no sound in rmvb @ Ubuntu Forums
]]></description>
			<content:encoded><![CDATA[<p>有時候播 rmvb 會沒聲音，不需要灌 plugin，只要調一下參數就可以。編輯 ~/.xine/catalog.cache，找到  [/usr/lib/xine/plugins/1.1.4/xineplug_decode_real_audio.so] 這段，將 decoder_priority 調高為 10 即可：</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="br0">&#91;</span>/usr/lib/xine/plugins/<span class="nu0">1</span>.<span class="nu0">1</span>.<span class="nu0">4</span>/xineplug_decode_real_audio.so<span class="br0">&#93;</span><br />
<span class="re2">size=</span><span class="nu0">11300</span><br />
<span class="re2">mtime=</span><span class="nu0">1171041406</span><br />
<span class="re2">type=</span><span class="nu0">131</span><br />
<span class="re2">api=</span><span class="nu0">15</span><br />
<span class="re2">id=</span>realadec<br />
<span class="re2">version=</span><span class="nu0">10104</span><br />
<span class="re2">supported_types=</span><span class="nu0">52494336</span> <span class="nu0">52559872</span> <span class="nu0">52756480</span><br />
<span class="re2">decoder_priority=</span><span class="nu0">10</span></div>
</div>
<p>參考資料：<br />
<a href="http://ubuntuforums.org/showthread.php?t=320672" target="_blank"><strong>argh no sound in rmvb</strong> @ Ubuntu Forums</a></p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/10/rmvb-no-soun/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Linux Find</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/linux-find/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/linux-find/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 08:07:51 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Find]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=54</guid>
		<description><![CDATA[recursively 殺掉同樣副檔名的檔案（以 jpg 為例）

[code lang="bash"]
find -name "*.jpg" -exec rm {} \;
[/code]

-exec 找到以後對這些檔案執行的指令
{} 會被代換作檔名
\; 表 -exec 指令結束，為特殊字元，故需 back slash

recursively 殺掉除某副檔名以外的檔案（以 c, cpp, h 為例）

[code lang="bash"]
find ! -regex '.*\.\(c\&#124;h\&#124;cpp\)' -exec rm {} \;
[/code]

! 表反向選擇

複雜但是相當強大。身為一位巫師應該經常將自動化放在心裡。而這點正是 Linux 優越的地方。

附上連結一枚：
Using the find command]]></description>
			<content:encoded><![CDATA[<ol>
<li>recursively 殺掉同樣副檔名的檔案（以 jpg 為例）
<div class="codesnip-container" >
<div class="codesnip">find -name <span class="st0">&#8220;*.jpg&#8221;</span> -<span class="kw3">exec</span> rm <span class="br0">&#123;</span><span class="br0">&#125;</span> \;</div>
</div>
<p><strong><br />
-exec</strong> 找到以後對這些檔案執行的指令<strong><br />
{}</strong> 會被代換作檔名<strong><br />
\;</strong> 表 -exec 指令結束，為特殊字元，故需 back slash</li>
<li>recursively 殺掉除某副檔名以外的檔案（以 c, cpp, h 為例）
<div class="codesnip-container" >
<div class="codesnip">find ! -regex <span class="st0">&#8216;.*<span class="es0">\.</span><span class="es0">\(</span>c<span class="es0">\|</span>h<span class="es0">\|</span>cpp<span class="es0">\)</span>&#8216;</span> -<span class="kw3">exec</span> rm <span class="br0">&#123;</span><span class="br0">&#125;</span> \;</div>
</div>
<p><strong><br />
! </strong>表反向選擇</li>
</ol>
<p>有點小複雜但是相當強大。身為一位巫師應該經常將自動化放在心裡。而這點正是 Linux 優越的地方。附上連結一枚： <a href="http://www.linux.ie/newusers/beginners-linux-guide/find.php" target="_blank"><br />
Using the find command</a></p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/linux-find/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ubuntu 無線網路設定</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/ubuntu-wireless-networ/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/ubuntu-wireless-networ/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 07:58:16 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Network]]></category>

		<category><![CDATA[Wireless]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=53</guid>
		<description><![CDATA[把 Ubuntu 灌好，正常來講網卡都可以抓得到，訊號應該也沒問題。只要在 ESSID 的部分指定好你要的 AP 就可以。

若不經 WEP 加密的 AP 可以說是灌好馬上就可以用；經過加密的卻稍微麻煩一點，之前用內建套件輸入 encrypted key 不知為何並不能使用，應該是隻 bug。經過爬文之後大約歸納出三個 solution：

   1. sudo gvim /etc/network/interfaces
      編輯形如下式：
      iface eth1 inet dhcp
      wireless-essid tokyomod
      wireless-key s:meoap# 加 "s:" 表 ASCII，不加則為 HEX
      經過測試，此法可以使用，不過要 reboot 或 hibernate 重開… = =
   2. $iwconfig ath0 key XXXXX
      尚未測試。
   3. sudo gvim /etc/pcmcia/wireless.opt
      大致上同 1，不過還沒測過。

]]></description>
			<content:encoded><![CDATA[<p>把 Ubuntu 灌好，正常來講網卡都可以抓得到，訊號應該也沒問題。只要在 ESSID 的部分指定好你要的 AP 就可以。</p>
<p>若不經 WEP 加密的 AP 可以說是灌好馬上就可以用；經過加密的卻稍微麻煩一點，之前用內建套件輸入 encrypted key 不知為何並不能使用，應該是隻 bug。經過爬文之後大約歸納出三個 solution：</p>
<ol>
<li>
<div class="codesnip-container" >
<div class="codesnip">sudo gvim /etc/network/interfaces</div>
</div>
<p>編輯形如下式：</p>
<div class="codesnip-container" >
<div class="codesnip">iface eth1 inet dhcp<br />
wireless-essid tokyomod<br />
wireless-key s:meoap<span class="co1"># 加 &quot;s:&quot; 表 ASCII，不加則為 HEX </span><br />
&nbsp;</div>
</div>
<p>經過測試，此法可以使用，不過要 reboot 或 hibernate 重開</li>
<li>
<div class="codesnip-container" >
<div class="codesnip"><span class="re1">$iwconfig</span> ath0 key XXXXX</div>
</div>
<p>尚未測試。</li>
<li>
<div class="codesnip-container" >
<div class="codesnip">sudo gvim /etc/pcmcia/wireless.opt</div>
</div>
<p>大致上同 1，不過還沒測過。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/ubuntu-wireless-networ/feed/</wfw:commentRss>
		</item>
		<item>
		<title>cout 與 printf 效率比較</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cout-and-print/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cout-and-print/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 14:28:45 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[Efficiency]]></category>

		<category><![CDATA[OlineJudge]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=52</guid>
		<description><![CDATA[平常寫 research code 比較沒什麼感覺。最近無聊寫起 UVa Online Judge 就對效能比較在意一點。

今天才知道原來 printf 比 cout 快、scanf 比 cin 快、\n 比 endl 快。

有興趣可以自己 print 一堆 hello world 出來試看看。我測的結果大致上是十比九左右。


]]></description>
			<content:encoded><![CDATA[<p>平常寫 research code 比較沒什麼感覺。最近無聊寫起 <a href="http://icpcres.ecs.baylor.edu/onlinejudge/" target="_blank">UVa Online Judge</a> 就對效能比較在意一點。</p>
<p>今天才知道原來 printf 比 cout 快、scanf 比 cin 快、\n 比 endl 快。</p>
<p>有興趣可以自己 print 一堆 hello world 出來試看看。我測的結果大致上是十比九左右。</p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cout-and-print/feed/</wfw:commentRss>
		</item>
		<item>
		<title>C++ 底下 string 與 int 的互轉</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cpp-string-int-conversion/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cpp-string-int-conversion/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 14:22:06 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[atoi]]></category>

		<category><![CDATA[int]]></category>

		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=51</guid>
		<description><![CDATA[string 要轉 int 相對簡單，用 atoi 即可：
[code lang="c++"]
#include <cstdlib>
using namespace std;
atoi(input_string.c_str());
[/code]

但 int 要轉 string 就麻煩一點，雖然 itoa 這個 non-standard function 也不算太不常見，但不在標準裡面，最起碼 gcc 就沒支援。標準的作法應該是用 stringstream：
[code lang="c++"]
#include <iostream>
#include <stringstream>
using namespace std;

stringstream ss;
ss << input_number;
cout << ss.str() << endl;
[/code]

三個問題：首先、atoi 本身名稱有點醜。第二、有 atoi 卻沒有 itoa 是很莫名的不對稱性。第三、用到 stringstream 增加不必要的複雜度。有時候不得不承認 C++ 語法是太過駁雜不純了一點。string int 互轉又很常用…]]></description>
			<content:encoded><![CDATA[<p>string 要轉 int 相對簡單，用 atoi 即可：</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="co2">#include &amp;lt;cstdlib&amp;gt;</span><br />
using namespace std;<br />
atoi<span class="br0">&#40;</span>input_string.<span class="me1">c_str</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</div>
<p>但 int 要轉 string 就麻煩一點，雖然 itoa 這個 non-standard function 也不算太不常見，但不在標準裡面，最起碼 gcc 就沒支援。標準的作法應該是用 stringstream：</p>
<div class="codesnip-container" >
<div class="codesnip"><span class="co2">#include &amp;lt;iostream&amp;gt;</span><br />
<span class="co2">#include &amp;lt;stringstream&amp;gt;</span><br />
using namespace std;</p>
<p>stringstream ss;<br />
ss &amp;lt;&amp;lt; input_number;<br />
<a href="http://www.opengroup.org/onlinepubs/009695399/functions/cout.html"><span class="kw3">cout</span></a> &amp;lt;&amp;lt; ss.<span class="me1">str</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &amp;lt;&amp;lt; endl;</div>
</div>
<p>三個問題：首先、atoi 本身名稱有點醜。第二、有 atoi 卻沒有 itoa 是很莫名的不對稱性。第三、用到 stringstream 增加不必要的複雜度。有時候不得不承認 C++ 語法是太過駁雜不純了一點。string int 互轉又很常用…</p>
<p>p.s &#8220;&gt;&#8221;, &#8220;&lt;&#8221; 在 code snippet 當中會爛掉，爬了一下 google 暫時沒找到 solution，有空再回來修。若有其他 code display plugin on wordpress 也網友們推薦，找很久了。= =</p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/09/cpp-string-int-conversion/feed/</wfw:commentRss>
		</item>
		<item>
		<title>半瓶醋的 C++ 教學（第五章）：編程語言的軍團論</title>
		<link>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/cpp-tutorial-ch05/</link>
		<comments>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/cpp-tutorial-ch05/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 13:22:28 +0000</pubDate>
		<dc:creator>jutirain</dc:creator>
		
		<category><![CDATA[C++]]></category>

		<category><![CDATA[ProgrammingArt]]></category>

		<category><![CDATA[ProgrammingLanguage]]></category>

		<guid isPermaLink="false">http://graphics.csie.ntu.edu.tw/~jonathan/tpd/?p=50</guid>
		<description><![CDATA[編程界裡面有許多爭論不休的話題。語言之爭是最主要之一。就像宗教有各種流派一樣，信或不信有時只是個人價值觀，這種爭論說起來就跟宗教戰爭沒什麼兩樣。
我自己的看法是這樣，就像一個專業的投手需要配球一樣，一個專業的 programmer 也至少需要兩種以上用起來順手的語言。用軍隊來比喻或許更為恰當。一支現代化的軍隊不可能只有步兵，也不可能只有重裝甲部隊。根據戰略戰術需求的不同，在兵種之間取得適當的平衡，才能讓戰力達到最大化。但兵種之間，比方說，戰機到底要裝備蘇系的 SU-27 還是美系的 F-22 就看各人喜好了。只要記得在這個講究制空權的時代，買戰艦的時候別去買到過時的巨大戰列艦大和號就好。

那麼，在編程的世界裡我們怎樣裝備自己的語言比較好呢？既然標題是 C++ 教學，就先來談談 C++ 好了。
C/C++，一言以敝之，是編程界的重裝甲部隊。他的戰鬥能力強大（效率高），用途廣泛，從高階應用到低階系統幾乎無所不能，但最大的問題在於機動力（開發效率較低）。此階級語言，相類似的還有 Java, C# 等等可供選擇。C# 之前微軟在推的，後來有人 port 到 *nix 平台上，但基本上開源界還是不多人用，之後微軟如果又不推的話…如同我在第四章所講的一般，語言、工具要看得長遠，才能讓自己所投注精力的報酬率得到最大。
Java 的話寫過一陣子，的確比 C++ 開發效率高一些。語法也比較純粹，比起 C++ 那種「語言聯邦」式的狀況簡潔許多，跨平台也較容易，不像我現在作研究常常拿到別人用 MFC 包 GUI 的 code 就 port 不過來…但 Java 的最大問題就在效率。說實在我沒有很精確的比較過（把幾支具代表性的程式分別寫成要比較的語言），但 Java 給人的印象就是慢。固然有人宣稱 Java 跑某些 benchmark 是跟 C++ 差不多的，我不知道他們跑了什麼 benchmark，跟我個人的經驗是有很大的出入就是了。Java 慢到我覺得差不多跟 Python 之類的 scripting language 差不多了…也因此儘管 Java 有我個人欣賞的語法純粹、跨平台等優點，只好捨棄不用，若要為了這種程度的開發效率上的提升，而以巨大的執行效率作為代價，不如直接來寫 scripting language 算了。
就像 C++ [...]]]></description>
			<content:encoded><![CDATA[<p>編程界裡面有許多爭論不休的話題。語言之爭是最主要之一。就像宗教有各種流派一樣，信或不信有時只是個人價值觀，這種爭論說起來就跟宗教戰爭沒什麼兩樣。</p>
<p>我自己的看法是這樣，就像一個專業的投手需要配球一樣，一個專業的 programmer 也至少需要兩種以上用起來順手的語言。用軍隊來比喻或許更為恰當。一支現代化的軍隊不可能只有步兵，也不可能只有重裝甲部隊。根據戰略戰術需求的不同，在兵種之間取得適當的平衡，才能讓戰力達到最大化。但兵種之間，比方說，戰機到底要裝備蘇系的 SU-27 還是美系的 F-22 就看各人喜好了。只要記得在這個講究制空權的時代，買戰艦的時候別去買到過時的巨大戰列艦大和號就好。</p>
<p><span id="more-50"></span></p>
<p>那麼，在編程的世界裡我們怎樣裝備自己的語言比較好呢？既然標題是 C++ 教學，就先來談談 C++ 好了。</p>
<p>C/C++，一言以敝之，是編程界的重裝甲部隊。他的戰鬥能力強大（效率高），用途廣泛，從高階應用到低階系統幾乎無所不能，但最大的問題在於機動力（開發效率較低）。此階級語言，相類似的還有 Java, C# 等等可供選擇。C# 之前微軟在推的，後來有人 port 到 *nix 平台上，但基本上開源界還是不多人用，之後微軟如果又不推的話…如同我在<a href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/cpp-tutorial-ch04/" target="_blank">第四章</a>所講的一般，語言、工具要看得長遠，才能讓自己所投注精力的報酬率得到最大。</p>
<p>Java 的話寫過一陣子，的確比 C++ 開發效率高一些。語法也比較純粹，比起 C++ 那種「語言聯邦」式的狀況簡潔許多，跨平台也較容易，不像我現在作研究常常拿到別人用 MFC 包 GUI 的 code 就 port 不過來…但 Java 的最大問題就在效率。說實在我沒有很精確的比較過（把幾支具代表性的程式分別寫成要比較的語言），但 Java 給人的印象就是慢。固然有人宣稱 Java 跑某些 benchmark 是跟 C++ 差不多的，我不知道他們跑了什麼 benchmark，跟我個人的經驗是有很大的出入就是了。Java 慢到我覺得差不多跟 Python 之類的 scripting language 差不多了…也因此儘管 Java 有我個人欣賞的語法純粹、跨平台等優點，只好捨棄不用，若要為了這種程度的開發效率上的提升，而以巨大的執行效率作為代價，不如直接來寫 scripting language 算了。</p>
<p>就像 C++ 是 C 的改進版，最近有個語言 D 也自認是 C++ 的接班人。我幾乎沒有碰這個語言，不過如果他能把 C++ 雜亂的語法修正一些，搞不好在不遠（？）的將來會是個很不錯的選擇。</p>
<p>與 compiled language 相對的便是 scripting language。威力略遜重裝甲部隊（執行效率較低），但部署上極為機動（開發效率較高），可以稱得上是編程界的輕騎兵或是傘兵之類的，當你需要寫一些小程式，字串處理啦、<a href="http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/python-wretch-grabber/" target="_blank">無名抓圖</a>啦或是系統管理之類的，犯不著用 C/C++，那樣太笨重了，這時候用 scripting language 就可以搞定。</p>
<p>而在 scipriting language 當中，人們常提起的是所謂 3P1R: PHP, Perl, Python, Ruby。PHP 是網路編程很常用的語言，早期（好吧，其實也沒那麼早期）動態網站最常用的就是所謂 LAMP 的工具組合：Linux, Apache, MySQL, PHP。包括我現在用的 Wordpress 這個 blog 套件也是 PHP 所寫成。但說實在 PHP 的語法也不是那麼漂亮，所以轉移到另外 2P1R 的人也越來越多。</p>
<p>Perl 的話以「拋棄式語言」著名。字串處理很強，但是過一陣子回來看這程式就廢掉了，因為你看不懂。不太符合我的風格。</p>
<p>剩下 Python, Ruby。說實在話兩個都是很不錯的語言，以哪邊為主我也著實猶豫了一陣子。儘管 Python 也宣稱自己很有禪意，但單就語法來說其實 Ruby 真的是很乾淨很漂亮的，不得不承認。但現時點 Python 的社群、程式庫各方面支援較齊備（連 Google 也是把 Python 當作 official language），因此我選擇了 Python。另外我學 scripting language 很重要的是想用 web framework。這部分我喜歡 Python 的 Django 勝過 Ruby 的 Rails 一些些。</p>
<p>我建議如果時間、能力許可的話至少要熟一種 compiled language，一種 scripting language，如果兩者之間搭配得不錯，那就更好。我自己花比較多精神的是 C++ 與 Python。單獨寫的話都是不錯的語言，用 SWIG 之類摻在一起也很不錯。我自己的理想是 scripting 作 glue code，底層需要效率的再用 C++ 寫成可被 Python 呼叫的 module。</p>
<p>那為什麼我要首先來寫 C++ 的教學呢？因為現在的編程教學大部分都還是以 C++ 作為起頭。但如果將來有一天我當上某資工系的系主任，我倒是比較傾向讓同學大一上先學 Python 之類的 scripting language，把編程的觀念先打好了，下學期再來學 C++，屆時就可以專注在 C++ 深不可測的語言細節之中。</p>
<p><strong>參考資料：</strong><br />
<a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" target="_blank"> TIOBE 語言排名</a></p>
]]></content:encoded>
			<wfw:commentRss>http://graphics.csie.ntu.edu.tw/~jonathan/tpd/2008/08/cpp-tutorial-ch05/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
