C++内置类型指针间的转换(原创) - Visual C++/vc.net - 开发工具和...

来源:百度文库 编辑:神马文学网 时间:2024/05/25 08:25:59
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    
  例1 定义P1和P2如下(定义时不考虑是否必须初始化,以下例子同):  
  double *const**const P1;  
  double const*const** P2;  
  P2 = P1 ?  
  分析:  
  方法:对指针P1和P2从右至左将cv限定特征字写出,按相反方向排列,注意只写*前的,没有的用none标识。  
  按以上方法写出P1和P2的cv限定特征字:  
  P1的cv限定特征字: none const none  
  P2的cv限定特征字: none const const  
  按规则,Cv(1,3)和Cv(2,3)不同,则必须Cv(2,1)和Cv(2,2)为const,而P2的Cv(2,1)为none,转换失败。  
   
  例2 定义P1和P2如下:  
  char const**const P1[];  
  char const*const*const* P2;  
  P2 = P1 ?  
  分析:  
  按方法写出P1和P2的cv限定特征字:  
  P1的cv限定特征字: const none const  
  P2的cv限定特征字: const const const  
  按规则,Cv(1,2)和Cv(2,2)不同,则必须Cv(2,1)为const,P2符合要求,转换成功。  



参考资料:
[1]:C++程序设计陷阱,stephen c.dewhurst,陈君译