下面是我从书上抄下来的显示BMP图片的一段程序的一部分,其中有个类型转换我可以感性地理解,但是我无法从本质上认识到它是如何实现的,请大家帮我看看,程序段如下://下面的BITMAPINFOHEADER是一个结构体类型
BITMAPINFOHEADER  *pBitmapInfoHeader;  //定义一个指向位图信息头的指针
BYTE              *pDib;              
CFile             file;........ 
........
//在内存中开辟一块空间,用于存放位图中除去文件头剩余部分的数据
pDib=(BYTE *)malloc(位图中除去位图文件头剩余部分数据的大小);//把文件剩余部分的数据读到内存
file.Read(pDib,位图中除去位图文件头剩余部分数据的大小);//就是下面一句转换我无法理解???????
pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib;我不能理解的原因是:
通过上面的转换后,pBitmapInfoHeader和pDib都指向了同一块内存了吧,但是当我下面有这样的运用:pBitmapInfoHeader->biHeight、pBitmapInfoHeader->biWidth时,它怎么知道biHeight和biWidth分别存放在pDib所指向的那块数据的哪个地方?!pDib所指向的数据又没有其它标致!谢谢大家了!!

解决方案 »

  1.   

    pBitmapInfoHeader指针是BITMAPINFOHEADER结构,编译器当然知道哪块数据是Width,哪块是Height.
      

  2.   

    它怎么知道biHeight和biWidth分别存放在pDib所指向的那块数据的哪个地方?
    你不是已经把pDib强制转化为BITMAPINFOHEADER *这样的结构体了吗~~~
    位图信息头本身也是存储空间,只是用于存储位图信息~~
      

  3.   

    pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib;强制转换后内存格式pBitmapInfoHeader都知道了当然可以直接用->调用至于为什么可以强制转换,举例:
    A a;
    先吧a通过memcpy拷贝到一块内存BYTE *b;
    这时候虽然b只是一块内存,但是保留A的结构,当然可以强制转换
      

  4.   

    pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib;
    当你这样转换的时候,编译器就认为pDib指向的内存里是存放BITMAPINFOHEADER数据结构类型的。而内存里的数据,确实是BITMAPINFOHEADER结构的数据啊,所以自然可以认出了。
    如果pDib指向的内存里存放的数据不是BITMAPINFOHEADER结构,你这样转换:pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib;然后这样访问pBitmapInfoHeader->biHeight,就出现结果不确定了比如我在变量a里放了10个字答,然后我这样转换
    int b = (int)a;
    这时编译器就认为b指向的是int,而不是字符了,解释的时候也安4个字节一个单位来解释这些问题,主要是你对指针和内存的概念认识不够...
      

  5.   

    非常感谢楼上几位和gzlyb(冰风---现改名叫猪三叫,谢谢),但是对gzlyb(冰风---现改名叫猪三叫,谢谢) 说的我还有一点不太明白,你说:“而内存里的数据,确实是BITMAPINFOHEADER结构的数据啊,所以自然可以认出了”。但是pDib所指向的内存只有是由3部分构成的,只有第一部分数据是信息头,而第二部分是颜色信息,第三部分是图片象素信息,难道编译器在进行pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib转换的时候就把第二部分和第三部分的数据都丢掉了吗?也就是说pBitmapInfoHeader与pDib所指向的内存的地址是一样的,但是pBitmapInfoHeader所能“表示”的数据只有pDib所指向的数据的一部分吗?
      

  6.   

    有一种游戏,或者叫编码方式,就是用一块抠出不同方框的硬纸板,覆盖到一张写满文字的纸上,不同的方框布局可以看出不同的内容。数据结构就是这张硬纸板,内存就是这张写满字的纸,内存中的数据如何表现,就是根据你采取什么数据结构来映射,当然有可能没有任何意义,也可能发生错误。这里由于定义好的BITMAPINFOHEADER和你读进来的pDib数据之间逻辑上是一致的,所以可以这样转换。
      

  7.   

    Mackz(在相互)说的就很有意思。BITMAPINFOHEADER *)pDib转换的时候就把第二部分和第三部分的数据都丢掉了吗?
    -------------
    没有丢掉!只是都按BITMAPINFOHEADER结构为一个单位进行解释了。就你说的三部分不同的表现数据,我随便摹拟你说的情况,举一个例子:
    (把回复粘贴出来放在txt中,格式好看些)
    第一部分的数据结构:
    struct header
    {
       int nHeight;  //高
       int nWidth;   //宽
    }第二部分的数据结构:
    struct color
    {
       BYTE bR;  //r色
       BYTE bG;  //
       BYTE bB;  //
    }第三部分的数据结构:
    struct pixes
    {
      int nXCnt;  //x轴上的象素个数
      int nYcnt;  //y轴上的象素个数
    }....初始化...
    struct header hdr;
    struct color clr;
    strutc pixes pix;hdr.hHeight = 100;
    hdr.nWidth  = 200;clr.bR = 25;
    clr.bG = 45;
    clr.bB = 134;pix.nXCnt = 1024;
    pix.nYCnt = 768;//已经构造好三个不同部分的对象了,现在把它们放在一个内存块里
    //先分配足够三个对象的内存,我还多分了10个字节
    BYTE* pData = new BYTE[sizeof(struct header)+sizeof(struct color)+sizeof(struct pixes) + 10];
    //拷贝数据到内存中,相当于你把bitmap文件的数据放在内存里一样
    //放头数据
    size_t nCnt1 = sizeof(struct header); 
    memcpy(&pData,&hdr,nCnt1);
    //放颜色数据
    size_t nCnt2 = sizeof(struct color);
    memcpy(&pData[nCnt1],&clr,nCnt2);
    //放象素数据
    memcpy(&pData[nCnt1+nCnt2],&pix,sizeof(struct pixes));//现在pData指向的内存是以BYTE为一个单位的,也就是说
    //++pData后,pData就指向第二个BYTE了。这样解释内存的数据,
    //我们无法知道这些数据具体代表什么意思。现在进行转换:
    struct header * pHdr = (struct header*)pData;
    //这样转换后可以正确的如下这样解析内存里的数据块:
    int nHeight = pHdr->nHeight;
    int nWidth  = pHdr->nWidth;
    //但如果这样转(实质是把pData指向内存的数据的前3个字节解释为颜色结构了,
    //但实际上前3个字节是头结构的成员nHeigth的数据的一分部...):
    struct color * pClr = (struct color*)pData;
    //然后这样解析内存中的数据就会发生错误或不确定的行为:
    BYTE bR = pClr->nR;
    .......//写得罗嗦了,好好想想就明白
    //第二,三部分数据的转换
    struct color *pClr = (struct color*)&pData[sizeof(struct header)];
    struct pixes *pPix = (struct pixes*)&pData[sizeof(struct header)+sizeof(struct color)];
      

  8.   

    //第二,三部分数据的转换,也可以这样转,方式还是多
    struct header * pHdr = (struct header*)pData;
    struct color *pClr = (struct color*)(++pHdr);
    struct pixes *pPix = (struct pixes*)(++pClr);
      

  9.   

    the format of bitmap file:---------------------------
    | BITMAPINFOHEADER struct |
    ---------------------------
    | color palette (optianal)|
    ---------------------------
    | pixel data              |
    ---------------------------
    so, if you get a pointer point to the bitmap data buffer. this pointer also point to a struction BITMAPINFOHEADER.
    in this case we can change this pointer from type BYTE* to type struction BITMAPINFOHEADER* 
      

  10.   

    非常非常感谢楼上几位热心人的帮助,小弟现在有点眉目了,不过我还想再请大家帮我澄清一下:当进行pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib完后,pDib与pBitmapInfoHeader所指向的内存的内容在物理上是不是完全一样的,比如pDib指向内存的内容是:110110,
    pBitmapInfoHeader所指向内存的内容也是:110110吗?
    谢谢大家!
      

  11.   

    终于想明白了!
    再次感谢gzlyb(冰风---现改名叫猪三叫,谢谢)等同志!!