C語言學習——函數

1.自創函數
C語言提供了大量的庫函數(右側資料下載中有),比如stdio.h提供輸出函數,但是還是滿足不了我們開發中的一些邏輯,所以這個時候需要自己定義函數,自定義函數的一般形式:
注意:
1、[]包含的內容可以省略,數據類型說明省略,默認是int類型函數;參數省略表示該函數是無參函數,參數不省略表示該函數是有參函數;
2、函數名稱遵循標識符命名規範
3、自定義函數儘量放在main函數之前,如果要放在main函數後面的話,需要在main函數之前先聲明自定義函數,聲明格式爲:[數據類型說明] 函數名稱([參數]);
那現在我們就自定義一個sayHello()函數:


2.函數調用
自定義的函數不是放在程序中擺着看的,我們需要用到自定義的函數的時候,就得調用它,那麼在調用的時候就稱之爲函數調用
在C語言中,函數調用的一般形式爲:
 函數名([參數]); 
注意:
1、對無參函數調用的時候可以將[]包含的省略。
2、[]中可以是常數,變量或其它構造類型數據及表達式,個參數之間用逗號分隔。
比如上一小節中的例子可以修改爲:
運行結果爲: 慕課網的小夥伴們,大家好 



5.有參與無參
在函數中不需要函數參數的稱之爲無參函數,在函數中需要函數參數的稱之爲有參函數,有參和無參函數的一般形式如下:
有參函數和無參函數的唯一區別在於:函數()中多了一個參數列表。
下面看一個例子對比有參和無參函數:
對應輸出結果:
在該例子中,我們不難發現有參函數更爲靈活,輸出的圖形可以隨着n的改變而隨意變動,只要在main函數中傳遞一個參數就可以了;而在無參函數中輸出的相對就比較固定,當需要改動的時候還需要到自定義的方法內改變循環變量的值。


6.形參與實參
小明和小剛都說,要早起去鍛鍊,但是呢,小明每天都在睡懶覺,他只是形式上說說而已;而小剛則每天都在堅持,他是在實際行動。C語言函數中的參數也和情景中的類似有兩種。
函數的參數分爲形參實參兩種,形參是在定義函數名和函數體的時候使用的參數,目的是用來接收調用該函數時傳入的參數,就類似小明,說了的話而不實際行動;實參是在調用時傳遞該函數的參數,就如小剛能實際行動起來。
函數的形參和實參具有以下特點:
  • 形參只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只有在函數內部有效。函數調用結束返回主調函數後則不能再使用該形參變量。
  • 實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值等辦法使實參獲得確定值。
  • 在參數傳遞時,實參和形參在數量上,類型上,順序上應嚴格一致,否則會發生類型不匹配”的錯誤。
例如:以下函數multiDouble(int x)實現把x乘以2再返回給函數調用處。



7.函數的返回值
小明碰到一道數學選擇題問小剛,小剛算了一會給小明說計算結果是100,應選A。那麼小剛給小明的反饋就可以說是小剛的一個返回值。
那麼函數的返回值是指函數被調用之後,執行函數體中的程序段所取得的並返回給主調函數的值
函數的返回值要注意以下幾點:
1. 函數的值只能通過return語句返回主調函數。return語句的一般形式爲:
    return 表達式   或者爲:  return (表達式);
2. 函數值的類型和函數定義中函數的類型應保持一致。如果兩者不一致,則以函數返回類型爲準,自動進行類型轉換。
就如小剛說選A,那麼就返回一個字符型數據,用代碼表示就是:
小剛說值爲100,那麼就返回一個整型數據,用代碼表示就是:
3. 沒有返回值的函數,返回類型爲void。如果小剛算了一會沒有返回結果的話,那麼用代碼表示就是:
注意:void函數中可以有執行代碼塊,但是不能有返回值另void函數中如果有return語句,該語句只能起到結束函數運行的功能。其格式爲:return;


8.遞歸函數
從前有座山啊,山裏有座廟啊,廟裏有個老和尚和一個小和尚,他們在幹什麼呢?老和尚在給小和尚講故事,講的什麼呢?講的是從前有座山...看到這,大家都會問老師你不講課,你說這個老掉牙的故事幹嗎?
在這說這個故事是有意義的,大家在仔細讀讀這個故事,是不是老和尚在說一件事,當碰到一個條件的時候都會再重複的從頭說起呢?
那麼這就要給大家引入一個新的概念——遞歸,遞歸就是一個函數在它的函數體內調用它自身。執行遞歸函數將反覆調用其自身,每調用一次就進入新的一層。
例如:計算n的階乘可以使用以下代碼:
運行結果爲: 5的階乘=120 

