C++引用与指针基础

引用与指针基础

引用基础

本节探讨的引用为左值引用
引用为对象起了个别名,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。
其中引用必须初始化,因为定义引用时,程序把引用和它的初始值绑定到一起,而不是将初始值拷贝给引用,一旦初始化完成,引用将和它的初始值对象一直绑定到一起

int ival=1024;
int &refVal=ival;//refVal指向ival(是ival的另一个名字)
int &refVal2;//报错,引用必须初始化

因为引用本身不是对象,因此不能定义引用的引用。
允许在一条语句中定义多个引用。

int i= 1024,i2= 2048;//i和r2都是int
int &r= i,r2= i2;//r是一个引用,r2是int
int i3 =1024,&ri = i3;//i3是int,ri是引用
int &r3=i3,&r4=i2;//r3和r4都是引用

除两种例外情况,一种设计const的引用,一种涉及基类子类继承。

需要注意的是:

  • 不能建立引用的引用
  • 不能建立引用数组,也不能建立数组的引用
  • 可以建立指针的引用,但是不能建立引用的指针

一般情况下,所有引用的类型都要与绑定的对象严格匹配,而且,一般情况下引用只能绑定到对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

int &refval4=10;//错误,引用类型的初始值必须是一个对象
double dval =3.14;
int &refval55 =dval;//错误,此处引用必须是int型对象

//特殊情况
int i=42;
const int &r1=i;
const int &r2=42;//正确,特殊情况
const int &r3=r1*2;//正确,特殊情况

在C++中,引用主要用于定义函数参数和返回值类型,因为引用只需传递一个对象的地址,可提高效率。

指针基础

与引用类似,指针也实现了对其他对象的间接访问,然而指针和引用相比又有许多不同点。其一,指针本身就是一个对象,允许复制拷贝指针,而且指针的生命周期内它可以先后指向几个不同的对象
其二,指针无需在定义时赋初值。

指针存放某个对象的地址,要想获取该地址,需要使用取地址符(&),注意和引用处的&意义不同。
和引用类似,除两种特殊情况,指向常量的指针 和 基类子类问题
一般情况,所有指针的类型都要和他所指向的对象严格匹配

int *ip1,*1p2;//ip1和ip2都是指向int型对象的指针
double dp,*dp2;//dp2是指向double型对象的指针,dp是double型对象
double dval;
double *pd=&dval;//正确
double *pd2=pd;//正确
int *pi=pd;//错误,指针类型和对象类型不匹配
pi=&dval;//错误,不匹配

特殊情况一
double dval=3.14;
const double *cptr =&dval;//允许用指向常量指针指向一个非常量对象

如果指针指向了一个对象,则允许使用解引用符(*)来访问该对象

int ival=42;
int *p=&ival;//p是指向变量ival的指针
cout<<*p;//由符号*得到指针p所指的对象,输出42
*p=0;//由符号*得到指针p所指的对象,即可由p为变量ival赋值
cout<<*p;//输出0
空指针

不指向任何对象,在试图使用一个指针前代码可以首先检查他是否为空,以下列出几个生成空指针方法

int *p1=nullptr;//等价于int *p1=0;
int *p2=0;
//需要首先#include cstdlib
int *p3=NULL;
void* 指针

是一种特殊的指针类型,可用于存放任意对象的地址,利用void指针能做的事儿非常有限:拿它和别的指针比较,作为函数的输入或输出,或者赋给另外一个void指针。

指针支持的操作

对于两个类型相同的合法指针,可以用相等运算符(==)或 不等运算符(!=)来比较他们,比较的结果是布尔类型,如果两个指针存放的地址值相同,则他们相等;反之他们不相等,这里两个指针存放的地址值相同有三种可能:它们都为空、都指向同一个对象,或者都指向了同一个对象的下一个地址。需要注意,一个指针指向某对象,同时另一个指针指向另外对象的下一个地址,此时也有可能出现两个指针值相同的情况,即指针相等。 上述操作必须使用合法指针。

特别的,当指针指向数组时,vector和string的迭代器支持的运算,数组的指针全都支持为让指针的使用更加简单,更加安全,C++11标准引入了两个名为begin和end的函数,这两个函数与容器中的两个同名成员功能类似,不过数组不是类类型,这两个函数不是成员函数,所以正确的使用形式是把数组作为他们的参数;

int ia[]={0,1,2,3,4,5,6,7,8,9};
int *beg=begin(ia);//指向ia首元素的指针
int *last =end(ia);//指向ia尾元素的下一位置的指针

这两个函数定义在iterator头文件中,注意尾后指针不能执行解引用和递增操作
指向数组元素的指针可以执行迭代器所支持的运算,包括解引用,递增,比较,与整数相加,两个指针相减。 一个指针加上某整数值,结果仍是指针,新指针指向的元素与原来的指针相比前进了 该整数个位置,但如果计算所得的指针超出了范围就产生错误,

int arr[sz]={1,2,3,4,5};
int *ip=arr;//等价于int *ip=&arr[0]
int *ip2=ip+4;//ip2指向arr的尾元素arr[4]
int *ip3=arr+10;//错误,arr只有5个元素,p3的值未定义

和迭代器一样,两个指针相减的结果是它们之间的距离,类型是一种名为ptrdiff_t的标准库类型,和size_t一样,ptrdiff_t也是定义在cstddef头文件中的机器相关的类型
,因为差值可能为负,所以它是带符号类型

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值