您现在的位置是:首页 > 正文

引用和指针那些事

2024-04-01 00:55:48阅读 0
  • 对一个数据建立一个“引用”,其作用是为一个已经定义的变量起一个别名
  • 【1】引用的格式
    类型& 引用的变量名(别名)=定义过的变量名
    比如有一个变量a,想给他起一个别名:
int a=10;   //定义一个变量a
int& b=a;   //声明b是a的引用
cout<<a<<endl;  //10
cout<<b<<endl;  //10

以上声明了b是a的别名,有了这样的声明后,使用a或b的作用相同,都代表同一个变量,改变其中一个的值,另一个也会随之改变。&是引用声明符,并不代表地址,切记不能理解为“把a的地址赋给b的地址”,在数据类型后面出现的&是引用声明符,其他场合出现的&都是地址符。声明了引用后,使用它时不用带&,而只是引用的名字(如b,而不是&b)

int& d=c;   //此处的&是引用符,声明b是c的别名
int *p=&c;  //此处的&是地址符
  • 【2】引用的特点:
    1.引用不是一种独立的数据类型,对引用只有声明,没有定义
    2.声明一个引用时,必须对其初始化,即声明它是哪一个变量
    3.一个变量可以起多个别名
    4.在声明一个引用后,不能使之作为另一变量的引用
int a1,a2;
int& b=a1;  //声明b是a1的引用
int& b=a2;  //试图使b又成为a2的引用(别名),不合法
  • 【3】引用和const
    权限可以缩小,但不能放大
const int a=10;
int& b=a;   //不合法,试图给const类型的变量起别名,常量具有常性,倘若别名b修改了数据,b和a等价,那么const类型就被修改掉了
const int& c=a; //合法,常引用可以引用常量
int a=10;
const int& b=a; //合法
double d=3.14;
int i=d;    //隐式的类型转换,生成临时变量,具有常性
int& c=d;   //不合法,double型转为int型,生成临时变量,而临时变量具有常性,用低权限访问高权限
const int& C=d; //合法
  • 【4】引用作为函数参数
    1.值传递
void Swap(int a,int b)
{
    int tmp=a;
    a=b;
    b=tmp;
}

值传递并不能改变实参的值,a和b仅仅是形参,试图用形参改变实参实现数据的交换,不可能,改变上述问题,采用指针传递
2.指针传递

void Swap(int* a,int* b)
{
    int tmp=*a;
    *a=*b;
    *b=tmp;
}

调用函数时,将a和b的地址传给形参,实现数据的交换
3.引用传递(形参为引用类型)

void Swap(int& a,int& b)
{
    int tmp=a;
    a=b;
    b=tmp;
}

形参a和b是实参的引用,实参不是地址而是变量名,由于形参是引用,编译器会自动将实参的地址传给形参
用引用形参的方法比使用指针形参的方法简单、直观、方便,可以减小程序设计的难度。

  • 【5】引用做返回值
//1
int Func1(int a)
{
    return a*a;
}
//2
int& Func2(int a)
{
    return a*a;
}
int main()
{
    int a=Func1(3);//9
    int& b=Func1(3);//error
    int c=FUnc2(3);//9
    int& d=FUnc2(3);//9
    return 0;
}
  1. 第一种情况:
    一般的函数返回值方式,没啥可说的,函数返回结果时,C++创建临时变量,将结果赋值给临时变量(临时变量具有常性),返回main函数后,将临时变量的值赋给a。

  2. 第二种情况:
    函数依然返回结果,创建临时变量,赋值给临时变量,但是接收值b是int&,将临时变量赋值给引用类型,临时变量作用域短暂,b面临无效的危险,在int& b=FUnc1(3)后,临时变量将不再存在,所以引用b以后的值是个无法确定的值,error.
    可以将b声明为const类型解决,或者先创建一个变量,将函数结果赋给变量,再将变量初始化引用。

  3. 第三种情况:
    函数返回值是引用类型,将函数结果返回给main函数,赋值语句的左值直接得到赋值,避免了临时变量的产生,

  4. 第四种情况:
    函数返回一个引用,在主函数中,一个引用声明d用该返回值来初始化

    结论:
    1.不能返回一个临时变量的引用
    2.如果返回对象出了当前函数的作用域依旧存在,则最好使用引用返回,因为这样更高效

    -【6】 引用的性质:
    如果在程序中声明了b是变量a的引用,实际上在内存中为b开辟了一个指针型的存储单元,在其中存放变量a的地址,输出引用b时,就输出了b所指向的变量a的值,相当于输出了*b。引用其实就是一个指针变量,但他的指向不能改变,不想指针那样灵活,引用只能指向一个变量,所以引用的本质还是指针,所有引用的功能都可以用指针来实现,C++增进引用,是为了方便用户,用户不必具体去操作变量地址,而把引用当做变量的“别名”来使用,更直观,难度更小。

    -【7】引用和指针的关系:
    1.引用只能在声明时初始化一次,之后不能指向其他变量,而指针可以
    2.引用必须指向有效的变量,而指针可以指向空
    3.sizeof(指针)得到对象地址的大小,sizeof(引用)得到所指向变量的大小
    4.指针的++ –和引用不一样,引用就是单纯的加一减一
    5.引用比指针安全
    6.指针比引用灵活,但是使用指针时要检查是否为空,指针指向的地址释放后要置为0,避免野指针

