一 在函数传参中使用引用
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)