1、指针类型转换请使用static_castdynamic_cast等操作
2、指针变量(不管那种指针),大小都是四个字节,内容就是指向的对象的首地址。不同类型指针不同点就是对首地址之后的那块内存会做不同解释。
建议你看看《Inside  C++  Object  Model》里面关于指针的内容,里面有清晰的说明

int  *  pi  =  new  int;
pi  指向了一块内存的首地址,这块内存应该有sizeof(int)个字节,
由于piint  *类型,所以通过pi进行的操作,编译器都认为pi的内容是一个有sizeof(int)个字节的int型变量的首地址,所以*pi  =  4,遇到这样的操作,编译器产生的代码就是把4这个数付到pi所指的四个字节里。
char  *  pc  =  (char  *)pc;  //建议这样写char  *  pc  =  static_cast <char  *> (pc);
*pc  =  '4 ';
由于pcchar  *类型,所以通过pc进行的操作,编译器都认为pc的内容是一个有sizeof(char)个字节的char型变量的首地址,所以*pc  =  '4 ',遇到这样的操作,编译器产生的代码就是把4这个字符付到pc所指的第一个字节里。虽然,pc实际指向的是int型的变量,有4个字节。
改变指针的类型,解引用操作的时候会影响到所指向的地址内容(类型所占的字节数可能不同,还有高位是符号位或是数据位)解析,不会发生数据丢失
未必!设想下面三个类:
class  A
{
public:
int  m_nA;
A():m_nA(1){}
public:
A*  GetA(){  return  this;  }
};

class  B
{
public:
int  m_nB;
B():m_nB(2){}
};

class  C  :  public  A,  public  B
{
public:
int  m_nC;
C():m_nC(3){}
};

int  main()
{
C  *c  =  new  C;
此处调试察看c指向的内存空间,假设以c的指向为基点,其后的地址以偏移记
那么整个c所指向的对象在内存中的排列如下:
(0)四个字节的m_nA  (4)四个字节的m_nB  (8)四个字节的m_nC  (12)......
这里只关心最前面的12个字节,再看:

A  *a  =  c-> GetA();
此处察看a,和c一样,它也指向上面的(0)处。这没有问题,通过它来访问
m_nA会得到1,完全正确。再看:

B  *b  =  (B*)a;
此处得到的ba的指向完全一样,通过它来访问m_nB得到的值是不正确的。不
过,如果通过它来访问B的非虚的成员函数,可以得到正确的结果。
这里的强制转换仅仅是改变了指针的类型。看下面最关键的:

b  =  (C*)a;
b居然指向了(4)处,这句代码居然得到了正确的地址!也就是说,这里的强制
转换不仅改变了指针的类型,同时也改变了指针的值。为什么?
return  1;
}
把指向派生类的指针,转换为不是第一个基类的指针时,必须要对其地址做出改变
这样才可以使派生类指向该基类,这点inside  the  c++  object  model书上讲了的
关于这里:
B  *b  =  (B*)a;
此处得到的ba的指向完全一样,通过它来访问m_nB得到的值是不正确的。不过,如果通过它来访问B的非虚的成员函数,可以得到正确的结果。
这里的强制转换仅仅是改变了指针的类型
由于a是个指向类型A的指针,这种转换就和派生类毫无关系,仅是将一个类的指针
转换为指向另一个类(相当于这两个类没有任何联系,实际上A,B之间是毫无联系的)
并不像这样
b  =  (C*)a;a转换为C的指针后,bc有了基类和派生类的关系
#include <stdio.h>
int main(void)
sizeof 指针{
    unsigned int a = 0xfffffff7;
    unsigned char i = (unsigned char)a;
    char * b = (char *)&a;
    printf("%08x\n%08x\n", i, *b);
    return 0;
}
i  = 000000f7
*b = fffffff7
问题就是关于*b的,b是一个指向char型的指针,将&a解释成(char*)的类型,从而*b也就是a的最高位的那个字节,所以我感觉*b结果应该是0x000000ff,那里错了?
char * b = (char *)&a;
是将a的地址转换成 char *类型 ,实际上就是 b存放 a这个变量的地址 。也就是说 b指向了 a所以对b进行解引用得到的 就是 a
因为你用的是x86 CPU,将整形的高字节放在地地址处,也就字节顺序从高到低,地址从低到高顺序0xfffffff7
1little-endian的话,*b指向的是最低的那个字节也就是f7,这个上面已经说过了;
2)我想补充的是,即使指向的是高位字节,你的输出也不是0x000000ff,而是全f,符号位扩展的原因
char相当有符号的整数,所以打印fffffff7.


如果是:

unsigned char * b = (unsigned char *)&a;


那么也打印000000f7
其实b指向的就是最后一个字节f7,而char是有符号的,高位用ff补齐,而unsigned是无符号的,就直接打印一个字节的内容,高字节就用0补齐

#include <stdio.h>

int main(void)
{
  unsigned int a = 0xfffffff7;
  unsigned char i = (unsigned char)a;
  char * b = (char *)&a;
  unsigned char * c = (char *)&a;
  int d = *b;
int e = *c;
  printf("%08x\n%08x %08x %d %d\n", i, *b, *c, d,e);



  return 0;
}

打印结果:
000000f7
fffffff7 000000f7 -9 247
我们用2进制来写这些数字,并且参考6楼,增加一个unsigned char的指针或者数字。
为了书写方便,我这里都直接取数了,不进行指针操作。
unsigned int a = 1111 1111 1111 1111 1111 1111 1111 0111
因为a是无符号型,所以最高位的1是表示263次方。
unsigned char i = 1111 0111
char b = 1111 0111
unsigned char c = 1111 0111
注意b的最高位的1,并不是表示27次方,而是表示b是负数。
所以查看他们的值,会发现,b-9.利用补码加1,可以算出确实是-9ci都是247,也可以算出来。
所以intchar 的强制转换,不管是不是无符号型,肯定是截取了低16位。
什么呢?因为c/c++标准规定char类型可以是signed char,也可以是unsigned char,这就是实现相关。编译器可以自行选择其中一种,一般情况下编译器会

提供选项让用户选择。你所得到的结果,是因为你当前编译环境设定charsigned char而得到的。

由于*bsigned char,在作为参数传入printf之前,*b被自动提升为int,这是一个到signed int的转换,标准规定在这种情况下,如果*b的值能被signed 

int 表示,那么值不变,*b的值为f7,在signed char里表示-9,那么转换为signed int后它也应该保持-9这个值,-9在四字节signed int里面就是

fffffff7,因此才有*b = fffffff7的结果,事实上,这里从f7fffffff7的转换就叫做符号扩展。

如果编译器设定charunsigned char,情况就与i相同了,无符号f7值是247,转换为signed int后应该依然还是247,因此就是000000f7了。
实际上这些类型最终都是有最基本的几个类型定义的,
所以有一些类型之间只是名称不同,内涵是一致的,
指针类型是C的最强大的内容,只要转换成相应的类型指针,
就能按照目标类型来读写指针指向的空间,而不用理会它原来是什么类型

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。