当当网站建设与易趣网站对比,wordpress企业免费主题下载地址,wordpress批量,网站建设与管理属于什么部门六、引用
6.1 引用的概念 引用不是新定义一个变量#xff0c;而是给已存在变量取了一个别名#xff0c;编译器不会为引用变量开辟内存空间#xff0c;它和它引用的变量共用同一块内存空间。#xff08;语法上#xff09; 格式#xff1a;类型 引用变量名(对象名) …六、引用
6.1 引用的概念 引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。语法上 格式类型 引用变量名(对象名) 引用实体
void TestRef()
{int a 10;int ra a;//定义引用类型printf(%p\n, a);printf(%p\n, ra);
}注意引用类型必须和引用实体是同种类型的 6.2 引用的特性
引用在定义时必须初始化一个变量可以有多个引用引用一旦引用一个实体再不能引用其他实体 说明 int d c; //c是a变量的别名再为c取别名实际上还是引用a。相当于int d a;b x; //b是a的别名这句相当于a x; 将x赋值给b(a) 6.3 常引用
常引用即引用的类型用const进行修饰表示不能通过该引用修改引用对象的值。类似于常量指针const int *p;
权限不能放大权限可以缩小显示或隐式类型转换都会产生同类型的临时变量产生的临时变量具有常性。
void TestConstRef()
{//权限不能放大const int a 20;//int ra a;const int ra a;//权限可以缩小int b 30;const int rb b;//类型转换产生临时变量产生的临时变量具有常性int i 1;double d i; //类型转换的过程中会产生同类型的临时变量//double rd i; //产生的临时变量具有常性 const double rd i; //此处临时变量的类型是const double
}说明 权限放大或缩小的问题只存在于引用或指针上。普通变量不存在因为普通变量不对源值做修改只做值拷贝。如果使用引用传参函数内如果不改变源值输入型参数那么建议尽量用const引用传参提高程序的健壮性且这样的形参具有非常强的接收度类型转换。 6.4 使用场景
1. 做输出型参数
引用做输出型参数相比指针传参使用更加方便。
void Swap(int left, int right){int temp left;left right;right temp;
}
int main(){int a 0, b 2;Swap(a,b);return 0;
}2. 大对象传参
以值作为参数或者返回值类型在传参和返回期间函数不会直接传递实参或者将变量本身直接返回而是传递实参或者返回变量的一份临时的拷贝因此用值作为参数或者返回值类型效率是非常低下的尤其是当参数或者返回值类型非常大时效率就更低。
我们可以做以下测试
#include time.h
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;
}测试结果 得出结论大对象使用引用传参提高效率节省空间。
3. 做输出型返回值
做输出型返回值调用者可以修改返回对象。
int Count()
{static int n 0;n;// ...return n;
}同指针一样不能返回局部变量的引用。但可以返回静态区或堆空间变量的引用。 4.误区警示返回局部变量的引用
下面代码输出什么结果为什么
int Add(int a, int b)
{int c a b;return c;
}
int main()
{int ret Add(1, 2);Add(3, 4);cout Add(1, 2) is : ret endl;return 0;
}测试结果 解释原因 得出结论函数返回后函数内的局部变量栈帧空间就销毁了。那么一定不能返回局部变量的引用只能传值返回。
5. 返回大对象的引用
返回大对象的引用可以减少拷贝提高效率。
我们可以做以下测试
#include time.h
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
// 以值作为函数的返回值类型
size_t begin1 clock();
for (size_t i 0; i 100000; i)
TestFunc1();
size_t end1 clock();
// 以引用作为函数的返回值类型
size_t begin2 clock();
for (size_t i 0; i 100000; i)
TestFunc2();
size_t end2 clock();
// 计算两个函数运算完成之后的时间
cout TestFunc1 time: end1 - begin1 endl;
cout TestFunc2 time: end2 - begin2 endl;
}测试结果 得出结论结合大对象的传参和返回测试我们可以看出传值和引用在作为传参以及返回值类型上效率相差很大。 6.5 引用和指针的区别
在语法概念上引用就是一个别名没有独立空间和其引用的实体共用同一块空间。
#include iostream
using namespace std;
int main()
{ int a 10; int ra a; int* pa a; couta aendl; coutra raendl; coutpa paendl; cout*pa *paendlendl; couta aendl; coutra raendl; coutpa paendl; coutpa paendl;
return 0;
} 测试结果
在底层实现上实际是有空间的因为引用是按照指针方式来实现的。
int main()
{
int a 10;
int ra a;
ra 20;
int* pa a;
*pa 20;
return 0;
}我们来看下引用和指针的汇编代码对比 底层汇编完全相同说明引用是按照指针的方式来实现的。 引用和指针的不同点:
引用概念上定义一个变量的别名指针存储一个变量地址。引用在定义时必须初始化指针没有要求。引用在初始化时引用一个实体后就不能再引用其他实体而指针可以在任何时候指向任何一个同类型实体。没有NULL引用但有NULL指针。在sizeof中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下占4个字节)。引用自加即引用的实体增加1指针自加即指针向后偏移一个类型的大小。有多级指针但是没有多级引用。访问实体方式不同指针需要显式解引用引用编译器自己处理。引用比指针使用起来相对更安全。 总结 指针更强大更危险更复杂引用相对局限一些更安全更简单