多字节字符常量和位图文件头类型常量

时间:2009-03-02 06:29:16

标签: c++ windows

我有一些现有的代码,我曾用它将图像写入位图文件。其中一行代码如下所示:

bfh.bfType='MB';

我想我可能是从某个地方复制过的。其他开发者之一对我说“看起来不对,是不是应该是'BM'?”无论如何它似乎确实工作正常,但在代码审查时它会被重构:

bfh.bfType=*(WORD*)"BM";

谷歌搜索表明大部分时间,第一行似乎都在使用,而有些人会这样做:

bfh.bfType=0x4D42;

那有什么区别?他们怎么能给出正确的结果呢?无论如何,多字节字符常量意味着什么?他们真的一样吗?

3 个答案:

答案 0 :(得分:5)

这三个(可能)是等价的,但出于不同的原因。

bfh.bfType=0x4D42;

这是最容易理解的,它只是加载bfType,其数字恰好代表位8-15中的ASCII“M”和位0-7中的ASCII“B”。如果以little-endian格式将其写入流中,则流将包含“B”,“M”。

bfh.bfType='MB';

这基本上等同于第一个语句 - 它只是表达整数常量的另一种方式。它可能完全取决于编译器对它的作用,但它可能会根据您编译的机器的字节序生成一个值。如果你在同一个endian-ness的机器上编译和执行,那么当你在流上写出值时,你应该得到'B','M'。

bfh.bfType=*(WORD*)"BM";

这里,“BM”使编译器创建一个看起来像'B','M','\ 0'的数据块并获得一个指向它的char *。然后将其转换为WORD *,这样当它被解除引用时,它将把内存读作WORD。因此它在机器具有的任何字节序中将'B','M'读入bfType。使用相同的endian-ness写出它显然会在你的流上加上'B','M'。只要您只使用bfType写出流,这是最便携的版本。但是,如果您正在使用bfType进行任何比较/等等,那么最好选择一个endian-ness,并在读取或写入值时根据需要进行转换。

答案 1 :(得分:1)

我没有找到API,但根据http://cboard.cprogramming.com/showthread.php?t=24453,bfType是一个位图标题。 BM的值很可能意味着“位图”。

0x4D42是十六进制值(M为0x4D,B为0x42)。在little endian写入方式(最不重要的字节优先)中,这与“BM”(不是“MB”)相同。如果它也适用于“MB”,那么可能会采用一些默认值。

答案 2 :(得分:0)

tehvan帖子的附录:

来自维基百科的BMP条目:

  

File header   请注意,BMP文件格式的前两个字节(因此BMP标头)以big-endian顺序存储。这是神奇的数字'BM'。所有其他整数值都以little-endian格式存储(即,最低有效字节优先)。

因此,根据规范,重构代码看起来是正确的。

您是否尝试使用几个不同的照片编辑器以“MB”作为幻数打开文件?