C++ 左值引用与一级指针示例详解

 更新时间:2022年09月21日 08:31:42   作者:木三百川  
这篇文章主要介绍了C++ 左值引用与一级指针,本文给大家介绍了C++ (左值)引用和指针简介,结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

左值引用用于一级指针时,有以下几种用法:

//方式一:引用一级指针,常规用法
int a = 5;
int * pa = &a;
int * &rpa = pa;
 
//方式二:引用指向常量的一级指针,以下几种为等效表示
int a = 5;
const int * pa = &a;
const int * &rpac = pa; //方式一
int const * &rpac = pa; //方式二
 
//方式三:引用一级指针的常引用,引用自身为常量
int a = 5;
int * pa = &a;
int * const &crpa = pa;
 
//方式四:引用指向常量的一级指针,且引用自身为常量,以下几种为等效表示
int a = 5;
int * pa = &a;
const int * const &crpac = pa; //方式一
int const * const &crpac = pa; //方式二

在 Microsoft Visual Studio 中连续多个 const 会被编译器解释成一个,即 const const const const int *& 与 const int *& 等效,除此之外,const int const *& 在 Microsoft Visual Studio 中也与 const int *& 等效,而 int *& const 在 QT minGW 中将会报错,在 Microsoft Visual Studio 中与 int *& 等效。

各类型引用可修改属性如下表所示:

引用类型修改 *rp修改 rp
int * &rp可以可以
const int * &rp不可以可以
int * const &rp可以不可以
const int * const &rp不可以不可以

若将变量的地址赋予引用(例如 rp=&x),各类型引用可接受的变量地址如下表所示:

引用类型int变量地址const int变量地址
int * &rp不可以不可以
const int * &rp不可以不可以
int * const &rp声明时可以(将创建临时变量)不可以
const int * const &rp声明时可以(将创建临时变量)声明时可以(将创建临时变量)

若将一级指针变量赋予引用(例如 rp=p),各类型引用可接受的一级指针变量如下表所示。若赋值时等号右边是函数返回的临时指针变量(属于右值),则只有当等号左边为 int * const & 以及 const int * const & 类型时不会报错,此时必会创建临时变量(与 const 左值引用性质一致)。

引用类型int *变量const int *变量int * const变量const int * const变量
int * &rp可以不可以不可以不可以
const int * &rp不可以可以不可以不可以
int * const &rp声明时可以不可以声明时可以不可以
const int * const &rp声明时可以(将创建临时变量)声明时可以声明时可以(将创建临时变量)声明时可以

若将引用变量赋予引用(例如 rp=rp2),各类型引用可接受的引用变量如下表所示。比较上下两表可知,左值引用类型变量被初始化完毕后,若要将其赋值给另一引用变量,赋值时的表现与所引用类型的变量相一致。

引用类型int *&变量const int *&变量int * const&变量const int * const&变量
int * &rp可以不可以不可以不可以
const int * &rp不可以可以不可以不可以
int * const &rp声明时可以不可以声明时可以不可以
const int * const &rp声明时可以(将创建临时变量)声明时可以声明时可以(将创建临时变量)声明时可以

补充:C++ (左值)引用和指针简介

1. 引用

引用(reference):引用指向一个左值,并一直与指向的左值绑定(bind)在一起。用《C++ Primer》里面的话说,引用就是“给对象起了另外一个名字”

int ival = 1024;
int &refVal = ival; // refVal引用ival

引用必须被初始化:引用被声明后必须被立刻初始化,否则就会报错

int ival = 1024;
int &refVal = ival; // 顺利引用
int &refVal2;        // 报错,因为没有初始化

引用无法更改指向的左值:引用一旦经过初始化绑定后,就无法更改绑定的对象
引用不是对象:引用只是一个对象的别名,自身不是对象。你对引用的赋值,取值实际上等于对其引用的对象的赋值,取值

int ival = 1024;
int &refVal = ival;
refVal = 2;            // 等于对ival赋值
int ii = refVal;    // 等于将ival的值赋给ii

一个对象多个引用:这是允许的,一个对象可以拥有多个”别名“

int ival = 1024;
int &refVal = ival;
int &refVal2 = ival;    // refVal2作为ival的第二个引用

2. 指针

指针(Pointer):指针用于存储一个对象的地址,我们称为“指向”某个对象。通过指针,我们可以访问到对象在内存空间中的地址以及对象本身存储的值

int *p;    // 定义一个指针

2.1. 获取地址与访问对象

