顯示具有 Programming 標籤的文章。 顯示所有文章
顯示具有 Programming 標籤的文章。 顯示所有文章

2021年3月21日 星期日

[Refactoring] 編寫可讀代碼 筆記

  • 目標: 給未來的自己看懂
  • 方法: 
    • First level: 外在 - naming, alignment
      • Naming
        • 使用精確的詞: e.g. search / load / …
          • get/set 帶有 lightweight 的概念
          • first/last 代表範圍內頭與尾的指標, begin/end 來表示範圍外的指標
        • 避免 tmp, retval 等沒有解釋性的參數名詞
      • Alignment
        • 用 function / macro 等來對齊程式
        • Group 不同目的的 function lists
          • Constructors / deconstructors
          • Getter / setters
          • helper functions
        • 使用段落來註解程式
          • // 1. register database
          • // 2. init
          • // 3. CRUD operations
          • // 4. release resources
      • Comments
        • 移除沒有意義的註解, e.g. variable name has explained
        • 留下設計理念與意圖的註解 (全局觀)
        • 留下 limitation / FIXME / TODO
        • 提供 example (UT)
    • Second level: control flow
      • loops
        • 避免 do-while (except marco using do-while(0))
        • 大多時候避免 goto function
        • 最小化 embedded loops
      • Expressions / variables
        • 利用暫存的解釋變量減少長表達式, 但有時反過來要移除沒必要的中間變量
        • 盡可能縮小 variable scope (避免 global variables)
        • 善用 marcos 縮短表達式長度
    • Third level: 模組化
      • 善用 utility functions 來做到模組化
      • 利用 wrapper function 簡化 interface
      • 各 function 一次只做一件事
      • 熟悉既有 libraries
      • 善用 scripts 處理簡單工作, e.g. awk parse logs
    • Others:
      • Test-driven
      • Sample refactoring flow: from naïve solution to complete solution
    • 延伸閱讀
      • "Code Complete: A Practical Handbook of Software Construction, 2Ed", Steve McConnell
      • "Refactoring: Improving the Design of Existing Code", Martin Fowler
      • "The Practice of Programming", Brian Kernighan and Rob Pike
      • "Clean Code: A Handbook of Agile Software Craftsmanship", RobertC. Martin
      • "Design Patterns: Elements of Reusable Object-Oriented Software", Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
      • "Programming Pearls, 2Ed", Jon Bentley

2021年1月4日 星期一

[Programming] 重要的環境變數

  • PATH
    • 這應該不用多說, 執行時期搜尋的 directory path
  • LD_LIBRARY_PATH
    • dynamically load library search path
  • RPATH
    • run-time search path
  • ORIGIN
    • executable name

2020年12月27日 星期日

2020年11月4日 星期三

[Programming] void(p);

  • 今天 diff 兩個實作的程式碼, 某 function 的差異是多了一行
    void(p); 
    其中  p 是 function 參數
  • 這執行上完全沒有效果, 主要作用是避開有些 compiler 會有變數 unused 的 warning, 而 compiler 把 warning 也直接以 error 報錯時, 會 build error, 那可以用這方法避開.

2018年9月19日 星期三

[Programming] Recursive


  • Programming problems 中重要的一個分類就是 recursive
    • e.g. 著名的 n 階算法
    • int factorial(int n) { if (1 == n) return 1; if (0 == n) return 1; return n * factorial(n-1); }
    • 但更重要的是應該要考慮 recursive 的限制
    • stack overflow
      • 解法: 
        • tail recursive
          • 連結內的解釋相當清楚, 主要是透過寫法不同, 讓 compiler 在 O2, O3的 optimization時, 不用 call function, 而是 jne (jump not equal)
          • int factorial_acc(int n, int acc = 1) 
            {    
                if (n == 1) 
                    return acc;
                else
                    return factorial_acc(n - 1, n * acc);
            }
            
        • iterative
          • int factorial_iterative(int n)
            {
                int acc = 1;
                if (n <= 1) return acc;
                while (n > 1)
                {
                    acc *= n;
                    n--;
                }
                return sum;
            }
    • 延伸閱讀

2013年7月4日 星期四

[Programming] 保持乾淨的標頭檔


  • 不該無謂的 include 一堆東西, 容易造成名稱衝突
  • 不要在 header file中使用 using namespace

2012年12月17日 星期一

[Programming] 以單一空格取代重複空格

  1 #include <stdio.h>

  2 // This code transform multple blanks to single blank
  3 #define NONBLANK 'a'
  4
  5 int main(){
  6         int c=0;
  7         int lastBlank=NONBLANK;
  8         while((c=getchar())!=EOF){
  9                 if(' '!=c){
 10                         putchar(c);
 11                 }else{
 12                         if(lastBlank!=' '){
 13                                 putchar(c);
 14                         }
 15                 }
 16                 lastBlank=c;
 17         }
 18         return 0;
 19 }

[Programming] C用 printf印八進位與十六進位

利用 printf("%o %x", numOct, numHex); 可分別印出八進位與十六進位的數字

2012年10月14日 星期日

[Development] Loop Unrolling (unwinding)

寫程式時,有個基本的 loop unrolling,白話說,就是將迴圈內容展開。請看以下例子 (例子是 wiki的):
  1. 
     int x;
     for (x = 0; x < 100; x++)
     {
         delete(x);
     }
    
  2. 
    
    
     int x; 
     for (x = 0; x < 100; x+=5)
     {
         delete(x);
         delete(x+1);
         delete(x+2);
         delete(x+3);
         delete(x+4);
     }
    
以上兩個方法目的相同,對於可讀性來說,第一個方法明顯好讀很多,第二個則是 unrolling後的結果。簡單說,loop unrolling的概念就是在每回 (iteration) 中,多做幾次運算,而減少 iteration次數。因為每次 iteration就是一次 branch,以上例來說,判斷次數就差了 5倍,對於效能上是有很大的差異的。不過一般建議,寫程式還是以第一個方法為主,等最後要 tune效能再考慮 loop unrolling,這邊只是為了 "看懂" 為什麼別人要這麼寫!

Ref: