C++ Primer 讀書筆記 – 第七章

來源:互聯網
上載者:User

 第7章 函數

㈠ 函數的聲明和定義
⒈ 與變數類似:
⑴ 函數必須在調用前聲明
⑵ 函式宣告可與定義分離
⑶ 一個函數只能定義一次但可聲明多次
⒉ 函式宣告由函數傳回型別、函數傳回型別和形參列表組成
三者描述了函數的介面,稱為函數原型(function prototype)
⑴ 函數的運算元,即形參(parameter),在一對圓括弧中聲明,並以逗號分隔
形參名是可選的,但形參需要在定義函數時命名才能使用
⑵ 函數執行的運算在一個稱為函數體(function body)的塊語句中定義
⒊ 函數一般在標頭檔中聲明,在源檔案中定義
此時應使後者包含前者,以便編譯器檢查定義和聲明是否一致
⒋ 將一個較小的、常被調用的函數指定為 inline 可使函數在調用點展開,以避免調用函數的額外開銷
但內聯說明對編譯器來說只是一個建議,編譯器也可能選擇忽略

㈡ 函數的調用和參數傳遞
⒈ 函數的調用
⑴ 使用叫用作業符()實現函數調用
① 運算元是函數名和一組(可能為空白的)用逗號分開的實參(argument)
② 結果類型為函數傳回值的類型,結果為函數的傳回值
⑵ 函數調用做兩件事:
① 首先(隱式)定義形參,並用對應的實參進行初始化
· 形參的初始化與變數一樣:
如果形參為非參考型別則複製實參的值,如果形參為參考型別則它只是實參的別名
② 主調函數(calling function)的執行被掛起,被調函數(called function)開始執行
⒉ 非引用形參
⑴ 指標形參
① 可以通過傳入指標來間接訪問指標所指對象
② 若需要保護指標指向的對象,可指定形參為指向 const 對象的指標
const 形參
① 用來初始化 const 形參的實參無論是不是
const 都可以
在函數中不能改變該實參的局部副本
② 非引用形參是否為 const 不影響編譯器對其所屬函數類型的判別
·註:對於指標,注意區分 const 是修飾指標本身的性質還是所指對象的性質
⑶ 不適合複製實參的情況
① 需要修改實參值時
② 需要將大型物件作為實參傳遞時
③ 無法複製對象時
以上情況可通過將形參定義為指標或參考型別解決
⒊ 引用形參
⑴ 可以使用引用形參返回額外資訊
⑵ 可以利用 const 引用形參避免複製實參
⑶ 使用引用形參時,將不需要修改的定義為 const 會更靈活
const 引用形參不能用
const 左值或右值初始化,而定義為 const 則無此問題
⒋ 一般通過傳遞迭代器來傳遞 vector 等容器
⒌ 數組形參
⑴ 當把數組直接作為實參傳給函數時:
① 若形參不是數組的引用,則自動轉換為指向首元素的指標
例如以下三種定義完全等價:
void f(int*);
//推薦,明確指出操作對象為指標
void f(int[]);
void f(int[10]);//維數被編譯器忽略,寫法容易引起誤解
② 若形參是數組的引用則不發生轉換,函數得到的是數組本身
此時編譯器會檢查形參和實參數組的維數是否匹配
⑵ 把數組傳遞給函數處理時,可以:
⒈ 使用標準庫規範,即傳入首元素指標和超出末端指標
⒉ 傳遞數組首元素地址,並顯式傳遞表示數組大小的形參
⑶ 可以通過傳遞指向數組的指標來傳遞**數組
⒍ 含有可變形參的函數
為相容C語言而保留的特性,只能傳入單一資料型別,大多數類類型對象都不能正確複製
⒎ 預設實參
⑴ 通過給形參表中的形參提供明確的初值可指定預設實參,如
void f(
int, int =
1, int =
2 );
① 預設實參可以是任何適當類型的運算式
② 如果一個形參有預設實參,則其後的所有形參都必須有預設實參
③ 在一個檔案中,只能為一個形參指定預設實參一次
通常應在函式宣告中指定預設實參,並將該聲明放在合適的標頭檔中
⑵ 調用函數時可省略有預設值的實參:若省略則使用預設實參,否則使用使用者提供的實參
· 預設實參只能用來替換函數調用缺少的靠後的實參
因此設計帶有預設實參的函數時,應將最少使用預設實參的形參排在最前,最多使用預設實參的形參排在最後

㈢ 局部對象的範圍和生命期
⒈ 函數體是一個範圍,在其中定義的變數稱為局部變數(local variable),只可在該函數中訪問
局部變數和形參均不能重名
⒉ 自動對象(automatic objects)是局部於函數的對象,會在每次函數調用時重新建立,並在函數結束時撤銷
非靜態局部變數和形參都是自動對象
static 局部對象確保不遲於在程式執行流程第一次經過該對象的定義語句時初始化,一旦建立在程式結束前都不會撤銷
在所在函數被多次調用的過程中,static 局部對象會持續存在並保持它的值

㈣ 函數的傳回值和 return 語句
⒈ 函數傳回型別可為內建類型、類類型或複合類型,但不能是另一個函數或內建數群組類型
void 類型表示該函數不返回任何值
return 語句
用於結束當前函數,將控制權返回給該函數的主調函數
⑴ 沒有傳回值的 return 語句
① 只能用於傳回型別為 void 的函數
② 非必需,隱式 return 發生在函數最後一個陳述式完成時
⑵ 具有傳回值的 return 語句
① 傳回型別不是 void 的函數必須返回一個值(主函數 main 除外)
註:應在函數中的每條執行路徑末尾都提供 return 語句;若不提供編譯器可能也無法發現
② 用函數傳回值初始化在調用函數處建立的臨時對象,與用實參初始化形參的方法一樣
即若返回非參考型別則得到副本,若返回參考型別則得到對象本身
③ 切勿返回局部對象的引用或指標

㈤ 函數的重載
⒈ 出現在相同範圍中的兩個函數,如果具有相同的名字而形參表不同,則為重載函數(overloaded function)
僅僅是傳回型別不同、預設實參不同、非引用形參的 const 性質不同不能實現重載
⒉ 若局部地聲明函數,則該函數屏蔽而非重載在外層範圍中聲明的同名函數
⒊ 重載確定的三個步驟
⑴ 確定候選函數集合
候選函數(candidate function)是與被調函數同名的函數,且在調用點上聲明可見
⑵ 從候選函數集合中選擇可行函數(找不到則此調用錯誤)
可行函數(viable function)滿足兩個條件:
① 函數形參與該調用的實參個數匹配(考慮預設實參)
② 每個實參的類型須與對應形參匹配(類型相同或可隱式轉換)
⑶ 尋找首選(有多個匹配程度相同的則調用有二義性)
原則是實參類型與形參類型越接近則匹配越佳。具體匹配程度從高到低為:
① 精確匹配:實參與形參類型相同
② 通過型別提升實現的匹配
③ 通過標準轉換實現的匹配
④ 通過類類型轉換實現的匹配

㈥ 函數指標
⒈ 定義形式
傳回型別 (*標識符)(形參表)
⒉ 可使用 typedef 簡化定義
typedef 傳回型別 (*自訂類型名)(形參表)
⒊ 對函數指標進行初始化和賦值,可使用:
⑴ 同類型的函數
引用函數名但不調用該函數時,函數名被自動解釋為指向函數的指標
因此可以直接使用函數名對函數指標初始化或賦值,不需要使用取地址操作符&
·註:指標類型須與函數完全符合
⑵ 同類型的函數指標
⑶ 0值常量運算式
⒋ 通過函數指標調用函數
可以不使用解引用操作符,直接使用函數叫用作業符()調用所指函數
⒌ 函數指標作形參時,星號*可寫可不寫
⒍ 函數的指標作函數傳回值
函數指標傳回型別 (*函數名(函數形參表))(函數指標形參表)

㈦ 主函數 main
⒈ 傳回值
⑴ 主函數傳回型別為 int, 傳回值在大多數系統中是一個狀態指示器
返回0表示程式運行成功,其它大部分值表示失敗
⑵ 不需要顯式使用 return 語句,編譯器將隱式插入返回0的語句
⑶ 為使傳回值獨立於機器,cstdlib 標頭檔定義了兩個預先處理變數
EXIT_FAILURE(運行失敗)    EXIT_SUCCESS(運行成功)
⒉ 使用主函數形參處理命令列選項
int main(int argc,
char* argv[])
· argv為一個C風格字串數組,儲存了從命令列調用程式時輸入的字串(包括程式名和參數)
· argc表示argv中字串的個數
⒊ 主函數 main 不允許被顯式調用、取地址或重載

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.