【持續(xù)更新】C語言 第五天學習筆記(函數(shù)完整版)

一、【理解】復習昨天內(nèi)容

二、【掌握】函數(shù)的介紹和簡單使用

思考:
如果你要做個表白的軟件,其中想打印9次愛心,代表你對妹紙濃濃的愛,怎么做呢?

打印表白

親!你需要一種更簡單高效的編碼方式——函數(shù)??!
思考:

我們已經(jīng)學過的函數(shù)有哪些?

函數(shù)的作用:

函數(shù)就相當于是一個打包盒,將一段代碼打包在這個盒子里,當需要用這段代碼時,只要把這個盒子拿過來就行了。

稍微專業(yè)點的說法:

將一段需要被重用的代碼封裝在函數(shù)中,什么時候想要執(zhí)行這段代碼,只需要調(diào)用這個函數(shù)就行了。

函數(shù)的定義:


  返回值類型    函數(shù)名(參數(shù)列表){

               函數(shù)體

}

例:

int  main(){

 

}

 

void   test(){

 

}

 

 
    ```
####函數(shù)定義的注意點:

#####1、函數(shù)名可以任意寫,但最好符合標識符命名規(guī)范:

   1)函數(shù)的名稱一定要有意義,盡量做到別人一看你函數(shù)名就知道你的函數(shù)內(nèi)部做什么事情

 

2)函數(shù)的名稱用駝峰命名法:如果有多個單詞,第一個單詞首字母小寫,后面的其他單詞字母首字母大寫

 

 

#####2、什么時候該使用函數(shù)?

     
如果你發(fā)現(xiàn)有1段代碼是在完成1個獨立的功能或者需要重用,那么這個時候我們也可以將這段代碼封裝在函數(shù)之中.

 

#####3、函數(shù)的好處:

1、減少代碼冗余,增強閱讀性

2、方便維護和修改

 

 

 

#####練習:使用函數(shù)來打印九九乘法表




###三、【掌握】Xcode調(diào)試的使用  

####一、斷點調(diào)試


![斷點調(diào)試](http://upload-images.jianshu.io/upload_images/3899701-4cb79f263456856b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![斷點示意圖](http://upload-images.jianshu.io/upload_images/3899701-de4cb1b007189208.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

下斷點有什么用?

 

當你用Xcode編譯并啟動程序時,程序執(zhí)行到你下斷點的地方會卡住,不再往下執(zhí)行,如:



![如圖](http://upload-images.jianshu.io/upload_images/3899701-56eb3e4a85fb46da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我們發(fā)現(xiàn)第43行代碼處有一行綠色的yin陰影,這代CPU執(zhí)行到這一行時停止了(此行還沒執(zhí)行),如果想繼續(xù)往下執(zhí)行,此時有三種方法:

####    1、往下繼續(xù)執(zhí)行全部
繼續(xù)往下執(zhí)行,直到遇到下一個斷點、阻塞式函數(shù)、或者程序結(jié)束

![如圖所示](http://upload-images.jianshu.io/upload_images/3899701-2a64d4050acd667b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    調(diào)用完成直接執(zhí)行后面的結(jié)果,打印圖形和文字


![打印圖形](http://upload-images.jianshu.io/upload_images/3899701-adf8002753cdd70d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

####單行跳過執(zhí)行(step over)
一行一行地執(zhí)行,按一次執(zhí)行一次。但是使用這種模式會使當前遇到的函數(shù)一下子就執(zhí)行完

![單行跳過執(zhí)行](http://upload-images.jianshu.io/upload_images/3899701-be7e46bbdfb0bf58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![如圖所示](http://upload-images.jianshu.io/upload_images/3899701-77aa28dccacb8fe3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

按完后會執(zhí)行完printf,停在drawHeart


![如圖](http://upload-images.jianshu.io/upload_images/3899701-3a01c0356044e94b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![圖2](http://upload-images.jianshu.io/upload_images/3899701-dee59eeeb7d4f73e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

####3、單行進入執(zhí)行(step into)

一行一行地執(zhí)行,按一次執(zhí)行一次。但是使用這種模式會使進入到當前遇到的函數(shù),并在函數(shù)里一步一步運行

![單行進入](http://upload-images.jianshu.io/upload_images/3899701-3fb2c1d2f7db69e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
此時CPU卡在drawHeart,當我們再按step into時,發(fā)生了和step over不同的事情
![如圖所示](http://upload-images.jianshu.io/upload_images/3899701-94d426d6602de4d9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![圖2](http://upload-images.jianshu.io/upload_images/3899701-dcddbf064f414144.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![圖3](http://upload-images.jianshu.io/upload_images/3899701-8437fe0c2fd89c80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



![圖4](http://upload-images.jianshu.io/upload_images/3899701-c3754491ffd0e4e2.png)


![圖5](http://upload-images.jianshu.io/upload_images/3899701-d87fa98ab3e081e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

總結(jié):
step over 和step into最大的不同在于:

step over一下子就執(zhí)行完函數(shù),不進入函數(shù)的內(nèi)部

step  into 會進入到函數(shù)的內(nèi)部,在內(nèi)部一行一行地執(zhí)行





###二、刪除斷點:
1)直接按住斷點左鍵不動往右邊一拖再松開即可刪除斷點

2)右鍵斷點陰影,在彈出的選項中左鍵單擊Delete Breakpoint即可刪除斷點
![如圖所示](http://upload-images.jianshu.io/upload_images/3899701-67132365cfae7784.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


四、【掌握】全局變量和局部變量
-> 全局變量

直接定義在.c源文件中,函數(shù)的外部.就叫做全局變量

 

-> 局部變量

 定義在函數(shù)內(nèi)部的變量,就叫做局部變量

 

####不同點:

1)全局變量可以在任何函數(shù)中使用,而局部變量只能在被申明這個變量的函數(shù)里使用。

2)全局變量直到程序結(jié)束時才會銷毀,而局部變量在函數(shù)結(jié)束后就會被銷毀

### 五、【掌握】函數(shù)的參數(shù)
思考:
        如果想做一個函數(shù),用來判斷一個數(shù)是不是偶數(shù),怎么辦?

 

 

我們發(fā)現(xiàn),很多時候函數(shù)要想完成某種功能,也必須要接收外界傳入的值才能進行處理,那么這時怎么辦呢?

 

我們可以使用全局變量解決這個問題,但是,全局變量有個很不好的地方在于始終占據(jù)著我們的內(nèi)存空間,除非程序退出才會釋放占用的空間,那么這時怎么辦呢?

 

 好在C語言為我們提供了一套十分好的解決方法:函數(shù)的參數(shù)!

 

####1、什么是函數(shù)的參數(shù)?

在函數(shù)名右邊的小括號里申明的變量,就叫參數(shù)。注意:沒有分號!

 

 

####2、函數(shù)的參數(shù)的本質(zhì):

相當于函數(shù)內(nèi)部的局部變量,所以不能在函數(shù)內(nèi)部再定義一個同名的變量,并且在函數(shù)內(nèi)部可以直接使用參數(shù)的值

![函數(shù)本質(zhì)示意圖](http://upload-images.jianshu.io/upload_images/3899701-1bd2e09561ad5300.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

調(diào)用函數(shù)時需要給參數(shù)進行賦值,否則會報錯!如:


![函數(shù)本質(zhì)示意圖2](http://upload-images.jianshu.io/upload_images/3899701-05b3c841d88443ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


思考:什么時候該為函數(shù)寫參數(shù)呢?
建議:如果以后不知道要不要給函數(shù)寫參數(shù),就先寫函數(shù)的功能,等發(fā)現(xiàn)需要接收外部傳入的值時,再寫函數(shù)!

####3、帶多個參數(shù)的函數(shù)

思考:如果我們需要做一個實現(xiàn)做加法運算功能的函數(shù),怎么做呢?

 

我們再一次發(fā)現(xiàn)很多時候一個參數(shù)是完全不夠用的,所以我們需要多個參數(shù)。多個參數(shù)怎么定義

呢?

 

 

定義方法:

返回值 函數(shù)名(參數(shù)類型 參數(shù)名1,參數(shù)類型 參數(shù)名2…………參數(shù)類型 參數(shù)名n){

函數(shù)體;

}

 

使用注意:

1)實參的個數(shù)必須與形參的保持一致

2)實參的順序也必須與形參的保持一致

3)實參的類型必須與形參保持一致,否則會做類型轉(zhuǎn)換



![如圖所示](http://upload-images.jianshu.io/upload_images/3899701-7cbff79eaff2096e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###4、形參和實參

形參:全稱形式參數(shù)。在聲明函數(shù)右邊的小括號里寫的參數(shù)就叫形參。
實參:全稱實際參數(shù)。在調(diào)用函數(shù)時,給函數(shù)的形參賦值的值就叫實參。


![形參和實參](http://upload-images.jianshu.io/upload_images/3899701-5bd6477b091d20da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用注意:因為實參的本質(zhì)就是在調(diào)用函數(shù)時為形參賦值,所以當我們調(diào)用一個帶參數(shù)的函數(shù)時,會要求實參的類型與形參的類型一致。如果類型不一致,會將實參的數(shù)據(jù)類型轉(zhuǎn)換為形參的類型然后再賦值

 

例:  int  
a   = 10.3     會先將10.3轉(zhuǎn)成int類型(即10)再賦值給變量a,所以變量a的值為10

 

在函數(shù)的實參中,也是類似這樣的過程來給形參賦值


###六、【理解】課堂練習
1、用函數(shù)來實現(xiàn)判斷一個數(shù)是不是水仙花數(shù)

 

 

 

2、寫一個函數(shù),求指定某個數(shù)到某個數(shù)之間所有的整數(shù)的累加和

如:3到8,算出3+4+5+6+7+8 = ?

 

 

3、用函數(shù)來實現(xiàn)判斷一個年份是不是閏年(考點)

###七、【掌握】return關鍵字

回憶:break   、 continue關鍵字的作用是什么?

 

return關鍵字也有結(jié)束的作用,但效果比break、continue恐怖的多,是直接結(jié)束整個函數(shù)。return關鍵字后面的語句不會被執(zhí)行

 

 

 

 

總結(jié):break     continue     return

 

break:用在循環(huán)或者switch case語句中,用來結(jié)束其所在的循環(huán)或者switch
case語句

 

continue:用在循環(huán)中,用來結(jié)束其本次循環(huán),繼續(xù)下次循環(huán)

 

return:用在函數(shù)中,用來結(jié)束整個函數(shù)


練習:

  用函數(shù)實現(xiàn)判斷一個數(shù)是不是偶數(shù),但函數(shù)內(nèi)部只能用if語句實現(xiàn),不能用if else 或者if else if



###八、【掌握】函數(shù)的返回值

思考:寫一個函數(shù)實現(xiàn)計算出語文成績和數(shù)學成績的總分。然后蒼老師叫小明和小王還有小軍分別去計算出他們的總分,然后蒼老師要統(tǒng)計他們?nèi)齻€人的總分,這時怎么做呢?

####什么時候需要函數(shù)的返回值?

         當函數(shù)執(zhí)行完畢能得出一個結(jié)果,但是函數(shù)內(nèi)部不知道怎么正確地處理這個結(jié)果,恰好這個結(jié)果又是調(diào)用者想用來得到的,就需要有函數(shù)的返回值!

 

####怎樣讓函數(shù)有返回值?

1)確定要返回的值的類型

2)修改函數(shù)的返回值類型為你想要返回值的類型(如將之前的void改為int)

3)在函數(shù)內(nèi)使用  return 
表達式   
返回

 

 

####調(diào)用者如何拿到函數(shù)返回的數(shù)據(jù)?

申明一個與函數(shù)返回值相同類型的變量,并將返回值賦值給這個變量就可以了

 

 

 

####函數(shù)的其他注意點:

1)如果函數(shù)有返回值,調(diào)用者可以接收,也可以不接收。但如接收,需要準備對應的類型來接收

2)void 代表沒有返回值,如果一個函數(shù)返回值是void的,調(diào)用者不需要接收。如果強行接收會報錯

3)返回的數(shù)據(jù)類型要與函數(shù)定義的返回值類型一致,如果不一致,會先將所返回的值轉(zhuǎn)換成定義的返回值類型再返回

4)如果函數(shù)定義了返回值,并且函數(shù)體里面有多個分支,那么每個分支都必須要有返回值,否則會報錯

###九、【掌握】函數(shù)的申明


####1、為什么需要對函數(shù)進行申明
 

   編譯器很笨,只會從上到下依次將代碼翻譯成計算機可以識別的二進制指令,所以如果當函數(shù)的申明寫在它被調(diào)用之后,編譯器會報錯!

 

   為了解決這個問題,所以如果函數(shù)的實現(xiàn)寫在調(diào)用語句后面的話則需要先對函數(shù)進行申明。代表告訴編譯器:有這個函數(shù),你只管編譯就好!


####2、 完整的寫函數(shù)的兩個步驟

 

     1). 函數(shù)的聲明

         語法: 只寫函數(shù)頭 直接加1個分號結(jié)束.

         作用: 告訴編譯器,這個函數(shù)是有的 只不過在后面.

 

     2). 函數(shù)的實現(xiàn)(定義)

         和我們之前講的函數(shù)的定義是一樣的.

         表示真正的來實現(xiàn)這個函數(shù).

 

####3、函數(shù)申明的幾點注意

 

     1). 如果被調(diào)用的函數(shù)在主調(diào)用函數(shù)之前,那么被調(diào)用函數(shù)可以不寫聲明直接寫實現(xiàn)

 

         一般情況下,main函數(shù)是放在最前面的. 所以我們自定義的函數(shù)要在最前面寫聲明,在后面寫實現(xiàn).


![注意](http://upload-images.jianshu.io/upload_images/3899701-61c0772b73a802e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


     2). 函數(shù)的聲明可以在任意的地方但是至少應該在函數(shù)調(diào)用之前聲明

                    即使是這樣. 但是一般情況下 函數(shù)的聲明我們都放在#include指令之后.

 

     3). 函數(shù)的聲明必須要與函數(shù)實現(xiàn)的函數(shù)頭一樣,否則會出問題.

                    所以,我們建議大家 先寫函數(shù)的實現(xiàn) 然后將函數(shù)實現(xiàn)的頭拷貝聲明.



![如圖](http://upload-images.jianshu.io/upload_images/3899701-b1220432c540f710.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



     4). 聲明函數(shù)的時候形參可以只寫類型不寫名稱



![如圖4](http://upload-images.jianshu.io/upload_images/3899701-8a6b7b91fe8633e4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


     5). 如果函數(shù)的返回值類型是int類型的那么可以省略函數(shù)聲明

      但是為了更好的代碼可移植性 以及可閱讀性十分的建議還是要把聲明寫上.


![如圖](http://upload-images.jianshu.io/upload_images/3899701-df9ca0ab6918ed19.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###十、【掌握】函數(shù)的其他注意
1、值傳遞:是指實參給形參賦值,傳遞的永遠是值,而非實參的內(nèi)存空間(以后學指針后可以把空間地址傳過去),所以在函數(shù)里給形參重新賦值不會影響到實參。

 

 

2、C語言中函數(shù)沒有重載。即:C語言中的函數(shù)不允許出現(xiàn)函數(shù)同名的情況,否則編譯器會報錯

 

 

3、函數(shù)內(nèi)部不能定義一個新的函數(shù),但是可以在函數(shù)內(nèi)部再調(diào)用函數(shù)


###十一【理解】函數(shù)練習

1. 寫1個函數(shù) 返回兩個整型數(shù)中的最大值.

 

2. 寫1個函數(shù),傳入1個人的年齡,判斷年齡是否成年

 

 

附加題:

 

1. 寫1個函數(shù),返回1個浮點數(shù)的四舍五入的整數(shù)

 

2.寫1個函數(shù),用來判斷3個整數(shù)的最大值,這個函數(shù)只能傳兩個參數(shù)

 即申明成右邊的格式:int  getMax(int  num1,int num2);



###十二【理解】#include指令


####1、#include是一個預處理指令  
#####1) 什么是與處理指令?

   就是在源代碼編譯之前進行的一系列操作。其中預處理指令包含:文件包含、宏定義、條件編譯指令  等等

 

  預處理指令的特點:

A、所有的預處理指令都是以#開頭

B、沒有分號

C、在編譯之前執(zhí)行

 

   

##### 2)#include指令是一條文件包含預處理指令

 

作用:將指定文件的內(nèi)容拷貝到寫這條#include指令的地方

語法:

include "文件名稱"

include <文件名稱>


例:

![  預編譯](http://upload-images.jianshu.io/upload_images/3899701-86c8eb3bcf224c83.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用注意:

 1)被包含的文件里面的內(nèi)容必須符合C語言語法規(guī)范,否則即使包含進來,編譯的時候也會報錯!


![圖1](http://upload-images.jianshu.io/upload_images/3899701-48e605a04d888e15.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
        2)如果要包含的文件就在當前寫#include指令文件的同一目錄,則包含路徑可以省略,只寫文件名。

例:
![圖2](http://upload-images.jianshu.io/upload_images/3899701-2ec54210acc01cc6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


###2、#include指令的搜索順序

分兩種情況:



   
1)#include 
"文件名稱" 

a、如果指定了全路徑,則直接去對應的路徑查找文件



b、如果沒有指定全路徑,則先去當前代碼文件所在文件夾里查找,如果有就包含,沒有的話就會再去Xcode的編譯器目錄下去查找是否有這個文件,如果有則直接包含進來,如果這時還沒有,則報錯



Xcode編譯器目錄

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include



   
2)#include  <文件名稱>

直接去Xcode編譯器目錄去查找這個文件,如果有就包含進來,如果沒有就報錯





###3、 #include<stdio.h>的分析

我們學過函數(shù)后知道,如果要調(diào)用某個函數(shù),必須在調(diào)用之前對這個函數(shù)進行申明,而之前我們所用的printf("")   scanf("")都是函數(shù),只不過這些是系統(tǒng)給我們寫好的函數(shù),如果沒有進行申明直接調(diào)用會報錯,

所以我們需要對其進行申明,而這些函數(shù)申明的內(nèi)容,都包含在蘋果為我們提供的Xcode編譯器里的各種文件里了,我們只要用#include指令包含進來就行了!





###4、#include規(guī)范



如果是我們自己寫的文件,放在代碼文件里,并且用""包含

如果是編譯器提供的頭文件,則用<>包含








###十三【掌握】多文件開發(fā)

思考:實現(xiàn)微信搖一搖有哪些功能步驟?
我們實際開發(fā)中的項目,基本都是團隊協(xié)作開發(fā),每人負責一個模塊(功能),這樣比較利于項目的快速開發(fā)。


案例:

模塊:數(shù)學功能

將1個功能模塊的函數(shù)應該單獨的寫在1個文件之中. 每1個模塊1個文件.



新建1個.c文件.在這個.c文件之中寫上相關的函數(shù).  在要調(diào)用的地方, 先聲明函數(shù)以后才能調(diào)用.





    這么做可能存在的問題:

1). 如果寫模塊的人 新增了1個函數(shù) 那么調(diào)用者就還要去聲明這個函數(shù).

2). 如果寫模塊的人 改了函數(shù)不通知調(diào)用者的話 也會出問題.



    正確的做法:

1). 寫模塊的人寫兩個文件 .c文件 .h文件.  header頭文件.

.h文件中寫這個模塊中的函數(shù)的聲明.

.c文件中寫這個模塊中的函數(shù)的實現(xiàn).





2). 調(diào)用模塊功能的人 只需要包含頭文件就可以 調(diào)用模塊中的函數(shù).







4. 模塊.
 1個模塊至少包含2個文件

   .h文件

   .c文件




###十四【理解】抽查問題
1、為什么需要使用函數(shù)?





2、函數(shù)的基本格式





3、全局變量和局部變量有什么不同?





4、return、break、continue的異同





5、給形參重新賦值會影響實參嗎





6、函數(shù)內(nèi)部可以再定義一個函數(shù)嗎?





7、函數(shù)可以重名嗎?





8、#include的本質(zhì)是什么?





9、#include后面使用""和使用<>有什么不同?








最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容