当前位置: 首页 > news >正文

沈阳建站平台南通个人网站建设

沈阳建站平台,南通个人网站建设,网站的做网站公司,宝塔自助建站系统源码文章目录 一、引用的概念二、引用的语法规则1、引用特性2、常引用 二、引用的使用场景1. 引用做参数2. 引用做返回值 三、引用和指针的区别 一、引用的概念 首先明确一下,引用不是定义一个新的变量,而是给已经存在的变量起一个别名,变量和他…

文章目录

      • 一、引用的概念
      • 二、引用的语法规则
        • 1、引用特性
        • 2、常引用
      • 二、引用的使用场景
        • 1. 引用做参数
        • 2. 引用做返回值
      • 三、引用和指针的区别

在这里插入图片描述

一、引用的概念

首先明确一下,引用不是定义一个新的变量,而是给已经存在的变量起一个别名,变量和他的引用是共用同一块内存空间。

C++中的引用就是和人的外号一样,人的本名和外号都是指同一个人。比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

二、引用的语法规则

类型& 引用变量名(对象名) = 引用实体;

#include<iostream>
using namespace std;int main()
{int a = 10;int& b = a;  // b是a的引用cout << a << endl;cout << b << endl;return 0;
}

在这里插入图片描述
变量a 和它的引用b使用的是同一块内存空间

int main()
{int a = 10;int& b = a;cout << &a << endl;cout << &b << endl;  // a 和 b 使用的是同一块内存空间return 0;
}

在这里插入图片描述

int main()
{int a = 10;int& b = a;b = 20; cout << a << " " << b << endl;return 0;
}

在这里插入图片描述由于变量和变量的引用是使用的同一块内存地址,这意味着如果改变b,那么a也会随着b的改变而改变。

1、引用特性

1、引用在定义时必须初始化

void testref()
{int a = 10;int& b;  // err 引用是必须初始化
}

在这里插入图片描述

2、一个变量可以有多个引用
一个变量被引用后,可以继续被引用,也可以引用变量的引用。

void testref02()
{int a = 10;int& b = a;int& c = a;  // 一个变量可以有多个引用 int& d = b;  // 可以引用变量的引用
}

3、引用一旦引用一个实体(变量),就不能在引用其他实体

void testref02()
{int a = 10;int b = 20;int& c = a;int& c = b;  // c不可以重复引用
}

在这里插入图片描述
这里要和C/C++中的指针区分一下,指针可以改变指针指向的对象,但是引用不可以。

2、常引用

一般来说,引用只可以引用变量,不可以直接引用常量的。因为常量是不可以改变的。

void testref03()
{int& a = 10;  // err, 不可以引用常量
}

在这里插入图片描述
解决办法
想要引用常量的话,只要在引用的前面加一句const,加上const之后,引用就不可以发生改变。
除了上述情况,引用的类型不同也会导致编译不同过,这是因为在发生类型转化的过程中,会产生临时变量,而临时变量具有常性,和常量一样,需要用const引用。

在这里插入图片描述

void testref04()
{char ch = 'a';int& a = ch;  // 不可以引用不同类型的变量,类型转化时会产生临时变量,临时变量具有常性
}

在这里插入图片描述

产生临时变量时都要用常引用。

void testref05()
{char ch = 'a';const int& a = ch;
}

二、引用的使用场景

1. 引用做参数

在C语言学习指针的时候一定学过一个交换函数Swap,那时候我们在Swap时参数必须要用传址调用,因为如果用传值调用的话,形参的改变是不影响实参的,无法实现交换功能。
在这里插入图片描述

但是如果我们学了引用的话就不需要使用传址调用了,可以直接用引用作为参数,引用的形参就是实参的别名

void func(int& x, int& y)
{cout << &x << endl;cout << &y << endl;
}int main()
{int a = 10;int b = 20;cout << &a << endl;cout << &b << endl;cout << "-------------" << endl;func(a, b);return 0;
}

在这里插入图片描述
用引用的话,在函数传参时就不需要传址调用了,更加方便。

void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
2. 引用做返回值

是的,你没看错,引用不仅可以做函数的参数,还可以做函数的返回值,我们之前写的具有返回值的函数返回的并不是直接将函数中的变量,而是返回的变量的一份临时拷贝,而拷贝是需要付出一定代价的,这样会降低我们代码的效率,但是如果我们用引用返回的话就可以避免拷贝的代价,在对程序性能要求高且允许使用引用的情况下,尽量使用引用返回。

注意:并不是所有的函数都可以用引用返回,有些强行使用引用返回会造成一些不必要的错误。
函数可以用引用返回的条件:
函数的返回值在出函数作用域后不会被销毁。

int& Count()
{static int n = 0;n++;// ... return n;
}

静态变量出了函数定义域之后不会销毁,可以用引用返回。

