第六章 函數
函數是一個命名了的代碼塊,通過調用函數執行相應的代碼。
函數基礎
局部對象
函式宣告
參數傳遞
如果形參是參考型別,它將綁定到對應的實參上;否則,將實參的值拷貝後賦給形參。
- 如果無需修改引用形參的值,最好將其聲明為常量引用。
main:處理命令列選項
假設main函數位於可執行檔prog內,我們可以向程式傳遞下面的選項:
prog -d -o ofile data0
這些命令通過兩個可選的形參傳遞給main函數:
int main(int argc, char *argv[]) {...}//或:int main(int argc, char **argv) {...}
當實參傳給main函數之後,argv的第一個元素指向程式的名字或者一個Null 字元串,接下來的元素一次傳遞命令列提供的實參。最後一個指標只會掉元素值保證為0。
- 以上面的命令列為例:
argc = 5;argv[0] = "prog";argv[1] = "-d";argv[2] = "-o";argv[3] = "ofile";argv[4] = "data0";argv[5] = 0;
含有可變形參的函數
傳回型別和return語句
主函數main的傳回值
返回數組指標
使用類型別名
typedef int arrT[10]; //arrT是一個類型別名,它表示的類型是含有10個整數的數組
using arrT = int[10]; //與上一句等價
arrT* func(int i); //func返回一個指向含有10個整數的數組的指標
聲明一個返回數組指標的函數,形式如下
Type (*function(parameter_list)) [dimension]
//Type表示返回的數組指標指向的數組元素類型
//dimension表示數組的大小
//例如:
int (*func(int i)) [10];
使用尾置傳回型別(C++11)
auto func(int i) -> int(*)[10];
使用decltype
int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
decltype(odd) *arrPtr(int i)
{
return (i % 2) ? &odd : &even; //返回一個指向數組的指標
}
函數重載
如果同一範圍內的幾個函數名字相同但形參列表不同,我們稱之為重載(overloaded)函數。
特殊用途語言特性
介紹三種函數相關的語言特性:預設實參、內嵌函式、constexpr函數。
預設實參
內嵌函式(inline)
調用函數一般比求等價運算式的值要慢,內嵌函式可避免函數調用的開銷。
- 將函數指定為內嵌函式,通常就是將它在每個調用點上“內聯地”展開。
constexpr函數
內嵌函式和constexpr函數通常定義在標頭檔中
調試協助
程式可以包含一些用於調試的代碼,但這些代碼只在開發程式時使用。當應用程式編寫完成準備發布時,要先屏蔽掉調試代碼。這種方法用到兩項預先處理功能:assert和NDEBUG。
assert預先處理宏
#include <cassert>assert(expr);//首先對expr求值,//如果運算式為假(即0),assert輸出資訊並終止程式的執行。//如果運算式為真(即非0),assert什麼也不做。//例如:對一個文本進行操作的程式可能要求所給定單詞的長度都大於某個閾值。assert(word.size() > threshold;
NDEBUG預先處理變數
assert的行為依賴於一個名為NDEBUG的預先處理變數的狀態。如果定義了NDEBUG,則assert什麼也不做。預設狀態下沒有定義NDEBUG,此時assert將運行執行時檢查。
這隻是偵錯工具的輔助手段,不能代替真正的邏輯檢查,也不能代替程式本應該包含的錯誤檢查。
除了assert以外,也能使用NDEBUG編寫自己的條件調試代碼:
//如果定義了NDEBUG,#ifndef和#endif之間的代碼將被忽略void print(const int ia[], aize_t size){ #ifndef NDEBUG //_ _func_ _是編譯器定義的一個局部靜態變數,用於存放函數的名字,它是const char的一個靜態數組。 cerr << _ _func_ _ << "array size is " << size << endl; #endif}
除了_ _ func _ _之外,還有其它四個名字:
_ _FILE_ _ 存放檔案名稱的字串字面值_ _LINE_ _ 存放當前行號的整型字面值_ _TIME_ _ 存放檔案編譯時間的字串字面值_ _DATA_ _ 存放檔案編譯日期的字串字面值
函數指標
bool lengthCompare(const string &, const string &);//pf指向一個函數,該函數的參數是兩個const string的引用,傳回值是bool類型。注意圓括弧必不可少bool (*pf) (const string &, const string &); //未初始化
當我們把函數名作為值使用時,該函數自動地轉換成指標
pf = lengthCompare; //pf指向名為lengthCompare的函數pf = &lengthCompare; //等價指派陳述式,&是可選的
調用該函數:
//此三個調用等價bool b1 = pf("hello", "goodbye");bool b2 = (*pf)("hello", "goodbye");bool b3 = lengthCompare("hello", "goodbye");
參考:C++Primer第五版
相關文章:
第四章C++:運算式概念-運算子的應用
第五章C++:語句的相關介紹