能否用同一语句访问联合中不同结构体的同名成员x?
能否统一访问联合中两个结构体的x成员?
嘿,这个问题我来给你捋清楚~直接用ptr->x这种形式是不行的,但我们可以通过封装宏或函数的方式,实现类似“统一语句”的访问效果,下面详细说:
为啥直接ptr->x行不通?
你定义的uni联合本身并没有x这个成员,它的成员只有a和b,编译器根本找不到uni类型的x成员,直接写会报错。
另外还要注意:两个结构体里的x在内存里的位置不一样哦:
a_里的x是第一个成员,偏移量是0(相对于结构体起始地址)b_里的x是第二个成员,前面有个float类型的成员,通常偏移量是sizeof(float)(一般是4字节)
这意味着uni_ptr->a.x和uni_ptr->b.x指向的是内存里不同的位置,所以不可能通过同一个内存地址直接访问到两者。
实现统一访问的可行方法
既然不能修改原有的联合和结构体定义,我们可以通过封装来搞定:
方法1:封装内联函数(推荐)
如果你的代码里需要区分联合当前存的是a_还是b_(通常得加个标记位),可以写个内联函数来处理:
// 先定义个枚举,用来标记联合里存的是a还是b typedef enum { UNI_TYPE_A, UNI_TYPE_B } UniType; // 把联合和标记打包成一个带标签的结构体 typedef struct { UniType type; uni data; } TaggedUni; // 统一获取x的函数 static inline int get_uni_x(TaggedUni *tagged_uni) { switch (tagged_uni->type) { case UNI_TYPE_A: return tagged_uni->data.a.x; case UNI_TYPE_B: return tagged_uni->data.b.x; default: // 这里可以根据需求处理错误,比如返回0或者触发断言 return 0; } }
用的时候直接调用get_uni_x(&my_tagged_uni)就行,相当于用统一的语句拿到对应结构体的x成员。
方法2:用宏定义简化
如果你明确知道当前联合存的是哪个结构体,或者已经有标记位,也可以写个宏来简化写法:
// 带标记的条件宏,直接返回对应x #define GET_UNI_X(tagged_u) \ ((tagged_u).type == UNI_TYPE_A ? (tagged_u).data.a.x : (tagged_u).data.b.x)
使用时直接写GET_UNI_X(my_tagged_uni),看起来就像统一的访问语句一样。
重要提醒
一定要搞清楚联合当前存的是哪个结构体成员!如果联合里存的是a_,你却去访问b_.x,会读到无效的内存数据,属于C语言里的未定义行为,程序可能崩溃或者出现奇怪的结果。C语言的联合本身不会记录自己存的是什么类型,所以这个标记位得你自己维护好哦~
内容的提问来源于stack exchange,提问作者Kami Kaze
相关产品推荐
相关产品推荐

