结构和指针

我在将条目内存地址获取到结构的成员变量时遇到问题。 我试过两种方式,其中一种方法不能正常工作。 如果你们给我一些建议,那将是非常好的。

首先 ,我定义了一个名为BITMAP_HEADER的结构。

struct BITMAP_HEADER { WORD bfType ; DWORD bfSize ; WORD bfReserved1 ; WORD bfReserved2 ; DWORD bfOffBits ; } ; 

其次 ,我定义并初始化了一些变量。 在阅读下一行之前,请先查看下面的代码。 如果你问我为什么我有一个字符指针,我需要访问整数bfSize的每个字节。

 struct BITMAP_HEADER bitmap_header ; char* pSize = (char*)&bitmap_header.bfSize; 

第三 ,我以两种不同的方式获得了bfSize的内存地址并打印了值

 1. printf("%X\n", *pSize) ; 2. printf("%X\n", (unsigned char)*(((char*)&bitmap_header)+2)) ; 

(1)直接获取bitmap_header.bfSize的内存地址。

(2)得到一个存储器地址到结构BITMAP_HEADER并将指针移动到下一个2字节。

最后 ,结果如下。

 2D F6 

有关您的信息,请参阅结构BITMAP_HEADER的hex数据。

 42 4D / F6 C6 2D 00 / 00 00 / 00 00 / 36 00 00 00 

为什么第一种方法不起作用? 我认为这两种方法完全相同。

你在这里遇到了结构填充。 编译器在bfTypebfSize字段之间插入两个字节的填充,以使bfSize与4个字节的大小对齐,因为bfSize是一个DWORD。

一般来说,您不能依赖于能够计算结构中的精确偏移量,因为编译器可能会在成员之间添加填充。 您可以使用特定于编译器的位在某种程度上控制它; 例如,在MSVC上, 包pragma ,但我不推荐这个。 结构填充用于指定成员对齐限制,并且某些体系结构将在未对齐访问时出错。 (其他人可能会手动修复对齐,但通常会这么慢 。)

另见: http : //en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding

对于预先知道结构的原始数据,通常最好将其读取到数组并使用定义的偏移量来访问所需的字段。 这样您就不必担心编译器的行为(可能通常不像您期望的那样)。 您的代码如下所示:

 #define FIELD_TYPE 0 #define FIELD_SIZE 2 #define FIELD_RES1 6 #define FIELD_RES2 8 #define FIELD_OFF 10 #define SIZE_HEADER 14 static uint8_t header[SIZE_HEADER]; <...> uint8_t * pheader = header; DWORD offset_bits = (DWORD)*(pheader + FIELD_OFF); 

PS要使这段代码可移植, WORD和endianness的大小必须考虑,很少#ifdef .. #else .. #endif应该有帮助。

PPS甚至可以更好地使用手动逻辑运算和移位运算符而不是转换,但为了简洁起见,将其保留为这种方式。