有没有名字并不重要,只是在使用时,x.unname.x1与x.x1的书写区别。

如这个结构:
TV_INSERTSTRUCT STRUCT
  hParent       DWORD      ?  
  hInsertAfter  DWORD ?
               ITEMTYPE <>
TV_INSERTSTRUCT ENDS

其中ITEMTYPE定义为
ITEMTYPE UNION
        itemex TVITEMEX <>
        item TVITEM <>
ITEMTYPE ENDS

它后面直接跟了ITEMTYPE定义,这个时候,展开就变成了这样:
TV_INSERTSTRUCT STRUCT
  hParent       DWORD      ?  
  hInsertAfter  DWORD ?
  union
     itemex        TVITEMEX <>
     item          TVITEM <>
  ends
TV_INSERTSTRUCT ENDS

然后,会取union中,其中最大的一项做为这个union的尺寸,TVITEMEX大小为44,TV_ITEM为40,所以,TV_INSERTSTRUCT总大小固定为44+8=52字节。

所以,无论你在union中是使用itemex,还是item,除了item比itemex少了一个成员,结果是一样的,申明变量时local a:TV_INSERTSTRUCT,a.itemex.iMask和a.item.iMask,编译后,相对地址都一样为[xxx+8],那为什么要用union来进行区分呢?

union书面的意思是联合,正如这个意思所说的,它是联合了相似的结构的一种方法,像TV_INSERTSTRUCT,它一个结构,就可以用在不同版本的TreeView控件上,注意看,高版本的itemex比低版本的item结构中多了一个成员iIntegral,但是,两个结构前面的成员名字和位置是完全一模一样的,低版本的TreeView肯定只会用到item,最后的成员iIntegral会忽略掉,只有高版本的才会用到iIntegral,如果之后结构体又变了,又会多一个union成员itemex1,里面可能会多一个或多个成员,每个版本的TreeView只使用当时的定义,多的成员会自动忽略,以便于自动处理而不需要用户特别针对不同版本去写不同的代码。

总的来说,使用union结构,不需要特别处理就能够做到结构的加强而兼容原来的。如果只是专门针对当前版本,那与直接插入最大尺寸的union成员来定义一个struct是一样的。那就没必要使用union。

说到这里了,其实上面的结构,可以固定为:

TV_INSERTSTRUCT STRUCT
  hParent       DWORD      ?  
  hInsertAfter  DWORD ?
  itemex        TVITEMEX <>
TV_INSERTSTRUCT ENDS

结果是一样的。低版本会忽略掉最后一个成员,固定使用40字节。高版本会自动使用全部成员,这样就做到了版本兼容。而使用union的原因是结构化编程规范而已,实际情况中,都会自动处理的,所以,偷懒的话,就直接像上面一样,新的结构前面包含旧的,后面追加新的成员,就别去用union了。

注意:struct与union是不一样的,如果ITEMTYPE UNION变成ITEMTYPE STRUCT,那是全部累加而不是取最大成员大小的。TV_INSERTSTRUCT大小就成了92而不是52。

这些初学的朋友可能不了解,知道了union的定义与属性,在转换或使用时,就不会不知道如何处理,其实这些东西,多试试就能试出来的,呵呵

不知道我说得清楚不。。。