软件定制开发网站建设,成都网站建设哪里好点,网站建设要准备什么资料,wordpress前台登录框C入门——引用
一、引用的概念
引用不是新定义一个变量#xff0c;而是给已存在变量取了一个别名#xff0c;编译器不会为引用变量开辟内存空间#xff0c;它和它引用的变量共用同一块内存空间。这就好比《水浒传》中#xff0c;一百零八位好汉都有自己的绰号。通过…C入门——引用
一、引用的概念
引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。这就好比《水浒传》中一百零八位好汉都有自己的绰号。通过符号我们可以实现对一个变量的引用。
1.使用规则
如图所示
在这里我们先定义了一个变量aint b的意思就是给a取别名为b因为a定义的是一个整型因此是int如果a是浮点型则取别名为double如果a为整型指针那么取别名就应该写为int*。我们可以给同一个变量取多个别名比如这里就是把a取别名为b把b又取别名为c其实b和c都是a的别名就像《水浒传》中一个好汉可能有好多个称呼比如鲁智深他在做和尚之前名为鲁达作为提辖人称鲁提辖后来人们又叫他“花和尚”一个道理。我们将a以及它的别名bc的地址打印出来不难发现都是指向同一块空间。
2.注意事项
引用在定义时必须初始化指针没有要求。如图所示 同理我们也不能引用空指针。我们来看下面两段代码 在两段代码中均初始化了两个变量int a1int b10在第一段代码中我们给变量a取别名为x然后我们让xb。怎么理解这个xb呢我们先来运行一下发现此时a和b都是10说明a发生了变化。如果xb意思是x刚才是a的别名现在变成b的别名那么a的值就不会发生变化而事实恰恰相反说明这里的并不是改变引用的对象而是一个赋值将b的值拷贝给a的别名x既然a的别名发生了变化自然而然a也就发生了变化因为a和x本来就是一个变量就好比“豹子头”喝了酒就是林冲喝了酒同样的意思。第二段代码就有所不同了p作为一个指针它指向的对象是可以改变的。因此我们可以总结出引用和指针的一个不同点引用一旦引用一个实体再不能引用其他实体而指针可以任意改变指向的对象。引用是编译器自己处理指针需要显式解引用 让我们来感受一下 这是一个经典的交换两个数的函数我们以前都是用的第一种方法使用指针但是在函数中需要写解引用有了引用取别名操作后我们在传参的时候也不需要传地址直接传值即可因为函数形参都是int是实参的别名因此在函数里直接修改别名即可更加方便。
二、引用作参数、返回值
1.引用作参数 上文提到的就是一个典型的例子引用做参数能够减少拷贝提高效率尤其是大对象深拷贝对象以后会逐渐讲解使用引用效率更高我们举个例子
#include time.hstruct A
{int a[100000];
};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;
}运行结果如图 很明显传引用效率更高。
2.引用作返回值
传值返回传引用返回 这里返回的是n的引用引用作返回值能够减少拷贝提高效率尤其是大对象深拷贝对象以后会逐渐讲解使用引用效率更高我们举个例子
#include time.hstruct 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;
}int main()
{TestReturnByRefOrValue();return 0;
}
很明显引用作返回值效率更高。
基本所有的场合都可以用引用进行传参。需要注意的是我们应当谨慎使用引用作为函数的返回值如果出了函数的作用域引用的对象不在了就不能使用引用作返回还在比如static int a就可以用引用返回。
三、引用的权限问题——常引用
1.引用过程中权限不能放大
如图所示 这里的a加了const是不能被修改的但是a的别名b没有加const是可以被修改的在引用取别名的过程中a的权限被放大因此产生报错作如下修改即可 这样一来a和b都是不能被修改的它们的权限相等。
2.引用的过程中权限可以平移或缩小
权限平移 上文的示例就是一个权限的平移a和它的引用b都加上了const都是不能被修改的。权限缩小 如图所示 如图所示这里的a是可以被修改的它的别名b是不可以被修改的这就是权限的缩小那么既然b不可以被修改为什么a1后b也1了呢我们打个比方宋江让李逵下山办事城里的人们都知道“黑旋风”的存在因此宋江告诉李逵下山后人人都知道你是“黑旋风”你不能喝酒喝酒会误事等你回来后我们再慢慢喝。也就是说李逵作为“黑旋风”时不能喝酒在这里就相当于a的别名b不能被修改李逵上山后宋江又允许他喝酒了这里就相当于a1那么既然李逵上山后喝了酒“黑旋风”不就喝酒了吗a1就是b1只不过在只能以b的形式出面时权限被约束罢了。
本期总结下期预告
本期内容我们讨论了引用的相关知识下期内容将为大家带来内联函数auto关键字基于范围的for循环等内容
感谢大家的关注我们下期再见