2018年3月23日 星期五

用輕鬆的方式來學習編譯程式指令 (gcc/g++), 不一定要靠 IDE 來編譯程式。

最開始學習 C 語言時, 是用 turbo c 2.0, 記得只要按下 F9, 就會產生一個 dos 執行檔案。而裡頭的除錯環境也很好用, 對於剛學習 C 語言的初學者幫助很大, 只要專心在 c 語言的學習上就可以了, 不需要花太多時間和編譯工具奮鬥。

然而老師卻要我們用 unix 上的 cc 編譯器, 一下子難倒許多人, 在上大學之前, 不可能有人會有 unix c 語言開發經驗的。

turbo c 2.0 的開發者真是厲害, Anders Hejlsberg 開發了 turbo pascal, turbo c 不知道其是不是也有參與?

我現在的程度可以在 dos 上獨立開發出 turbo c 2.0 的開發工具嗎? 方便的 ide 除錯環境目前還難倒我。



如何看待「年轻人不要用 Visual Studio」的言论?

這篇在討論應該要用這種 ide 嗎? 我有自己的想法, 但我寫這篇文章不是要參加大辯論, 我想寫些東西, 讓願意不使用 ide 的初學者, 可以不要那麼痛苦。

以下介紹 linux c 開發環境, 使用 windows/vs 的朋友就抱歉了, vs 系列我連「略懂」都沒有。

寫程式最需要的是編譯指令, 以 gcc 來說, 就是使用 gcc 這個指令。
最簡單的用法就是:
gcc h.c
這時候會編出一個 a.out 的執行檔, 執行它就可以了。
如果你有 2 個 c 檔案:
gcc h1.c h2.c
這樣就可以, 應該沒難到記不住。

再來是 -o option,
gcc h.c -o h
這會輸出一個 h 的可執行檔。

再來是和 header files (.h) 有關:
如果你 include abc/1.h
很直覺的一個想法, 你應該告訴 gcc 去哪裡找是吧? 否則 gcc 怎麼知道要去那裡找 abc 目錄裡頭的 1.h。
這就有了 -I option,

如果 abc 是在 /abc
gcc h.c -I /abc
這樣就會告訴 gcc 去 /abc 找那個 1.h。

如果 abc 是在 /xyz/abc
gcc h.c -I /xyz/abc
這樣就會告訴 gcc 去 /xyz/abc 找那個 1.h。

你說那 stdlib.h 怎麼不用下 -I option, 那是因為 stdlib.h 是標準程式庫的一部份, gcc 知道 stdlib.h 在哪裡, 既然 gcc 知道在哪裡, 當然就不用我們加入 -I option。

再來是連接一個程式庫 libabcdef.a, 假設這個放在 /def/ 裡頭, 那麼
gcc h.c /def/libabcdef.a
就可以了, 很直覺, 不用解釋。

同理, c 程式如果呼叫了 printf, 就需要連結 libc.a, 為什麼我不用加入 /aaa/libc.a, 因為這是標準程式庫的一部份, gcc 知道 libc.a 在哪裡, 既然 gcc 知道在哪裡, 當然就不用我們寫。

以下的 option 可以不需要, 但因為很常見, 介紹一下, 覺得太複雜可以先不記。
-c option:
gcc -c h.c
會產生 h.o object file, 而不是可執行檔案。

再一次
gcc h.o
就會產生 a.out 可執行檔案。

gcc h.o -o h
就會產生 h 可執行檔案。

-l option, -L option:
這 2 個通常一起用,
gcc h.c /def/libabcdef.a
/def/libabcdef.a 可以換成
-L/def/ -labcdef
-L 告訴 gcc libabcdef.a 放在哪裡。
-l 可以不用寫出完整的 libabcdef.a 名稱。
麻煩多了吧! 所以有時候我也不用這 2 個 option。

只要先這樣, 就不需要靠 ide 完成編譯, 自己打指令就可以了。

這方式顯然比使用 ide 的 F9 痛苦了不只一點, 那有什麼好處嗎?
好處是你知道編譯的細節, 當你換了一個編譯器指令時, 知道要去找類似的 option 來使用。這個理由不太吸引人, 我知道。

debug 是一個問題, 不靠 IDE, 要學習 gdb 來 debug, 這就真的不容易。

而沒有 IDE 你很難作到:
function complete
看變數初始值
ifdef 是哪一段
macro 的值, 或是展開後的結果
...

一但 ide 裝好就會有的神奇功能, 使用原始開發工具的我都無法直接受惠。

我自己依然在使用 makefile + vim 的環境, 很久之後我才知道現在的 ide 和 turbo c 2.0 的 ide 已經大不相同, 提供了很多的功能, 但不用 ide 對我沒造成太大的困擾, 我一樣可以用 vim 來查看 linux source code, 寫 qt 的時候開啟 qt doc 查閱相關函式, 複製/貼上, 原始人的開發方式, 這也不算是什麼厲害的技巧, 就每個人習慣的工具不同罷了。

而事實上, 不用 ide 還得學習 makefile 的編寫, 這也是一個小門檻。

最基本 makefile 用法:
h.o: h.c
        gcc -c h.c
應該很直覺, h.o 要由 h.c 來產生, 用 gcc -c h.c 指令來產生 h.o。

h: h.o
        gcc -o h h.o
應該也很直覺, h 要由 h.o 來產生, 用 gcc -o h h.o 指令來產生 h。

makefile 我通常用 $@, $<, $^, 只要記住這 3 個, 負擔應該不大。如果覺得太複雜, 也可以不理這個。

h: h.o
        gcc -o $@ h.o

$@ 就是指 h。

h: h.o
        gcc -o h $<

$< 就是指 h.o。

h: h.o k.o
        gcc -o h $<

$< 還是指 h.o, 如果要把 k.o 也包含進來, 要用 $^。

h: h.o k.o
        gcc -o h $^

$^ 就是指 h.o k.o。

好了, 作為一份輕鬆的簡介, 這樣已經太複雜了。

這只是很簡單的介紹, 實際上要在學習多一點, 才會更好用, 但如果要嘗試看看不使用 ide 環境, 這樣就夠了。

2 則留言:

  1. 記憶的畫面,懷念的工具。二十年前高中就是對著他學C語言,想印九九乘法表卻連for loop都搞不定

    回覆刪除
    回覆
    1. 看來很多人都有共同的回憶。

      刪除

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。