C++函式傳參:引用和const引數
一 在函式傳參中使用引用
1.使用例子:
#include<iostream> using namespace std; void reset(int &i){//引用傳參 i=0; } void reset(int *i){//指標傳參 *i=0; } int main(){ int a=10,b=24,c=8; int &d=b; reset(a);cout<<a<<endl; reset(d);cout<<d<<endl; reset(&c);cout<<c<<endl; return 0; }
上面結果執行均是0。
2. 函式傳參使用引用的好處:
(1)避免拷貝:
拷貝大的類型別物件或者容器物件是不值得提倡的。
也有可能有些類型別就不支援拷貝,此時函式只可通過引用形參訪問物件。
(2)可以返回更多資訊:
例如:下用cnt傳回所找字元出現個數。
#include<iostream> #include<string> using namespace std; string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt){ auto first=s.size(); cnt=0; for(decltype(first) i=0;i!=s.size();++i){ if(s[i]==c){ if(first==s.size()) first=i; cnt++; } } return first; } int main(){ int first; string::size_type occurs=0; cout<<"第一次出現a位置:"<<FindFirstOccur("kobe bryant",'a',occurs)<<endl; cout<<"出現的次數:"<<occurs<<endl; return 0; }
執行結果:
二 const形參和實參
1. 實參初始化形參時會忽略頂層const,即是說,形參有頂層const的時候,
傳給它常量物件或者非常量物件均可以,當然對傳進來的不管是不是const物件,都不能寫。
#include<iostream>
using namespace std;
void test(const int i){
}
int main(){
const int a=0;
int i;
test(a);
test(i);
return 0;
}
儘管在C++中可以允許函式名字相同但通過形參列表的不同區分,
但是由於形參頂層const被忽略,故不能做一下貌似對的寫法:
#include<iostream>
using namespace std;
void test(const int i){
}
void test(int i){
}
int main(){
const int a=0;
int i;
test(a);
test(i);
return 0;
}
會顯示重複定義!
2. 我們要知道一些const方面的細節:
容易理解:
#include<iostream>
#include<string>
using namespace std;
void reset(int &i){
i=0;
}
void reset(int *i){
*i=0;
}
string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt){
auto first=s.size();
cnt=0;
for(decltype(first) i=0;i!=s.size();++i){
if(s[i]==c){
if(first==s.size())
first=i;
cnt++;
}
}
return first;
}
int main(){
int i=24;
const int *p=&i;//正確,且不能通過p改變i,底層const!
const int &r=i;//正確,且不能通過r改變i
const int &r2=24;//正確!
// int *p2=p;//錯誤!
// int &r3=r;//錯誤!
// int &r4=42;//錯誤!
const int a=i;
string::size_type s=0;
reset(&i);//void reset(int *i)
// reset(&a);//錯誤!不能用指向const int物件的指標初始化int *
reset(i);//void reset(int &i)
// reset(a);//錯誤!不能將普通引用繫結到const物件
// reset(42);//錯誤!
// reset(s);//錯誤!型別不匹配,s是無符號型別
FindFirstOccur("kobe bryant",'a',s);
return 0;
}
3. 使用常量引用
若函式不改變形參,儘量將形參定義為常量引用,可避免兩個問題:
(1)如在上述函式
string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt)
中,改為
string::size_type FindFirstOccur(string &s,char c,string::size_type &cnt)
則對於呼叫
FindFirstOccur("kobe bryant",'a',s)報錯!
(2)如果在另一個函式形參列表中有(const string &s,·····)
且函式中裡面使用了函式
string::size_type FindFirstOccur(string &s,char c,string::size_type &cnt)
報錯!當然如果真要如此定義形參,也可以定義一個string變數,成為s副本,再傳給
FindFirstOccur(string &s,char c,string::size_type &cnt)