/*** sqrt2.c --- sqrt(2.0) by tsaiwn@cs.nctu.edu.tw *** *** **************************/ // 只會印出根號 2 的答案 #include #include // math.h 內有關於 sqrt 需要何種參數以及會傳回哪種類型的值(double) // 阿就是說有 sqrt 這函數的 prototype (雛形) 啦 // 更精確地說, 就是有這句: double sqrt(double); // 用 < > 夾住住 math.h 表示該檔案在系統某目錄內 // 例如 Unix 系統是在 /usr/include 之下 // 又如 Turbo C++ 可能在 C:\TC\INCLUDE 之下 // 再如 Dev-C++ 可能在 C:\Dev-Cpp\include 之下 /// 如果寫 #include "math.h" 則會先找目前的目錄 /// .. 若目前目錄找不到, 還是會到系統的目錄去找 // ..所以, 只要目前目錄沒有 math.h, 寫 "math.h" 與 會相同! /// int main( ) { // 大多數 main program 都這樣開頭 printf("sqrt(2.0)=%f\n", sqrt(2.0)); return 0; // 告知作業系統(OS)表示我們這主程式正常結束 } /***Unix: gcc sqrt2.c -lm C:\testc> gcc sqrt2.c C:\testc> a.exe sqrt(2.0)=1.414214 C:\testc> gcc sqrt2.c -o haha.exe C:\testc> haha sqrt(2.0)=1.414214 請注意在許多類似 Unix 系統, 要有 -lm 表示要去找 數學程式庫! 不然可能會出現找不到 sqrt 這程式庫函數的訊息! 再強調一次, 裡面只有 sqrt 的宣告! 沒有實體! 通常 -lm 表示是要去找 /usr/lib 之下的 libm.a 因為所有的數學相關函數放在 /usr/lib/libm.a 所以 sqrt 這函數的實體其實是在 libm.a 裡面! 通常在 Unix 系統, 若寫 -labc 表示要去抓 libabc.a 啥? TC++ 找不到 libm.a 喔? 廢話! 它是在 LIB 目錄裡面 math?.lib 其中 "?" 有 C, S, M, L, H, 分別對應到五種 memory model 又啥啦? Dev-C++ 找不到 math?.lib ? 廢話, 因握 Dev-Cpp 雖然是在 Windows 下, 可是它仿照 Unix 啊 所以, 看看 Dev-Cpp\lib 裡面有沒有一個 libm.a 不過在 Windows 下的 通常會自動做 -lm 的選項! ////// 很多初學者常會說: 奇怪, 已經 #include 為何還要 -lm 就是說何以要寫 gcc sqrt2.c -lm 其實, #include 是給 Compiler 看的 但是 -lm 則是給鏈結程式(Linker; 如 ld 或 ld.exe)看的! 當我們下達 gcc sqrt.c -lm 這個命令之話, gcc 首先偷叫一個小程式"前處理"幫忙處理原始碼中 一些由 # 開頭的句子如 #incliude 或 #if 或 #define 等等, 然後生出一個臨時的原始檔案, 不含任何 # 開頭的句子 接著, 調用真正的 編譯器(compiler) 把跟臨時檔案編譯成 obj 檔案 obj 檔案在 Unix 通常是 .o 檔案, 是機器碼, 但仍不完整; 這時若編譯有錯就結束了! 若編譯沒錯, 則偷偷調用鏈結器(Linker) Link.exe 或 ld.exe 等 去抓用到的程式庫來跟 obj 檔案(可很多個)綁一起生出執行檔案! 然後, 我們就可以執行該執行檔案(Executable image). 例如 Dev-C++ 的 a.exe 或是 TC++ 生出與原檔名同名的 .exe 檔案! (Unix 系統下gcc 生出 a.out, 若要改生出的檔案名稱可用 -o 選項!! ============ *************************** ************************/