C++基础——引用和指针的区别?

 从语法规则上说明:

指针变量存储的是某个实例(变量或对象)的地址;引用是某个实例的别名

int a=10;
int *ip=&a;//指针ip存储的是变量a的地址
int &ra=a;//ra是a的别名

程序为指针变量分配内存空间,但是不为引用分配内存区域。

在32位系统上,指针大小为4字节
在64位系统上,指针大小为8字节

解引用是指针使用时要在前面加“  *  ”,但是引用可以直接使用。

double a=12.23;
double *p=&a;
sizeof(p);//4字节
sizeof(*p);//8字节

指针变量的值可以发生改变(存储不同实例的地址),但是引用在定义时就被初始化,之后无法改变(不能是其他实例的引用)。

int a=10,b=20;
int *ip=&a;//ip指向a
ip=&b;//ip也可以指向b
int &ra=a;//ra一辈子都是a的别名

指针变量的值可以为空(指针可以指向NULL,nullptr),但是引用没有空引用

int *ip=nullptr;
int &rp=*ip;//引用不能为空,但是可以间接为空

指针变量作为形参时需要测试它的合法性(判空NULL),但是引用不需要判空。

void func(int *p)
{
    assert(p!=nullptr);//判空操作
}

void funb(int &p)
{
    ......
}

//引用要比指针安全,但是需要付出代价(能力收缩),不可以出现funb(nullptr)

对指针变量使用“sizeof”得到的是指针的大小,但是对引用变量使用“sizeof”得到的是变量的大小。

理论上指针的级数没有限制,但是引用只有一级。即不存在引用的引用的,但存在指针的指针。

char a=1;
char &ra=a;//ra为a的别名
char *cp=&a;//一级指针
char **ccp=&cp;//二级指针
sizeof(ccp);//4字节
sizeof(*ccp);//4字节
sizeof(*cp);//1字节
sizeof(ra);//1字节,引用要和类型保持一致

++引用与++指针变量的效果不同。对指针变量的操作:会使指针变量指向下一个实例(变量或者地址),而不是改变所指实例(对象或者对象)的内容;对引用的操作:直接作用于引用的实体。

int ar[]={1,2,3,4,5,6};
int *ip=&ar[0];
int &ra=ar[0];
++ip;//ip指向数组的下一个元素
++ra;//ar[0]+1

引用存在存在左值引用和右值引用之分,但是指针没有左值指针和右值指针之分。

int *ip;
int a=10;
int &ra=a;//左值引用
int &&rb=20;//右值引用
ip=&20;//err,指针不可以指向一个字面常量
ip=(int *)20;//此处可以强转,但是仍然不可以取地址

const int &cra=30;//常引用也可以引用一个字面常量

在使用模板时指针和引用有完全不同的表现形式:引用作为模板类可以得到实参的全部信息

template<class T>

void funa(T x)//以值接收,无法接收到这个地址有多少个整型元素
{
    cout<<sizeof(x)<<endl;//4字节
}

void funb(T &x)//只能接收一个左值引用,对于变量来说没有什么大的差别,但是对于数组来说,x将是数组ar的别名
{
    cout<<sizeof(x)<<endl;//24字节
}
int main()
{
    int ar[]={1,2,3,4,5,6};
    funa(ar);//ar退化成指针
    funb(ar);
    return 0;
}
//总结:引用作为模板类来说,可以得到实参的全部信息

只有引用具有的:在模板类中,引用型别未定义

template <class T>
void func(T &&x)//注意:此处不是右值引用!!!而是叫做引用型别未定义
{
    ......
}
int main()
{
    int ar[]={1,2,3,4,5};
    int a=10;
    const int b=20;
    func(a);//x为int &类型
    func(b);//x为const int &类型
    func(30);//x为int &&类型
    func(ar);//x为int[5] &类型
}

可以定义一个数组元素是指针,但是不能定义一个数组元素是引用。

int *ar[10];//ok
int &br[10];//err

在容器中可以放值类型,指针类型,但是不可以放值类型。

std::vector<int>ievc;//ok
std::vector<int *>pievc;//ok
std::vector<int &>prievc;//err

从引用的本质说明:

通过汇编层次理解,引用是一个常性的指针(自身为常性的指针,我是你的别名,我就一辈子只指向你)

int a =10;
int &ra =a;
int * const ra =&a;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值