user-0 提问: 结构体中联合体初始化的问题

回复:
user: user-1
content: 楼主，我现在也在做AUTOSAR的DEM这块，能否留个联系方式交流一下，多谢！

user: user-0
content: 引用 5 楼 vnvlyp 的回复:[quote=引用 4 楼 mianzhouhu 的回复:] 这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。 不支持c99的编译器怕是也应该更新一下了吧。。[/quote]  汽车行业的，芯片配套的编译器，没办法的

user: user-0
content: 引用 10 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)   这个是联合体中嵌套结构体，跟结构体中嵌套联合体还是有点区别

user: user-2
content: 仅供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)

user: user-0
content: 引用 6 楼 cfjtaishan 的回复: 24 #include <stdio.h>           23                              22                              21 #define MAX_LEN     32    20                              19 struct node {                18     int type;                17     union bb {               16     |   const int *a;        15     |   const char *b;       14     |   const float *c;      13     }cc;                     12 };                           11                              10 int main(void)                9 {             8     int array[MAX_LEN];       7     char src[MAX_LEN];        6                           >>  5     union bb type;            4     type.a = array;           3               2     struct node tmp[2] = {     1     |   {1,  {type.a}},   25      |   {2,  {type.a}}                                                                                                                                                                                      1     };        2               3     return 0;     4 }  类似这种定义方式，是否可以。  这种方法看起来有个问题，联合体的作用域不是在结构体中么？（虽然编译时确实可以通过）  另外，这个方法跟还是不适用此问题，因为实际中需要使用的是‘ type.b’,仍然会报类型不匹配

user: user-3
content: 如果你这联合体只有指针的话，应该可以添加一个void *类型吧，然后就应该可以接受所有指针类型了  typedef struct {     Dem_PreDebounceNameType                        PreDebounceName;                // (1)     union {     void *ptr;     const Dem_PreDebounceMonitorInternalType    *PreDebounceMonitorInternal;    // (0..1)     const Dem_PreDebounceCounterBasedType        *PreDebounceCounterBased;        // (0..1)     const Dem_PreDebounceFrequencyBasedType        *PreDebounceFrequencyBased;        // (0..1)     const Dem_PreDebounceTimeBasedType            *PreDebounceTimeBased;            // (0..1)     } PreDebounceAlgorithm; } Dem_PreDebounceAlgorithmClassType;

user: user-4
content: 24 #include <stdio.h>           23                              22                              21 #define MAX_LEN     32    20                              19 struct node {                18     int type;                17     union bb {               16     |   const int *a;        15     |   const char *b;       14     |   const float *c;      13     }cc;                     12 };                           11                              10 int main(void)                9 {             8     int array[MAX_LEN];       7     char src[MAX_LEN];        6                           >>  5     union bb type;            4     type.a = array;           3               2     struct node tmp[2] = {     1     |   {1,  {type.a}},   25      |   {2,  {type.a}}                                                                                                                                                                                      1     };        2               3     return 0;     4 }  类似这种定义方式，是否可以。

user: user-3
content: 引用 4 楼 mianzhouhu 的回复:这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。 不支持c99的编译器怕是也应该更新一下了吧。。

user: user-0
content: 引用 2 楼 cfjtaishan 的回复:typedef struct {     Dem_PreDebounceNameType                        PreDebounceName;                // (1)     union {     const Dem_PreDebounceMonitorInternalType    *PreDebounceMonitorInternal;    // (0..1)     const Dem_PreDebounceCounterBasedType        *PreDebounceCounterBased;        // (0..1)     const Dem_PreDebounceFrequencyBasedType        *PreDebounceFrequencyBased;        // (0..1)     const Dem_PreDebounceTimeBasedType            *PreDebounceTimeBased;            // (0..1)     } PreDebounceAlgorithm; } Dem_PreDebounceAlgorithmClassType;  const Dem_PreDebounceCounterBasedType PreDebounceCounterBased[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     } };  const Dem_PreDebounceAlgorithmClassType PreDebounceAlgorithmClass[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     } }; 试一下这种初始化方式～  这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。

user: user-0
content: 引用 1 楼 jianwen0529 的回复:成员换个位置？  强制转换？  干脆用一个void*替代联合体？  目前有的这个方法，将占用内存最大的成员放在第一个位置，然后强制转换成第一个成员类型，编译可以通过，但是这个方法太牵强，总觉得C语言不该这么low吧，目前也还没验证强制转换后对运行结果有没有影响。  void* 替代联合体？怎么知道联合体大小呢？估计行不通

user: user-5
content: 成员换个位置？  强制转换？  干脆用一个void*替代联合体？

user: user-4
content: typedef struct {     Dem_PreDebounceNameType                        PreDebounceName;                // (1)     union {     const Dem_PreDebounceMonitorInternalType    *PreDebounceMonitorInternal;    // (0..1)     const Dem_PreDebounceCounterBasedType        *PreDebounceCounterBased;        // (0..1)     const Dem_PreDebounceFrequencyBasedType        *PreDebounceFrequencyBased;        // (0..1)     const Dem_PreDebounceTimeBasedType            *PreDebounceTimeBased;            // (0..1)     } PreDebounceAlgorithm; } Dem_PreDebounceAlgorithmClassType;  const Dem_PreDebounceCounterBasedType PreDebounceCounterBased[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     } };  const Dem_PreDebounceAlgorithmClassType PreDebounceAlgorithmClass[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     } }; 试一下这种初始化方式～