结构体嵌套结构体名

转自:http://atu82.bokee.com/6706799.html

结构体嵌套结构体名

前一段时间在看DDK中例子的时候,看到这样的的结构体定义:
typedef struct _COMMON_DEVICE_DATA
{
    PDEVICE_OBJECT  Self;
    BOOLEAN         IsFDO;
      ......
   
} COMMON_DEVICE_DATA, *PCOMMON_DEVICE_DATA;
typedef struct _PDO_DEVICE_DATA
{
    COMMON_DEVICE_DATA; // 注意这里

    PDEVICE_OBJECT  ParentFdo;
    PWCHAR      HardwareIDs;
      ......   
} PDO_DEVICE_DATA, *PPDO_DEVICE_DATA;
typedef struct _FDO_DEVICE_DATA
{
    COMMON_DEVICE_DATA; // 注意这里

    PDEVICE_OBJECT  UnderlyingPDO;   
      ......
} FDO_DEVICE_DATA, *PFDO_DEVICE_DATA;

这里的结构体定义方法看起来好像是定义一个基类,然后在基类上扩展出两个子类。
这样的做法与平常的结构体嵌套结构体不同,因为在结构体中只有另外的结构体的名字,如PDO_DEVICE_DATA结构体中只有COMMON_DEVICE_DATA结构体名,而不是成员变量。这种写法在VC6.0中可以通过编译,在gcc中不能通过编译,因此我猜想可能微软扩展了C的语法,这种写法不是标准C的做法。

接下来,我写下面的例子程序来探讨这种定义结构体的方法。
在base.h中定义了三个结构体,BASE、EXT1、EXT2。EXT1和EXT2中都有BASE结构体名。发现嵌套了结构体名(BASE)的结构体(EXT1和EXT2)的长度是sizeof(BASE)+其它成员的长度。EXT1结构体指针可以直接访问BASE结构体的成员,且EXT1结构体指针可以强制转换成BASE结构体指针。

/* base.h */
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char BOOLEAN;
typedef unsigned long ULONG;
typedef void VOID;
#define FALSE 0;
#define TRUE ~0;

typedef struct _BASE
{
 BOOLEAN IsExt1;
 ULONG Number;
} BASE, *PBASE;
typedef struct _EXT1
{
 BASE;
 ULONG Ext1Num;
} EXT1, *PEXT1;
typedef struct _EXT2
{
 BASE;
 ULONG Ext2Num;
} EXT2, *PEXT2;

VOID TestStruct()
{
 BASE base, *pbase;
 EXT1 ext1, *pext1;
 EXT2 ext, *pext, *pext2;

 ext.Ext2Num = 2;
 ext.IsExt1 = FALSE;
 ext.Number = 100;
 pext = &ext;

 printf("sizeof(base) = %d\n", sizeof(base));
 printf("sizeof(ext1) = %d\n", sizeof(ext1));
 printf("sizeof(ext2) = %d\n", sizeof(ext));

 pbase = (PBASE)pext;
 if (pbase->IsExt1)
 {
  printf("Is Ext1\n");
  pext1 = (PEXT1)&ext;
  printf("Ext1Num = %ld\n", pext1->Ext1Num);
 }
 else
 {
  printf("Is Ext2\n");
  pext2 = (PEXT2)&ext;
  printf("Ext2Num = %ld\n", pext2->Ext2Num);
 }
 
}

/* main.c */
#include "base.h"

int main()
{
 TestStruct();
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值