结构和指针
我在将条目内存地址获取到结构的成员变量时遇到问题。 我试过两种方式,其中一种方法不能正常工作。 如果你们给我一些建议,那将是非常好的。
首先 ,我定义了一个名为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
为什么第一种方法不起作用? 我认为这两种方法完全相同。
你在这里遇到了结构填充。 编译器在bfType
和bfSize
字段之间插入两个字节的填充,以使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甚至可以更好地使用手动逻辑运算和移位运算符而不是转换,但为了简洁起见,将其保留为这种方式。