目前分類:C&C++ (51)
- Aug 07 Sun 2016 17:44
函數解析器
- Mar 05 Sat 2016 01:28
用 template 產生 Bose-Nelson Sorting Network
在排序固定長度的小陣列時,那些 big-O 優異的演算法往往討不到便宜,而且還很容易因為多餘的操作而拖慢速度。Sorting Network 就是為了排序固定長度的小陣列而發明的。Sorting Network 是一組事先規劃好的比較、交換操作,只要按照固定步驟操作就能將資料排序。
若一個 Sorting Network 滿足某些條件,就可以將操作步驟平行化或者實作成平行排序硬體,這是這類演算法最大的優勢,不過這不是本文的重點。即使在沒有平行化的情況下,Sorting Network 作為循序執行的排序法效能通常也不錯,至少可以狂電 Bubble、Insertion sort,而且所有的動作都是固定的,可以輕易寫成一連串無迴圈的 if-swap 串,這在「big-O不代表一切」的小資料世界裡具有實作優勢。
- May 15 Fri 2015 01:24
ld 小把戲
今天和同事聊到「真搞不懂為什麼某些人那麼容易中毒?」這個話題時,剛好心血來潮,順手示範了一個從前曾拿來整人用的老把戲。
這個把戲就是用 linker 把某個二進制資料嵌入到執行檔中,變成其中一個區段。當然,其中沒什麼高深的學問,只是因為很多人沒有仔細玩過 binutils,不曉得 ld 有這樣的功能。
- Feb 12 Thu 2015 01:40
對 C++ 物件一個常見的誤解
今天有位幫一位朋友釐清觀念的時候,發現他對物件的記憶體分配有些誤解。這位朋友告訴我他的資訊來源是這個網頁:
http://ot-note.logdown.com/posts/173174/note-cpp-named-type-convertion
- Sep 05 Fri 2014 01:46
談 C++11 的 Inline Namespace
C++14 都出來了,C++11 仍然有很多東西我沒有好好吸收,主要是因為在現實中沒有什麼使用機會,只是在閒暇時囫圇吞棗般看了一堆文章而已。舉例來說,inline namespace 就是一個我最近才仔細研究使用情境的機制。
C++11 的 inline namespace 主要功能在於,讓撰寫者可以在 namespace 建立抽象層,在底層切換不同版本。
- Aug 24 Sun 2014 16:20
關於 ld 的連結順序
之所以會有這篇文章,源於前天發生的一件笨事。我正在為手邊新專案撰寫 CMakeLists,結果在編譯某個 DLL 的時候出現錯誤,主要的訊息是一堆 "Undefined reference to..."。
我對這類的玩意還算蠻有經驗的,快速確定了該連結的東西都有寫到,剩下比較有可能的大概就是連結順序的問題。但這實在不太可能發生,我一向非常留意這些細節。
- Aug 02 Sat 2014 22:22
Boost.Log:依內容改變輸出顏色
有一個很簡單的需求,一開始我以為對 Boost.Log 這樣功能強大的程式庫應該輕而易舉,結果花了我一點時間才摸出門徑。條件是這樣子的:
- 必須支援命令列和檔案輸出。
- 在支援 ANSI color code 的環境中,允許使用者啟用彩色輸出,程式會依照 log record 的 severity level 改變輸出顏色。
- 若環境不支援 ANSI color code,程式不應該輸出色彩,否則可讀性會慘遭 ANSI color code 破壞。
- 無論如何檔案都不應該輸出 ANSI color code,理由同上,更何況各家的 log viewer 都已經有自動上色的功能了。
假設既有的片段如下,為了簡短起見,一些細節被我簡化了,這不是隨貼即用程式碼。
- Dec 05 Thu 2013 01:30
除了功能正確以外
大概兩週前有位網友在調查有多少人了解下面這個宣告式:
unsigned int n = -1;
我看到這個問題的時候,已經有不少人實驗得出結果,並且也開始討論這段程式碼的風格問題。以上程式碼的作用在於將 n 所有 bit 設為 1,這是一個非常可靠的行為 -- C 和 C++ 語言標準中對由 signed 到 unsigned 的轉型有段謎語般的詳盡敘述,事實上在採用 2 補數的環境中,所謂轉型的實質行為就只是把位元照搬過去而已(至於採用其他數字系統的平台太罕見,以下不討論)。
- Jun 25 Tue 2013 20:52
在編譯期選擇演算法
假設程式需要用到三個演算法,分別是 Foo、Bar、Qwerty,每個演算法可能會有 64-bit 整數、32-bit 整數、SSE2、SSE3 等四種實作方式。
在 32-bit 編譯環境上,通常 32-bit 版本會比 64-bit 版還快,且 SSE 版還會比原生整數更快;反過來說,在 64-bit 編譯環境應當優先使用 64-bit 整數版。基於懶人因素以及現實考量,大部分的演算法在一開始並不會有 SSE 版,只有當現有演算法還有顯著改善空間時,才有足夠的誘因去實作 SSE 版。最後,並非所有平台都支援 SSE,因此必須適時關閉這部份實作。
- Jun 08 Sat 2013 01:40
Back to Basic: 談浮點數的比較
不熟悉浮點數的人最容易犯的錯誤之一,就是直接用 == 或 != 比較兩個浮點數。以最常見的 IEEE 754 浮點數來說,下面這樣的判斷式竟然不成立:
if (0.1 + 0.2 == 0.3)
原因在於以二進位表示的浮點數並沒有辦法精確儲存 0.1、0.2、0.3 這些十進位實數,只能以最接近的浮點數表示,和原本的數值有微小的誤差。三個各自帶有誤差的數字要碰巧讓整個等式成立,實在是相當困難的一件事。基於同樣的理由,在採用 IEEE 754 的環境下,以下程式片段陷入無窮迴圈也就沒什麼好奇怪的了:
- May 27 Mon 2013 20:00
volatile 是不夠的
前幾天剛好逛到幾篇說明 volatile 的文章,其中有關 volatile 在多執行緒環境的應用並不很完整,這裡做一點補充。
簡單來說,volatile 的作用僅僅是告訴編譯器不要用暫存器快取變數,每次使用都必須從資料的原始來源重新載入。
- May 18 Sat 2013 00:37
Smart Ptr 一點訣 (1):使用 intrusive_ptr
前言
之前說過想花點整理 boost 和 C++11 當中 Smart Ptr 使用上的小細節,本系列假設讀者對 Smart Ptr 有一定程度的認識,只做一些重點探討。
目前 smart pointer 的現況:
- Nov 14 Wed 2012 00:30
如何吃掉 debug code
這是一位網友的問題,原問題見http://www.ptt.cc/bbs/C_and_CPP/M.1351841869.A.BAF.html。本部落格之前也稍微碰過這個主題,不過之前的重點在於腦筋急轉彎式的模擬 __VA_ARGS__ 功能,實用性是另一回事。
在開始討論各種作法可行性之前,這裡先宣導一項原則:應該要讓正常輸出與非常態輸出分流,更精確的說,給使用者看的輸出應該要和給開發者看的輸出分流。例如使用 stdout 作為正常輸出時,就不應該也用 stdout 作為非常態輸出,而是改用 stderr 或檔案。實戰中非常態輸出的 sink 很多樣,這裡就不多說了。即使不想多花心力去設計非常態輸出機制,使用基本的 stderr 並不會比用 stdout 多費功夫,好處卻是立即可見,可謂有利而無害。
- Oct 02 Tue 2012 00:54
小小的考題
最近看到有人出了一個考初學者的問題,於是我改了一個複雜化的版本,應該蠻適合拿來鑑別初學者的程度。假設使用的語言為 C++,下面這個 expression 有幾種可能性?
(f(a) && f(b))
任何一個有把教科書第一章念完的人差不多都會回答,執行順序類似於:
- May 06 Sun 2012 19:38
不怎麼有趣的小實驗...
這個實驗在電腦裡躺了一段時間了,雖然不是很有價值的實驗,但想說既然做了不如就整理一下放上來吧。
大約兩個月前在 xkcd 上看到有位仁兄挑戰既有的資料結構常識:「假使只查詢而不需要更新資料,使用排序陣列搭配二分搜尋,效能通常會勝過複雜精巧的二元搜尋樹」。這位仁兄很意外的發現,用 std::lower_bound 對排序過的 vector 做二分搜尋比 map 還慢。他提供的程式很快被網友點出兩個錯誤:
- Apr 18 Wed 2012 17:29
查表法的訣竅--以三角函數為例
算是回答一個網友的問題。(真希望回答問題有錢可拿.....)
在沒有標準程式庫的情況下,計算 sin、cos 這些函數值最直覺的方法可能是用級數逼近。但假如我們只想求有限範圍內離散數字的三角函數值,級數逼近就顯得有點複雜了。
- Oct 30 Sun 2011 02:48
用 SFINAE 偵測 operator
這是一位網友出的問題:要如何偵測某個型別是否可以套用大於運算式( > expression )呢?這裡假設是在 C++ 03 的標準之下。
熟悉 C++ 的網友應該都會想到可以靠 SFINAE 手法解決這類偵測問題。仿照 tr1 type_traits 的使用風格,典型的寫法大概像這樣:
- Aug 06 Sat 2011 23:43
動手玩機器碼
每隔一段時間就會看到有人對機器語言、組合語言感興趣,特別是剛翻了幾本書的初學者,但很多人只對書上幾句描述有點含糊的理解而已。這也未必不好,個人的能力是有限的,應該把精力放在對自己最有價值的事物上。只是有時候看到有初學者指明要學「機器語言」,不免讓人覺得好笑。
如果你真的對機器語言長什麼樣子很感興趣,而且很碰巧使用 x86-32 處理器就繼續往下看吧。以下假設讀者已經對 x86 組合語言有基本的認識。
- Jul 10 Sun 2011 17:37
Code Express 專案頁面及 demo 影片
我幫 Code Express 開了一個 Google code 專案,大家可以去下載來用用看。
功能上和前一版有些許不同,但我現在暫時沒有時間寫說明檔。我想詳細的文字敘述可能沒幾個人有耐心看,不如直接看影片示範吧:
- Jun 30 Thu 2011 02:10
Code Express: 好用的 Notepad++ Snippet Plugin
如果網友常用 Notepad++ 寫程式而且又需要 Snippet 功能,進來這裡就對了。花個五分鐘時間,我介紹一下 Code Express 這個 plugin。
Notepad++ 已經有很多 plugin 了,雖然 Snippet 功能也不少,但我用起來總是不太順手。之前比較有人用的 QuickText 雖然操作簡單,但它改變 Notepad++ 的行為到了難以使用的地步,若是只為了 Snippet 功能實在得不償失。另外兩個非常優秀的實作是 FingerText 和 Zen Coding,其中 Zen Coding 專注在 WEB 開發上,和我平常的應用比較無關;FingerText 和 QuickText 一樣完全採用 Tab 鍵 觸發的方式,使用起來非常方便,並且採用特殊文字標記的方式完全避開 QuickText 的 bug。