引用不单单是取别名,还有更大的用处

8 篇文章 0 订阅

目录

  • 什么是引用
  • 左值和右值
  • 左值引用
  • 指针和引用的区别

什么是引用?

引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作是完全等价,引用(reference)是c++对c语言的重要扩充。

引用在使用时,有几个要注意的地方:

1、&不是求地址运算符,而是起到标志作用。
2、引用的类型和绑定的变量类型必须相同(指针也一样)
3、声明引用的同时,必须对其进行初始化,因此内存不会为引用开辟新的空间存储这个引用 。
4、声明引用的同时,必须对其进行初始化,否则报错。
5、不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立以一个数组的别名。
6、引用只能在初始化的时候引用一次,不能更改转为引用其他变量。

指针交换数据:

//C语言数据交换
#include<stdio.h>

void chang_num(int* a,int* b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
int main()
{
  int a=1;
  int b=9;
  printf("before:a=%d,b=%d\n",a,b);
  chang_num(&a,&b);
  printf("after:a=%d,b=%d\n",a,b);
    return 0;
}

基本引用交换数据:

//C++
#include <iostream>
using namespace std;
void chang_num(int &a,int &b)//参数 做引用
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}
int main()
{
  int a=1;
  int b=9;
  cout<<"before:a="<<a<<",b="<<b<<endl;
  chang_num(a,b);
  cout<<"after:a="<<a<<",b="<<b<<endl;
    return 0;
}

左值和右值

C++的表达式要么是左值lvalue,要么是右值rvalue,这两个名词是C语言继承过来。左值可以出现在赋值语句(=)的左侧和右侧,右值只能出现在右侧

不能简单的以等号的左右来判断是否是左值还是右值。判断是否是左值,有一个简单的方法,就是看看能否取它的地址能取地址的就是左值。使用排除法,其他的即为右值。左值一般就是对象、变量,右值一般是普通的数据(实实在在的数据)、运算表达式、函数的返回值。

#include <iostream>
using namespace std;
//只能把左值赋值给引用,不能把右值赋给引用
int square(int &n){
    return n*n;
}

int main()
{
  int x=100;
  x=1000+2;
  int b = 10;
  b = x;
  
  int num=10;
  square(num);
  square(5)//错误,因为5是右值
    return 0;
}

左值引用

平常说的引用,实际上指的就是左值引用lvalue reference,常用单个&来表示。左值引用只能接收左值,不能接收右值。const关键字会让左值引用变得不同,它可以接收右值。为了支持移动操作,在C++版本,增加了右值引用。右值引用一般用于绑定到一个即将销毁的对象,所以右值引用又通常出现在构造函数中。左值具有持久的状态,有独立的内存空间,右值要么是字面常量,要么就是表达式求值工程中创建的临时对象,返回值。常用单个&来表示。

void reference_function(){
  int i = 0;
  int &l_value = i;//左引用
  l_value = 1;
  const int &l_value1 = i;//变为常量,数值不可变
  l_value1 = 2;//出错,常量不可变
  /*const关键字会让左值引用变得不同,它可以接收右值*/
  const int &l_value2 = 3;//右值引用 特殊之处 可以接收右值
  
  float l_value3 = 1.1;
  int &l_value4 = l_value3 ;//出错,类型不对应
  
  const int &l_value5 = l_value3;//接收常量 l_value5 = 1;
  
}

指针和引用的区别

1、两者自增自减的意义不一样,一个地址变化,另一个数值变化。

2、引用不能为空,指针可以为空。

3、sizeof的大小不一样,一个是变量的内存大小,一个是指针的内存大小

4、指针是一个实体,而引用仅是个别名。

5、引用使用时无需解引用,指针需要解引用(*)。

6、引用只能在定义时初始化一次,之后不能改变指向其它变量。指针变量可以变。

为什么使用引用

一般引用主要用在函数传参,相比值传递,值传递需要花费额外时间拷贝实参副本,而引用可以节省内存空间和时间,特别是函数调用时在内存不会生成副本,只是将变量改名,对引用操作就是对目标变量操作。如果参数是一个对象或者空间比较大的结构体变量,使用引用将很好提高程序运行效率,通过使用const关键字,可以实现引用传递的安全性
以下是各函数调用的运行时间:

#include <sys/time.h>
#include <iostream>
using namespace std;
class Car{
          int length;
          int width, height;
          int number[100];
    public:
          int getlength() { return length; }
};
void function(Car &a){
}
void function1(Car a){}
Car car;
Car &function2(){
    return car;
}
Car function3(){
    return car;
}
int main(int argc, const char** argv) 
{
    struct timeval start, end;
    unsigned long timer;
    Car a,b;
    int num = 0;
    //使用引用
    gettimeofday(&start, NULL);
    num = 10000;
    while(num--)
    function(a);
    gettimeofday(&end, NULL);
    timer = 1000000*(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);
    cout<<"引用传参时间开销:"<<endl;
    cout<<"function(CAR& ) = "<<timer<<" us"<<endl;

    //普通值传递
    struct timeval start1, end1;
    gettimeofday(&start1, NULL);
    num = 10000;
    while(num--)
    function1(a);
    gettimeofday(&end1, NULL);
    timer = 1000000*(end1.tv_sec - start1.tv_sec) + (end1.tv_usec - start1.tv_usec);
    cout<<"值传参时间开销:"<<endl;
    cout<<"function1(CAR ) = "<<timer<<" us"<<endl;

    //引用 返回
    struct timeval start2, end2;
    gettimeofday(&start2, NULL);
    num = 10000;
    while(num--)
    function2();
    gettimeofday(&end2, NULL);
    timer = 1000000*(end2.tv_sec - start2.tv_sec) + (end2.tv_usec - start2.tv_usec);
    cout<<"引用返回时间开销:"<<endl;
    cout<<"Car &function2() = "<<timer<<" us"<<endl;

    //值返回
    struct timeval start3, end3;
    gettimeofday(&start3, NULL);
    num = 10000;
    while(num--)
    function3();
    gettimeofday(&end3, NULL);
    timer = 1000000*(end3.tv_sec - start3.tv_sec) + (end3.tv_usec - start3.tv_usec);
    cout<<"值返回时间开销:"<<endl;
    cout<<"Car function3() = "<<timer<<" us"<<endl;
    return 0;
}

输出结果:

以上是结果,都是经过我测试验证成功,如有疑问,请麻烦联系我。我是小昭!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小昭dedug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值