往期文章: C++学习笔记
打个比方,C语言调用函数函数就相当于:菜市场的人要吃饭,厨师叫菜市场call外卖员运菜给餐馆,厨师在餐馆炒好菜后贪心,做了两份菜只回给一份菜,然后call外卖员运回菜市场。
(函数被调用,调用时给了函数实参,实参传到函数定义处用形参接收,然后形参执行函数内容得到结果,最后把结果拷贝一份传回去)
C++调用函数则是:菜市场的人要吃饭,菜市场的人叫厨师来菜市场炒菜,当场做一份菜。
(函数被调用,函数对别名执行函数内容,执行完毕结果自动给到函数变量里面去)
引用是给一个已经存在的变量取一个别名,变量与它的引用变量共用一块内存空间。
代码如下(示例):
int m=0;
int& n=m; //n是m的别名
printf("%p\n",&m);
printf("%p\n",&n); //它们的地址相同
printf("%p\n",&n);
printf("%p\n",&n); //它们打印的结果相同
PS:引用的类型和被引用的实体是一致的。
代码如下(示例):
int a = 10;
int& b; //必须为别名赋值否则报错
int& c = a;
int& d = a;
int与&会被识别为一个整体,即使它们之间隔了空格,在代码用分号结尾后编译器会主动把它们合并。
我们再给引用变量赋值时要注意赋值时,变量的权限和值的权限是否一致。
const int a = 0;
int& na = a; //const int 与 int 权限不同,
//前者有常性不可更改,后者可以更改,
//权限不同时取别名会报错
const int& ra = a; //权限一致,可取别名
//普通数字有常性,它的别名必须也有常性
int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
//浮点型数值也有常性
double d = 12.34;
int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
引用变量做参数的好处是可以直接操作实参本体;即调用的函数可以直接对实参执行指令,不需要设置返回值返回结果。这省去了C语言的传参和返回值的麻烦。
打个比方,C语言调用函数函数就相当于:菜市场的人要吃饭,厨师叫菜市场call外卖员运菜给餐馆,厨师在餐馆炒好菜后贪心,做了两份菜只回给一份菜,然后call外卖员运回菜市场。(函数被调用,调用时给了函数实参,实参传到函数定义处用形参接收,然后形参执行函数内容得到结果,最后把结果拷贝一份传回去)
C++调用函数则是:菜市场的人要吃饭,菜市场的人叫厨师来菜市场炒菜,当场做一份菜。(函数被调用,函数对别名执行函数内容,执行完毕结果自动给到函数变量里面去)
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
int main() {
int x = 1;
int y = 2;
printf("%d %d\n", x, y);
Swap(x, y);
printf("%d %d\n", x, y);
return 0;
}
做返回值的时候注意
#include
#include
using namespace std;
int& Add(int a, int b) //注意这里Add做了c的别名,可c在Add函数结束的时候就销毁了,c的值变成了一个随机值,此时Add在给一个随机值做别名。
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(1, 2); //Add和ret都在给同一个随机值做别名
cout << "Add(1, 2) is :" << ret << endl;
Add(3, 4); //Add和ret都在给同一个随机值做别名,再调用一次Add,c也还是在那个位置被销毁
cout << "Add(1, 2) is :" << ret << endl; //Add和ret都在给同一个随机值做别名
return 0;
}
引用做参数可以省去传参的过程,
引用做返回值可以省去结果拷贝的过程,效率是很高的。
如,引用做参数代码如下:
#include
#include
#include
using namespace std;
struct A
{
int a[10000];
};
void TestFunc1(A a)
{
}
void TestFunc2(A& a)
{
}
void TestRefAndValue()
{
A a;
// 以值作为函数参数
size_t begin1 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc1(a);
size_t end1 = clock();
// 以引用作为函数参数
size_t begin2 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc2(a);
size_t end2 = clock();
// 分别计算两个函数运行结束后的时间
cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main() {
TestRefAndValue();
return 0;
}
可以看到 0:7 ,效果拔群。
同理,引用做返回值也是如此。