下面是我从书上抄下来的显示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所指向的数据又没有其它标致!谢谢大家了!!
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所指向的数据又没有其它标致!谢谢大家了!!
你不是已经把pDib强制转化为BITMAPINFOHEADER *这样的结构体了吗~~~
位图信息头本身也是存储空间,只是用于存储位图信息~~
A a;
先吧a通过memcpy拷贝到一块内存BYTE *b;
这时候虽然b只是一块内存,但是保留A的结构,当然可以强制转换
当你这样转换的时候,编译器就认为pDib指向的内存里是存放BITMAPINFOHEADER数据结构类型的。而内存里的数据,确实是BITMAPINFOHEADER结构的数据啊,所以自然可以认出了。
如果pDib指向的内存里存放的数据不是BITMAPINFOHEADER结构,你这样转换:pBitmapInfoHeader=(BITMAPINFOHEADER *)pDib;然后这样访问pBitmapInfoHeader->biHeight,就出现结果不确定了比如我在变量a里放了10个字答,然后我这样转换
int b = (int)a;
这时编译器就认为b指向的是int,而不是字符了,解释的时候也安4个字节一个单位来解释这些问题,主要是你对指针和内存的概念认识不够...
-------------
没有丢掉!只是都按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)];
struct header * pHdr = (struct header*)pData;
struct color *pClr = (struct color*)(++pHdr);
struct pixes *pPix = (struct pixes*)(++pClr);
| 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*
pBitmapInfoHeader所指向内存的内容也是:110110吗?
谢谢大家!
再次感谢gzlyb(冰风---现改名叫猪三叫,谢谢)等同志!!