我們對上一小節中求5的階乘這個例子進行一下剖析,看一看他的運算過程:
程序在計算5的階乘的時候,先執行遞推,當n=1或者n=0的時候返回1,再回推將計算並返回。由此可以看出遞歸函數必須有結束條件
遞歸函數特點:
  1. 每一級函數調用時都有自己的變量,但是函數代碼並不會得到複製,如計算5的階乘時每遞推一次變量都不同;
  2. 每次調用都會有一次返回,如計算5的階乘時每遞推一次都返回進行下一次;
  3. 遞歸函數中,位於遞歸調用前的語句和各級被調用函數具有相同的執行順序;
  4. 遞歸函數中,位於遞歸調用後的語句的執行順序和各個被調用函數的順序相反;
  5. 遞歸函數中必須有終止語句。
一句話總結遞歸:自我調用且有完成狀態。


9.局部與全局
C語言中的變量,按作用域範圍可分爲兩種,即局部變量和全局變量。
局部變量也稱爲內部變量。局部變量是在函數內作定義說明的。其作用域僅限於函數內, 離開該函數後再使用這種變量是非法的。在複合語句中也可定義變量,其作用域只在複合語句範圍內。
全局變量也稱爲外部變量,它是在函數外部定義的變量。它不屬於哪一個函數,它屬於一個源程序文件。其作用域是整個源程序



10.變量存儲類別
C語言根據變量的生存週期來劃分,可以分爲靜態存儲方式動態存儲方式
靜態存儲方式:是指在程序運行期間分配固定的存儲空間的方式。靜態存儲區中存放了在整個程序執行過程中都存在的變量,如全局變量。
動態存儲方式:是指在程序運行期間根據需要進行動態的分配存儲空間的方式。動態存儲區中存放的變量是根據程序運行的需要而建立和釋放的,通常包括:函數形式參數;自動變量;函數調用時的現場保護和返回地址等
C語言中存儲類別又分爲四類:自動(auto)、靜態(static)、寄存器的(register)和外部的(extern)。
1、用關鍵字auto定義的變量爲自動變量,auto可以省略,auto不寫則隱含定爲“自動存儲類別”,屬於動態存儲方式。如:
2、用static修飾的爲靜態變量,如果定義在函數內部的,稱之爲靜態局部變量;如果定義在函數外部,稱之爲靜態外部變量。如下爲靜態局部變量:
注意:靜態局部變量屬於靜態存儲類別,在靜態存儲區內分配存儲單元,在程序整個運行期間都不釋放;靜態局部變量在編譯時賦初值,即只賦初值一次;如果在定義局部變量時不賦初值的話,則對靜態局部變量來說,編譯時自動賦初值0(對數值型變量)或空字符(對字符變量)
3、爲了提高效率,C語言允許將局部變量得值放在CPU中的寄存器中,這種變量叫“寄存器變量”,用關鍵字register作聲明。例如:
注意:只有局部自動變量和形式參數可以作爲寄存器變量;一個計算機系統中的寄存器數目有限,不能定義任意多個寄存器變量局部靜態變量不能定義爲寄存器變量。
4、用extern聲明的的變量是外部變量,外部變量的意義是某函數可以調用在該函數之後定義的變量。如:



11.內部函數與外部函數
人本身是有自己的特定方法的,比如當你說話的時候,不希望是別人讓你怎麼說你就怎麼說吧,那麼這種不能被外人調用的方法稱爲人的內部方法。人本身還有一些可以調配的方法,比如當你家人跟你說,家裏沒有鹽了,你去買袋鹽,去買鹽就是他人調用你的方法,那麼能被外人調用的方法稱謂外部方法。
在C語言中不能被其他源文件調用的函數稱謂內部函數 ,內部函數由static關鍵字來定義,因此又被稱謂靜態函數,形式爲:
 static [數據類型] 函數名([參數]) 
這裏的static是對函數的作用範圍的一個限定,限定該函數只能在其所處的源文件中使用,因此在不同文件中出現相同的函數名稱的內部函數是沒有問題的。
在C語言中能被其他源文件調用的函數稱謂外部函數 ,外部函數由extern關鍵字來定義,形式爲:
 extern [數據類型] 函數名([參數]) 
C語言規定,在沒有指定函數的作用範圍時,系統會默認認爲是外部函數,因此當需要定義外部函數時extern也可以省略。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章