引用、指针、数组

本文详细探讨了C++中引用和指针的区别,引用的初始化要求,以及数组操作中的隐式退化和指针类型转换。还讨论了左值引用和右值引用的概念,强调了常量引用来避免修改const变量的错误用法。
摘要由CSDN通过智能技术生成

引用,指针,数组名

1.引用和指针

-引用指针
定义上定义时必须初始化且后续不能更改。引用只有一级可以先定义,后面用到了再初始化。后续可以指向其他变量,指针可以有多级
值上引用必须绑定到一个具体的、已经存在的对象上。(因此不能用退化的临时变量来初始化,见后文引用数组)指针没有太多限制,会导致安全问题
空状态引用必须引用一个具体的对象,不能是空指针可以是空
操作上引用就像普通变量,不需要特殊语法必须使用解地址符来访问其数据

引用的底层实现是指针(VS2022):因此引用需要用左值进行初始化
int &p=30;是不可以的

    int a = 10;
00007FF7A2571AAD  mov         dword ptr [a],0Ah  

    int* p = &a;
00007FF7A2571AB4  lea         rax,[a]  
00007FF7A2571AB8  mov         qword ptr [p],rax  

    //下面引用的实现,在编译器用指针进行实现
    int& b = a;
00007FF7A2571ABC  lea         rax,[a]  
00007FF7A2571AC0  mov         qword ptr [b],rax  

    *p = 20;
00007FF7A2571AC4  mov         rax,qword ptr [p]  
00007FF7A2571AC8  mov         dword ptr [rax],14h  
    b = 30;
00007FF7A2571ACE  mov         rax,qword ptr [b]  
00007FF7A2571AD2  mov         dword ptr [rax],1Eh  

2.数组

2.1 arr和&arr

arr&arr
第一个元素的地址第一个元素的地址
类型上在大多数情况下(除去sizeof、&)会被隐式退化成指向第一个元素的指针。是指向整个数组的指针。
类型为int(*)[5],
操作上arr+1会移动到下一个元素的位置(即向前移动int大小)&arr+1会移动到整个数组以外的下一个位置(即移动sizeof(int)*5的大小)。因为&arr是指向整个数组的指针。
sizeof函数不会退化为指向第一个元素,因此返回整个数组大小返回指针大小
&操作符不会退化。返回的是指向整个数组的指针-
int arr[5]={1,2,3,4,5}
cout << arr << endl;                    //000000F1824FFBA8
cout << typeid(arr).name() << endl;     //int [5]
cout << sizeof(arr) << endl;            //20

cout << &arr << endl;                   //000000F1824FFBA8
cout << typeid(&arr).name() << endl;    //int (* __ptr64)[5]
cout << sizeof(&arr) << endl;           //8

2.2 引用数组

int arr[5] = {1,2,3,4,5};
int* &p = arr; // 这行是错误的
int(&p2)[5] = arr; // 这行是正确的

解释错误:

声明要求 p 必须初始化为绑定到一个已存在的 int* 类型的指针上。然而,在示例中,arr 是一个数组类型,不是一个指针类型,尽管它在表达式中会退化为指向其第一个元素的指针(即 int*)。但这种退化产生的是一个临时的指针值,不是一个可以持久绑定的指针变量。
因此,尝试将 arr 直接赋值给 int* &p 是非法的,因为这相当于试图让引用绑定到一个临时产生的右值上。

正确的使用int *&p:

int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;  // ptr 是一个指针,指向 arr 的第一个元素
int* &p = ptr;   // p 现在是对 ptr 的引用

3.左值引用和右值引用

思考

int a=10;
int*p = &a;
const int *&q=p;

问代码可不可以?

int a=10;
int*p = &a;
const int *&q=p;//假设可以
const int b=99;
q=&b;
*p = 33;

如果const int *&q=p;执行成功。那么qp就是等价的了,执行完q=&b;以后,q(p)指向了一个const变量,那么我后续可以通过p(int *)来修改一个const 变量。
因此这种做法是错误的。

对于指针的引用如何判断是否可以?
方法:把引用改成指针
const int *&q=p; --> const int **&*q=*p
上文中,我们知道int**不能直接赋值给const int **因此,这种方法是错误的

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值