一、【理解】復習昨天內(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)試


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

我們發(fā)現(xiàn)第43行代碼處有一行綠色的yin陰影,這代CPU執(zhí)行到這一行時停止了(此行還沒執(zhí)行),如果想繼續(xù)往下執(zhí)行,此時有三種方法:
#### 1、往下繼續(xù)執(zhí)行全部
繼續(xù)往下執(zhí)行,直到遇到下一個斷點、阻塞式函數(shù)、或者程序結(jié)束

調(diào)用完成直接執(zhí)行后面的結(jié)果,打印圖形和文字

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


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


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

此時CPU卡在drawHeart,當我們再按step into時,發(fā)生了和step over不同的事情





總結(jié):
step over 和step into最大的不同在于:
step over一下子就執(zhí)行完函數(shù),不進入函數(shù)的內(nèi)部
step into 會進入到函數(shù)的內(nèi)部,在內(nèi)部一行一行地執(zhí)行
###二、刪除斷點:
1)直接按住斷點左鍵不動往右邊一拖再松開即可刪除斷點
2)右鍵斷點陰影,在彈出的選項中左鍵單擊Delete Breakpoint即可刪除斷點

四、【掌握】全局變量和局部變量
-> 全局變量
直接定義在.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ù)的值

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

思考:什么時候該為函數(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)換

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

使用注意:因為實參的本質(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).

2). 函數(shù)的聲明可以在任意的地方但是至少應該在函數(shù)調(diào)用之前聲明
即使是這樣. 但是一般情況下 函數(shù)的聲明我們都放在#include指令之后.
3). 函數(shù)的聲明必須要與函數(shù)實現(xiàn)的函數(shù)頭一樣,否則會出問題.
所以,我們建議大家 先寫函數(shù)的實現(xiàn) 然后將函數(shù)實現(xiàn)的頭拷貝聲明.

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

5). 如果函數(shù)的返回值類型是int類型的那么可以省略函數(shù)聲明
但是為了更好的代碼可移植性 以及可閱讀性十分的建議還是要把聲明寫上.

###十、【掌握】函數(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 <文件名稱>
例:

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

2)如果要包含的文件就在當前寫#include指令文件的同一目錄,則包含路徑可以省略,只寫文件名。
例:

###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后面使用""和使用<>有什么不同?