1.函數調用:實參初始化形參;控制權交給被調函數
2.函數返回(return語句):返回return中的值;控制權交回主函數
3.參數傳遞
傳值 | 傳引用 | 傳指針 | |
初始值 | 不變,拷貝給形參 | 可變,形參是實參的別名 若不想變,加const |
拷貝指針給形參 |
//1.傳指針 void reset(int *p) { *ip=0;//改變了指針所指向對象的值 ip=0;// 只改變ip的局部拷貝,實參未被改變。指針本身可以在局部內任意變化,但指針指向的值沒變 } int i=42; reset(&i);//改變I的值,而非地址 cout<<i<<endl;//i=0 //2.傳引用 void reset(int &i) { i=0; } int j=42; reset(j);//改變I的值,而非地址 cout<<j<<endl;//j=0
4.const參數傳遞
void reset(int &i)//引用傳遞 { i=0; } void reset(int *ip)//指針傳遞 { *ip=0; } int i=0; const int ci=i; string::size_type ctr=0; reset(i);//引用傳遞 reset(&i);//引用傳遞 reset(ci);//×,int類型不能傳遞給const int類型 reset(&ci);//×,const in *類型不能傳遞給int *類型 reset(42);//× reset(ctr);//×
如果函數參數是const呢?能接受什么參數傳入?
5.數組形參
//三個函數等價,形參是const int* void print(const int*); void print(const int[]);// void print(const int[10]);//期望含有10個元素的數組,實際不一定,那實際怎么操作,如果元素>10的話? int i=0,j[2]={0,1}; print (&i);//int*類型 print(j);//自動轉為int *
5.1 判斷數組長度
1.使用標記(字符串末尾空)
void print(const char*cp) { if(cp) { while(*cp)//判斷方法 cout<<*cp++ } }
2.使用標准庫
void print(const int *beg,const int *end) { while (beg!=end) cout<<*beg++<<endl; } int j[2]={1,2}; print(begin(j),end(j));
3.顯式傳遞大小
void print(const int ia[],size_t size) { for (size_t i=0;i!=size;i++){ cout<<ia[i]<<endl; } }
6.main命令行,傳遞參數
int main(int argc, // char *argv[])//argv是數組,元素是char*指針 { } //與上式等價 int main(int argc,// char ** argv)//argv 指向char* { } prog -d -o file data0//可執行文件prog,輸入參數 //argc=5 //argv[0]= "prog"; //argv[1]= "-d"; //argv[2]="-o"; //argv[3]=" file"; //argv[4]=" data0";
7.可變形參
7.1 類型相同,數量不同——initializer_list標准庫類型
常量值,無法改變,只讀
void error_msg(initializer_list<string> istring) { for (auto beg=istring.begin();beg!=istring.end();++beg) cout<<*beg<<" "; cout << endl; } if (expected !=actual)//2 個string 對象 error_msg({"FunctionX output:",expected, actual });//{}用於傳遞initializer_list序列 else error_msg({"FunctionX output:","Okay"});
可根據實際改寫為先打印錯誤代碼,再打印內容:
void error_msg(ErrorCode e, initializer_list<string> string) { cout<<e.print()<<":" for (const auto & elem:string) cout<< elles<<" "; cout<<endl; }
7.2 省略符形參:varargs標准庫
8.函數返回
8.1 不要返回局部對象的引用或指針
8.2 返回數組
1.聲明返回數組指針的函數
int (*func(int i))[10];//解引用的結果是一個10個int元素的數組 //func(int i): //(*func(int i)):對函數調用的結果解引用 //
2.尾置返回?
auto func(int i)->int(*)[10];
3.decltype返回?
int odd[]={1,3,5,7,9}; int even[]={0,2,4,6,8}; decltype (odd) *arrptr(int i)//decltype不會把數組轉為指針 { return (i%2)?&odd:&even; //返回一個指針,該指針指向含有5個整數的數組 }
9.函數重載
9.1.不能定義兩個除了返回值類型不同外,其他都相同的函數
9.2 有時候兩個形參看起來類型不一樣,實際上相同,也是不許的
9.3 帶頂層const的形參和不帶const的形參是無法區分的
bool lookUp(Phone);//1 bool lookUp(const Phone);//2,與1重復。/? bool lookUp(Phone*);//3 bool lookUp(Phone* const);//4,與3重復。/? bool lookUp(Phone&);//5,作用於Phone的引用 bool lookUp(const Phone&);//6,作用於常引用,同時存在會優先選用 bool lookUp(Phone*);//7,作用於指向Phone的指針 bool lookUp(const Phone *)//8,作用於指向常量的指針,同時存在會優先選用
10.默認實參:一旦有一個參數為默認,其他必須給默認值
string screen(size_type hight=24, size_type width=80);
window=screen();
window=screen(100,200);
11.內聯函數
1.定義在頭文件中(文件中多次要用)
12.constexpr函數
1. 函數的返回類型、形參類型都是字面值類型
2.函數中有且僅有一條return語句
3.定義在頭文件中
constexpr int new_size() { return 42; } constexpr size_t scale(size_t cnt) { return new_sz()* cnt; } int arr[scale(2)];
13.函數調用時的實參匹配
1.精確匹配
2.const轉換實現匹配
3.類型提升實現匹配
4.算術類型轉換(或指針轉換)實現匹配
5.類類型轉換實現匹配
bool lookUp(Account &); bool lookUp(const Account &); Account b; lookUp(b);//兩個都可以調用,但是第一個優先
14.函數指針
bool lengthCompare(const string &,const string &); bool (*pf)(const string &,const string &);//pf是指向函數的指針 //bool *pf(const string &,const string &);//聲明一個名為pf的函數,返回bool * pf = lengthCompare; pf =& lengthCompare;//與上等價 bool b1=pf("hello","goodbye"); bool b2=(*pf)("hello","goodbye"); bool b3=lengCompare("hello","goodbye");//三式等價
14.1 返回指向函數的指針
14.2 auto 和decltype用於函數指針類型