利用指针获取对象地址:由于指针本身是“存储地址的对象”,我们不能直接让指针存储对象本身,这时候就需要用取地址符(&)来提取对象的地址

int ival = 42;
int *p = &ival;        // 让指针p指向ival的地址

利用指针访问对象:直接访问指针的话,得到的是地址。要访问实际对象,就要用到解引用符(*)。解引用只适用于指向某个对象的有效指针

int ival = 42;
int *p = &ival;
int ival2;        // 新定义整数类型变量ival2
ival2 = *p;        // 将ival2赋值为p指向的值(也就是ival的值)

2.2. 指针的特殊状态

空指针(Null Pointer):一个值为0,不指向任何对象的指针

// 以下三行代码本质相同,都是初始化一个空指针
int *p1 = nullptr;    
int *p2 = 0;
int *p3 = NULL;

未初始化的指针:未指向任何地址,并且也不是空指针的指针是忌使用的。这样的指针由于指向的位置不确定,访问时有可能会造成未定义行为(Undefined Behaviour)。所以在定义指针时,一定要进行初始化,即便现在不会立刻使用,也要初始化为空指针

2.3 void* 指针

void类型:void被称之为“空类型”,它一般被用与没有返回值的函数上。
void*指针:一个void类型的指针同样能指向一块内存地址,但因为类型是空,我们没有办法知晓指向的类型,以至于不知道该类型占用的内存大小,因此无法访问指向的对象本身。

3. 引用和指针的复合使用

引用的引用:不合法。因为引用本身不是对象,所以无法使一个引用绑定另一个引用
引用的指针:不合法。因为引用本身不是对象,所以无法使一个指针指向一个引用
指针的引用:合法。指针本身是对象,引用可以绑定指针

int i = 42;
int *p = &i;
int *&r = p;    // r引用指针p

指针的指针:合法。指针本身是对象,指针可以指向指针

int i = 42;
int *p = &i;    // p指向i
int **p2 = &p;    // p2指向p

std::cout << **p2 << std::endl;    // 两次解引,输出“42”

到此这篇关于C++ 左值引用与一级指针的文章就介绍到这了,更多相关C++ 左值引用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言实现万年历源码

    C语言实现万年历源码

    这篇文章主要为大家详细介绍了C语言实现万年历源码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • C++实现四叉树效果(附源码下载)

    C++实现四叉树效果(附源码下载)

    这篇文章主要介绍了C++实现四叉树效果(附源码下载),非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • C++ LARGE_INTEGER解析与使用案例详解

    C++ LARGE_INTEGER解析与使用案例详解

    这篇文章主要介绍了C++ LARGE_INTEGER解析与使用案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 如何编译libfreetype方法详解

    如何编译libfreetype方法详解

    libfreetype是为跨平台设计的,在windows下要编译的话,可以直接打开目录进行编译,本文将详细介绍libfreetype编译
    2012-11-11
  • C语言深入探索之单链表与typedef的用法

    C语言深入探索之单链表与typedef的用法

    typedef为C语言的关键字,作用是为一种数据类型定义一个新名字,单链表是后面要学的双链表以及循环链表的基础,要想继续深入了解数据结构以及C语言,我们就要奠定好这块基石!接下来就和我一起学习吧
    2022-05-05
  • windows消息和消息队列实例详解

    windows消息和消息队列实例详解

    这篇文章主要介绍了windows消息和消息队列实例详解,详细讲述了Windows的消息机制与原理,对于深入理解和学习Windows应用程序设计有不错的借鉴价值,需要的朋友可以参考下
    2014-10-10
  • 详解c++优先队列priority_queue的用法

    详解c++优先队列priority_queue的用法

    本文详细讲解了c++优先队列priority_queue的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C语言实现控制台版贪吃蛇游戏

    C语言实现控制台版贪吃蛇游戏

    这篇文章主要为大家详细介绍了c语言贪吃蛇控制台版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C++实现动态烟花效果

    C++实现动态烟花效果

    这篇文章主要介绍了利用C++实现的放烟花程序,用到了EGE图形库,文中的示例代码讲解详细,对我们学习C++有一定帮助,需要的可以参考一下
    2022-01-01
  • c++ 面向对象的类设计

    c++ 面向对象的类设计

    类的设计在于用恰到好处的信息来完整表达一个职责清晰的概念,恰到好处的意思是不多也不少,少了,就概念就不完整;多了,就显得冗余,累赘,当然特例下,允许少许的重复,但是,这里必须要有很好的理由
    2017-07-07

最新评论