原创 令人头晕的指针

2008-12-5 22:24 3744 6 6 分类: 软件与OS
某种类型名   *)另一种类型指针变量名:
这个只是转换了指针类型。

*(某种类型名*)&另一种类型指针变量名    
这个将   另一种类型指针的指针(地址)   转换成了   某种类型指针,然后前面的*解引用,
就相当于是吧   “另一种类型指针”给转换成了   某种类型,注意不是某种类型的指针。

比如:

        int   i="6465",   *pi=&i;
        char   *p;
       
        p   =   (char   *)pi;       //指针转化,就是按照   char   方式访问int内存位置,65对应字符就是A
        cout < <*p < <endl;           //输出A
       
        p   =   *(char   **)&pi;     //这里也许应该是   “某种类型的指针的指针”
        cout < <*p < <endl;           //输出A


 


可以发现其实结果都是一样的   ...

*(某种类型名*)&另一种类型指针变量名
这里的转换指针级数不对应,【2级指针强转为1级指针】
一般不会有这样的操作。

或许应该是:
*(某种类型名**)&另一种类型指针变量名       //转换前后都是2级指针
或者:*(某种类型名*)&另一种类型变量名     //转换前后都是1级指针


"*(某种类型名*)&另一种类型指针变量名"中的第一个*号后面部分与"(某种类型名   *)另一种类型指针变量名"的区别是:

"(某种类型名   *)另一种类型指针变量名" 这个是强制转化一个指针的类型,如int   a   =   10;int*   p   =   &a;   double*   pd   =   (double*)p;

而"*(某种类型名*)&另一种类型指针变量名"这个强制转化的是一个指向指针的指针(即指针的地址值):如
int   a   =   10;   int*   p   =   &a;   double*   pd   =   *(double**)&p;   //   先把指针p的地址强制转化为double**,然后再取转化后的这个指向指针的指针的值(这里是一个一维指针)赋值给pd.

实际上上面两个操作的结果是一样的,但用来对理解指针也有好处.


1)(某种类型名   *)另一种类型指针变量名    

        首先,这个操作的结果是   指针

        作用是,强制把一种指针类型转换成另外一种指针类型

        比如   :

        float   f       =   10.5f;
        float*   pf   =   &f;

        int*   pi   =   (int*)pf;              

        pi   和   pf   指向同一个数据,但类型不一样

        当你用   pi   引用这个数据的时候,程序把这个数据当int看,所以你得到的是如

        1093140480   错误的int数,你相当于欺骗了编译器,这个本来是个float,但你

        却说是个int
   
        当你用   pf   引用这个数据的时候,程序把这个数据当float看,你得到的是   10.5      

        这个重转换一般用于基类转派生类

        比如   :

        class   base   {};
        class   dev   :   public   base   {};

        base*   p   =   new   dev;

        dev*   pv   =   (dev*)p;

        前提是数据本来是派生类的

        其他情况下这种转换都是错的,如前面的   float*   转   int*  

       


2)

*(某种类型名*)&另一种类型指针变量名

     
首先这个的结果是一个   数据   不是指针

比如

        float   f   =   10.5;

        int   i   =   *(int*)&f;

        这个就相当于

        float   f       =   10.5f;
        float*   pf   =   &f;

        int*   pi   =   (int*)pf;    

        int   i   =   *pi;                         //   得到错误的数据


        同1),这个可以用于基类转派生类


        还有一个比较奇妙的用法

        在存储数据的时候,比如数据都是按DWORD   存


        //   sava

          float   f   =   10.5f;

          DWORD   dw   =   *(DWORD*)&f;

          fwrite(dw,   sizeof(DWORD),   1,   fp);

      //   read
 
          float   f;

          DWORD   dw;

          fread(dw,   sizeof(DWORD),   1,   fp);

          f   =   *(float*)&dw;

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条