【C語言】MOOC翁愷老師-入門-函式-5
函式
-
問題:寫了函式有什麼好處?有沒有什麼親身感受能體會到函式的好、函式的美?
答:1.當遇到重複的程式碼的時候,就可以通過使用函式來簡化程式碼,而且當其他源程式要用到這個程式碼塊的功能的時候,直接複製函式過去就可以了。 2.親身體會,輸出題目所需要的輸入的時候,可以把判斷是不是素數的程式碼提出來定義成函式,簡化效果很明顯,也更易於理解主函數了。 3.當要維護程式時,工作量能大大減小
-
函式定義:函式是一塊程式碼,接受0個或多個引數,做一件事情,並返回0個或一個值。
-
函式返回值:最好也遵循著
單一出口
原則進行編碼! -
函式的先後關係:C的編譯器是自上而下順序分析程式碼。因此被呼叫的函式要寫在main函式的上方,讓編譯器先知道被呼叫的函式什麼情況。當在main函式中執行到相關呼叫函式的時候,編譯器就知道(我剛才遇到過,然後回去上面呼叫)。
-
函式原型:
-
背景:在C99之前,如果不按現有規則去編寫函式順序,比如說main函式在最上面,而main函式裡面要呼叫的函式在下面。那麼main函式會在執行到相關呼叫函式的時候自己猜想著定義一個函式。可是這樣的話執行到下面遇到真正由程式設計師定義的函式就會引發衝突。所以為了解決這一情況,在C99標準之後,我們嚴格遵守函式的先後關係原則便可以避免這樣的衝突。或者,有些人出於自己的編碼習慣,一定要把main函式放在最上面,自己定義的函式放在下面,那麼可以使用到函式原型來避免這樣的衝突發生。
-
定義:函式頭以分號為結尾,放在main函式的最上面。
double max(double a, double b); // 函式原型宣告 int main() { max(10.0, 20.0); // 呼叫函式 .... } double max(double a, double b) // 函式定義 { .... }
-
-
函式中形參和實參型別不匹配問題:
- 呼叫函式時給的值與引數的型別不匹配是C語言傳統上最大的漏洞
- 編譯器總是悄悄地把你的型別轉換好,但是這很可能不是你所期望的
- 後續的語言中,C++/Java在這方面很嚴格
-
函式傳值:
- 每個函式都有自己的變數空間,引數也位於這個獨立的空間中,和其它函式沒有關係。每個引數都有自己的生命週期。
- 函式的呼叫在傳遞的時候僅僅只是
傳值
,而不是把變數傳進去! - 傳統的形參和實參概念容易讓人誤會,現在我們認為,函式呼叫是引數和值的關係問題
-
本地變數:
-
函式的每次執行,就產生了一個獨立的變數空間,在這個空間中的變數,是函式的這次執行所獨有的,稱作本地變數。
-
定義在函式內部的變數就是本地變數,引數也是本地變數。
-
對於本地變數,生存期和作用域都是在大括號內的塊
補充:
- 生存期:什麼時候這個變數開始出現,到什麼時候消亡
- 作用域:在什麼範圍內這個變數可以起到作用
-
塊外面定義的變數在裡面依然有效
int main() { int a = 6; if(1){ printf("%d", a); // 輸出6 } }
-
塊裡面定義了和外面同名的變數則掩蓋了外面的,但同樣出了塊外就消亡了
int main() { int a = 6; if(1){ a = 0; // 掩蓋了外面-塊內同名遵循就近原則 printf("%d", a); // 輸出0 } }
-
本地變數不會被預設初始化,C語言的型別都這樣,所以要特別注意給初始化!引數除外,因為呼叫的時候已經傳值初始化了。
-
-
其它細節:
-
如果函式原型宣告的時候,沒有引數那就寫
void
void max(void); // 引數裡面沒有引數,記得寫上void,至少C語言要這樣
-
呼叫函式時的逗號和逗號運算子怎麼區分?
f(a,b) // 逗號,呼叫函式的逗號沒有作用,只是區分兩個數字 f((a,b), c) // 逗號運算子( , )是C語言運算子中優先順序最低的一種運算子。 a = 12+(s+2,d+4); // 逗號運算子,括號內算完會取後一個的數,即d+4的值
-
C語言不允許函式的巢狀定義,而Python中的高階函式可以
-