指针间的转换

指针间的转换是众多初识C++者深感迷惑的难点之一。他们困惑的原因则是认为这种转换没有规律可循,加之类型繁复,理不清头绪实属无奈,但也情有可原。其实问题较为棘手,但规律是依然可循的。在这里我总结出来,希望在大家学习C++时有所助益。如有不确之处,敬请指正。 (一)一级指针间的转换 一级指针若只有const限定(不考虑volatile的限定),不外乎四种类型:T*,T*const,const T*,const T* const,其中T为类型。下面先阐述后三种含const指针的要点,再举例解析四种指针之间的转换规则。 (1)T* const pt2 = pv2; pt2一般称为常量指针,一经指定为pv2后便不能再指向其他,由此可见pt2在定义时必须初始化,再给pt2赋值也就非法了。 (2)const T* pt3 = pv3; pt3称为指向常量的指针,不能通过pt3修改其指向的变量或对象,即对*pt3赋值是非法的,但可以对pt3再赋值,使其指向其他变量或对象。显然pt3定义时不须初始化。 (3)const T* const pt4 = pv4; pt4称为指向常量的常量指针,pt4一经指定为pv4则不能指向其他,这样在定义pt4时也须初始化,再对pt4赋值非法,对*pt4赋值也非法。 总结: 以上的限定是对“指针使用时”的限定,而不是对pv2/3/4的限定,我们可以肆无忌惮(or毫无顾及)地修改pv2/3/4或*pv2/3/4,若它们是可以修改的。 先定义如下变量,下面的例子都要用到这些变量: int i = 1; const int a = 2; int va[] = {1,2,3}; int vb[] = {4,5,6,7}; int* p[2] = {va,vb}; const int* p0[2] = {va,vb}; int* const p1[2] = {va,vb}; const int* const p2[2] = {va,vb}; (i)其他类型转换为T* 1)int* pt11 = &i;//ok 2)int* pt12 = &a;//error 3)int* pt13 = va;//ok 4)int* pt14 = p[0];//ok 5)int* pt15 = p;//error 6)int* pt16 = p0[0];//error 7)int* pt17 = p0;//error 8)int* pt18 = p1[0];//ok 9)int* pt19 = p1;//error 10)int* pt110 = p2[0];//error 11)int* pt111 = p2;//error (ii)其他类型转换为T* const 1)int* const pt21 = &i;//ok 2)int* const pt22 = &a;//error 3)int* const pt23 = va;//ok 4)int* const pt24 = p[0];//ok 5)int* const pt25 = p;//error 6)int* const pt26 = p0[0];//error 7)int* const pt27 = p0;//error 8)int* const pt28 = p1[0];//ok 9)int* const pt29 = p1;//error 10)int* const pt210 = p2[0];//error 11)int* const pt211 = p2;//error (iii)其他类型转换为const T* 1)const int* pt31 = &i;//ok 2)const int* pt32 = &a;//ok 3)const int* pt33 = va;//ok 4)const int* pt34 = p[0];//ok 5)const int* pt35 = p;//error 6)const int* pt36 = p0[0];//ok 7)const int* pt37 = p0;//error 8)const int* pt38 = p1[0];//ok 9)const int* pt39 = p1;//error 10)const int* pt310 = p2[0];//ok 11)const int* pt311 = p2;//error (iv)其他类型转换为const T* const 1)const int* const pt41 = &i;//ok 2)const int* const pt42 = &a;//ok 3)const int* const pt43 = va;//ok 4)const int* const pt44 = p[0];//ok 5)const int* const pt45 = p;//error 6)const int* const pt46 = p0[0];//ok 7)const int* const pt47 = p0;//error 8)const int* const pt48 = p1[0];//ok 9)const int* const pt49 = p1;//error 10)const int* const pt410 = p2[0];//ok 11)const int* const pt411 = p2;//error 举了这么多的例子,都只给出了答案,具体分析看下面。 先说明几点: (a)我们将变量和符号常量的地址也当作一个指针。它们的类型按如下定义给出: 若类型为T,则其地址看作类型为T*的指针。 如const int a = 2;则&a可以看作const int*指针。 (b)注意数组和指针之间的转换关系。 如const int a[] = {1,2};则a,a+1可以看作const int*指针。 具体分析: [1]以上例子(i)~(iv)中的5)7)9)11)都为error,这不是巧合,而是:二级指针转换为一级指针是不允许的。指针间的转换只能在同级之间进行。 [2]前两个例子的答案一致,后两个例子的答案也一致。他们之间能转换的自由度是相同的。并有如下规律:L(pt1)= L(pt2)< L(pt3)= L(pt4) [3]鉴别转换是否成功的方法: 只要比较*pt1/2/3/4和*pv1/2/3/4的可修改性,只要前者可修改,而后者不可修改,则转换不成功。 举个例子:int* const pt210 = p2[0];//error*pt210为int类型可以修改,而*p2[0]为const int不可修改,转换失败。 (二)多级指针间的转换 多级指针的转换更有规则可循。 设 P1是指向Cv(1,n)的Cv(1,n-1)指针的...的Cv(1,1)指针的Cv(1,0)指针; P2是指向Cv(2,n)的Cv(2,n-1)指针的...的Cv(2,1)指针的Cv(2,0)指针。 这里Cv(i,j)(其中i=1,2,0<= j <=n)为const或none(表示没有const限定)。 对特定的i,Cv(i,j)(其中0< j <=n)称为指针的cv限定特征字。 对P1和P2,若基类型相同且n取值相同,则说它们是相似指针。即含*的个数相同,基类型相同。 转换规则: P1能够转换为P2,若满足以下条件: <1>P1和P2是相似指针; <2>对每个j > 0,P1和P2的cv限定特征字相同; <3>若Cv(1,j)和Cv(2,j)不同,对0< k
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值