C++函数传参:引用和const参数

688 阅读2分钟

一  在函数传参中使用引用

\

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方面的细节:

点此处了解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)\

\

\

\

\

\

\

\

\


\