如果不行,为什么?联合在结构体上的用途是什么?
你可以在联合体中使用任何数据类型,没有限制。
至于在结构体和联合体之间的选择,结构体按顺序在内存中布局其数据。这意味着它们的所有子组件是独立的。
而联合体则使用相同的内存来存储所有子组件,因此一次只能存在一个子组件。
例如:
┌─────┬─────┐
struct { int a; float b } gives │ a │ b │
└─────┴─────┘
▲ ▲
│ │
memory location: 150 154
│
▼
┌─────┐
union { int a; float b } gives │ a │
│ b │
└─────┘
结构体用于表示由其他对象组成的“对象”,比如一个点对象由两个整数组成,即x和y坐标:
typedef struct {
int x; // x and y are separate
int y;
} tPoint;
联合体通常用于一个对象可以是多个东西中的一个,但每次只能是其中的一种情况,比如类型不确定的存储系统:
typedef enum { STR, INT } tType;
typedef struct {
tType typ; // typ is separate.
union {
int ival; // ival and sval occupy same memory.
char *sval;
}
} tVal;
尽管如今(除了嵌入式系统等低级别工作)内存保存变得越来越不重要,但它们对于节省内存仍然非常有用,因此你不会看到很多这样的应用。
根据ISO/IEC 9899:TC3(C99标准):
联合类型描述了一个重叠的非空成员对象集,每个对象都有可选的名称和可能不同的类型。
简而言之,联合成员的内存空间重叠,并且您为联合成员指定的名称允许您按大小在该位置读取内存。请考虑以下示例:
#include <stdio.h>
#include <stdint.h>
typedef union
{
struct
{
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
};
uint32_t x;
} somenewtype;
typedef union
{
uint32_t* p;
uint8_t* q;
} somepointer;
int main(int argc, char** argv)
{
uint32_t r;
uint8_t s;
somenewtype z;
somepointer p;
r = 0x11223344; s = 0x11;
z.x = 0x11223344;
p.p = &r;
p.q = &s;
printf("%x%x%x%x\n", z.d, z.c, z.b, z.a);
printf("%x %x\n", *(p.p), *(p.q));
}
p.p = (uint32_t *) 0x7fffffffde5c;
p.q = (uint8_t *) 0x7fffffffde5b "\021D3\"\021P\337\377\377\377\177";
p.p = (uint32_t *) 0x7fffffffde5b;
p.q
会覆盖p.p
的地址。我强烈怀疑将32位整数的地址解引用为8位指针会打印出“该位置+32位大小的任何内容”,这巧合地对我来说恰好是22334411
。但是我怀疑,在那一点上,行为是未定义的。somenewtype
的实际用途,但不能看到somepointer
的实际用途——那是一个我非常确定会出问题的虚构例子。
boost
时保持流畅比清晰地思考我正在编程的内容要困难得多,耗费更多时间。 - MickLHstruct tVal tval; tval->sval;
还是我们需要为联合指定标识符,并使用它来访问联合成员,例如tval.uval->sval;
? - Kamal Pandeytval.sval
。而且这只适用于存在一个未命名联合体的情况。如果你有像union { int ival; char * sval} name;
这样的命名联合体,我认为你需要指定为:tval.name.sval
。 - paxdiablo*tval.sval
还是tval.*sval
? - Kamal Pandey