函數
-
基本觀念及術語
- 在 C 語言中, 如果函數沒有傳回值, 必須宣告成 void ...(...); 如果不寫, 表示傳回值是整數: int ...(...).
- 如果函數不需要參數, 則應宣告其參數為 void.
void *表示指到任意型別的指標.- 函數的 declaration (宣告): 告訴編譯器「有人會提供某某函數給我們用」的這個動作. 至少要有函數的名稱, 往往也包含了傳回值型別及參數的個數型別
- 函數的 signature (簽名?): 包含函數的名稱, 及參數的個數、型別
- 函數的 prototype (原型): 函數的 signature 外加傳回值型別
- definition 定義: 函數真正的內容 (每一步該怎麼做 ...)
- invocation 呼叫
- formal argument/parameter 形式參數: 在副程式的 definition 的參數列當中出現的東西
- actual argument/parameter 實際參數: 在呼叫副程式 (invocation) 的地方出現
-
Call-by-value (以值呼叫)
- 例: 寫一個副程式, 交換兩個 double 變數的內容:
void swap(double x, double y) { ... }再從主程式中呼叫 swap(a, b) 為何無法達到交換 a b 的效果? 因為 C 的函數呼叫方式為 call-by-value, 形式參數其實真的是另外一個新的變數, 一個新的盒子, 只不過它的內容拷貝自實際參數而已. - 如果需要副程式修改傳進去的參數, 必須傳入位址: 以
void swap(double * x, double * y)宣告; 以 swap(&a, &b) 呼叫. 雖然仍舊是 call-by-value, 但這回拷貝的是位址, 所以副程式有辦法透過它修改實際參數. - 陣列參數: 在參數列中, 陣列完全同於指標, 而且一維陣列的大小可以不必宣告; 多維陣列的第一個 dim 也不必. ... arg[][10] ... 可; ... arg[10][] ... 錯!
- 例: 寫一個副程式, 交換兩個 double 變數的內容:
-
參數中的 const
- 在變數宣告中, const 表示你對 compiler 的承諾; 在參數宣告中 const 表示副程式對呼叫程式的承諾, 而不是副程式對呼叫程式的要求.
- 例:
int strcmp(char const * p, char const * q);與char * strcpy(char * dst, char const * src); - 結論 (配合 call-by-calue): 這就是為什麼參數列上的 const 沒有太大的用處: 好像副程式在對呼叫者說: 我像你借一本書來拷貝, 把原版還給你; 我向你保証不會去塗改我的抄本.
- Q: 若有
char name[20];則strcpy(name, "Sam");是正確的; 但是strcpy("Sam", name);是錯的, 錯在前面還是後面? - Q: 既然把程式中 (包含 include 檔) 所有的 const 完全拿掉, 對程式的執行效果完全沒有影響, 為何自找麻煩?
- 結論: 副程式的參數列中, 把指標宣告成常數沒有太大的意義; 通常都是把指標指到的東西宣告成常數.
- Recursion (遞迴) 及 activation record
- 本頁最新版網址: http://people.ofset.org/~ckhung//b/c/function.php; 您所看到的版本: July 19 2003 14:45:21.
- 作者: 朝陽科技大學 資訊管理系 洪朝貴
- 寶貝你我的地球, 請 減少列印, 多用背面, 丟棄時做垃圾分類。
- 本文件以 Creative Commons Attribution-ShareAlike License 或以 Free Document License 方式公開授權大眾自由複製/修改/散佈。
![[rss feed 圖案]](/~ckhung//i/rss.png)
![[帶頭升級 Office 2007? 別當害群之馬]](/~ckhung//i/n7/no-office2007.png)
![[(力求維持) 符合 xhtml 1.0]](/~ckhung//i/vxhtml10.png)