网站文章

  • 万事开头难? 喵小DI玩“羊了个羊”可不难

    万事开头难? 喵小DI玩“羊了个羊”可不难

    DI-sheep 版 羊了个羊

    2024-04-01 00:55:42
  • UML的学习专题

    根据大神的博客,进行学习UML-统一建模语言

    2024-04-01 00:55:18
  • Django 路径

    django BASE_DIRimport osBASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) PROJEC...

    2024-04-01 00:55:09
  • 【Springboot】springboot中使用mybatis操作数据库

    【Springboot】springboot中使用mybatis操作数据库

    新建springboot项目的时候,选择好web,mybatis,JDBC在application.properties或者application.yml中配置spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:33...

    2024-04-01 00:55:02
  • 静态连接(dynamic link)和动态连接(static link)初步理解

    前两天配置QT和VTK环境,焦头烂额啊,第一次配置个环境配置这么费劲的,这俩工具都不是微软出的开发库,需要自己编译,编译时间那个长。。。3,4个小时啊,等的花都谢了,好不容易编译好了,又出现了各种问题。 首先,早就听说过这两个库是跨平台的,当时觉得好牛逼啊,作为一个鄙视wind

    2024-04-01 00:54:37
  • mediawiki 详细安装

    1、首先在http://sourceforge.net/projects/wampserver/files/WampServer%202/WampServer%202.2/下载2.2版本,http://sourceforge.net/projects/wampserver/files/WampServer%202/是各个版本的安装文件。根据自己的系统确定安装32位的还是64位的 2、双击进行安装

    2024-04-01 00:54:29
  • 42. Trapping Rain Water 计算储水量

    给定一个数组, 表示高度,计算存水量。例子:Input: [0,1,0,2,1,0,1,3,2,1,2,1]Output: 6方法1:动态规划int trap(vector<int>& height) { if (height.empty()) { return 0; } int n = height.size(); int lef...

    2024-04-01 00:54:22
  • 从订单信息页面进入订单详细商品页面,最简单的MVC思想

    从订单信息页面进入订单详细商品页面,最简单的MVC思想

    前言习惯上图,看流程图把,下面是具体实现以后的一个流程图。步骤- (1)点击订单详情,进入订单详情列表,展示订单的一下基本信息,在上图框内,可随机输入查询信息,查询具体订单信息。(2)点击订单商品详情,进入具体订单,图中进入订单编号1的商品页面,可以看到具体商品信息,从数据库我们建立一张表,关联订单跟具体商品的关系。正文直接上代码吧,简单粗暴,因为之前有

    2024-04-01 00:53:58
  • 使用C/C++实现Java的Native方法接口(JNI)(4)JNI数据类型

    在Java程序中使用native接口(JNI)调用外部的使用C/C++实现的函数

    2024-04-01 00:53:45
  • python学习笔记

    argparse模块1.使用步骤:(1)import argparse 首先导入模块(2)parser = argparse.ArgumentParser() 创建一个解析对象(3)parser.ad...

    2024-04-01 00:53:34