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,陈君译
几年前写的一篇文章,现在把它贴在这里,供大家看看。
分一级和多级指针分别阐述。
(一)一级指针间的转换
一级指针若只有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,陈君译
C++内置类型指针间的转换(原创) - Visual C++/vc.net - 开发工具和...
C类型转换
Ren-Huang‘s Blog | [C ]Visual C 的.NET Socket
如何利用VC的Remote Debug功能-Visual C
iso9660文件格式 VC/MFC / Visual C 资源
windows编程通用的win32类型和常见的结构 [vc/c#]
Visual C .NET编程讲座之五
Visual C .NET编程讲座之六
Visual C .NET编程讲座之七
Visual C .NET编程讲座之八
防止对 Visual Basic .NET 或 C
Visual C .NET编程讲座之五
Visual C .NET编程讲座之(七)
C++、VC++、MFC的区别和联系
如何理解c和c ++的复杂类型声明
VC中BSTR、Char和CString类型的转换
VC中BSTR、Char和CString类型的转换
关于指针强制类型转换的思考
指针类型转换
C语言中强制类型转换总结
C语言中强制类型转换总结
彻底搞定C指针---指向指针的指针(转)
c/c++中函数指针的含义 [c/c++]---01
指针数组和数组指针 - 酸菜猪蹄的程序人生 - C 博客