int& Count()
{int n = 0;n++;// ...return n;  // n在出函数作用域后就销毁了,不要用引用返回
}

传值、传引用的的效率比较
用值作为参数或返回值时,在传参和返回期间,函数是不会直接传递实参或则是将变量之间返回,而是传递实参或者返回变量的一份临时拷贝,所以用值传参或者做返回值效率是非常低的,尤其是当参数或者返回值类型非常大时,效率更加低下。

值和引用作为函数参数的效率对比:

#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;
}

在这里插入图片描述
传值的效率明显低于传引用。

值和引用作为函数返回值的效率对比:

#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 (int i = 0; i < 100000; i++)TestFunc1();size_t end1 = clock();// 以引用作为函数的返回值类型size_t begin2 = clock();for (int i = 0; i < 100000; i++)TestFunc2();size_t end2 = clock();// 计算两个函数运算完成之后的时间cout << "TestFunc1() Time:" << begin1 - end1 << endl;cout << "TestFunc2() Time:" << begin2 - end2 << endl;
}int main()
{TestReturnByRefOrValue();return 0;
}

在这里插入图片描述
传值和指针在作为传参以及返回值类型上效率相差很大。

三、引用和指针的区别

1、语义概念上引用就是变量的别名,没有独立空间,和引用实体共用同一块空间。

int main()
{int a = 10;int& b = a;cout << &a << endl;cout << &b << endl;return 0;
}

在这里插入图片描述
底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

在这里插入图片描述
2、引用必须初始化,指针可以在定义时不初始化

int a = 20;
int* pa;  // 指针可以不初始化
int& ra;  // 引用必须初始化

在这里插入图片描述

3、 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体

4、没有NULL引用,但有NULL指针。

int* pa = NULL;
int& ra = NULL;  // err,没有NULL引用

在这里插入图片描述
5、在sizeof中含义不同引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)

#include<string>
int main()
{string str = "abcdef";string& rstr = str;string* pstr = &str;cout << "string& rstr = str: " << sizeof(rstr) << endl;cout << "string* pstr = &str: " << sizeof(pstr) << endl;return 0;
}

在这里插入图片描述
6、 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

int main()
{int a = 10;int& ra = a;int* pa = &a;ra++;pa++;cout << "int& ra = a:  " << ra << endl;cout << "int* pa = &a: " << pa << endl;return 0;
}

在这里插入图片描述
7、有多级指针,但是没有多级引用

int a = 10;
int* pa = &a;
int** ppa = &pa;
int& ra = a;
int&& rra = ra;  // 无多级引用

在这里插入图片描述
8、访问实体方式不同,指针需要显式解引用,引用编译器自己处理

int main()
{int a = 10;int* pa = &a;int& ra = a;cout << ra << endl;cout << *pa << endl;return 0;
}

在这里插入图片描述
9、引用比指针使用起来相对更安全,毕竟指针存在野指针,而不存在野引用。

http://www.yayakq.cn/news/368409/

相关文章:

  • 重庆新闻频道直播 今天自动优化网站建设电话
  • 深圳网站建设推广优化seowordpress h1 h2
  • 网站排名优化软件哪家好网站系统环境的搭建
  • 长沙市互联网加网站咖啡网站开发背景
  • 郑州网站开发公司名称大全网页游戏开服表时间表
  • 贵阳网站建设培训网站的页面布局是什么
  • 中学生做网站网店设计的重要性
  • 腾讯风铃怎么做网站上海网站建设优化公司
  • 网站主页制作海南省澄迈住房和城乡建设厅网站
  • 代理企业网站备案h5游戏中心
  • 中建八局土木建设有限公司网站商业网站设计欣赏
  • php 建设网站制作wordpress如何放pdf
  • 国外网站网站app彭州网站建设
  • 潍城区建设局网站在哪个网站做劳动用工备案
  • 网站后台附件无法上传唐山网站建设价格
  • 网站建设还能赚钱吗做网站优化竞价区别
  • 别人的抖音网站是怎么做的专业网站有哪些平台
  • 绍兴做网站鼎成学做网站快吗
  • 网站做链轮会被惩罚吗苏州网站推广服务
  • 高明网站设计哪家服务好速升网站
  • 网站建设公司怎么做建设网站制作公司如何选择
  • 能自己做的ppt网站昆明做网站报价
  • 尉氏做网站建筑网站大全豆丁网
  • 深圳网站开发ucreator怎么做公司网站优化
  • 翔安建设局网站wordpress 最新评论
  • 深圳外贸英文网站设计公司哪家好怎么把网站改为正在建设中
  • 重庆建网站价格表缅甸新闻最新消息
  • 有个蓝色章鱼做标志的网站洛阳青峰网络科技有限公司
  • 网站游戏入口快站登录
  • 建设网站需要的步骤wordpress 获取相关文章