如果没有原因?结构的使用?
如果没有原因?结构的使用?
您可以在联合中使用任何数据类型,没有任何限制。
至于结构在结构上的使用,结构在存储器中依次布置它们的数据。这意味着它们的所有子组件都是分开的。
另一方面,工会对所有子组件使用相同的内存,因此一次只能存在一个。
例如:
+-----+-----+
struct { int a; float b } gives | a | b |
+-----+-----+
^ ^
| |
memory location: 150 154
|
V
+-----+
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;
它们对于节省内存非常有用,尽管现在这种情况越来越少(除了像嵌入式系统这样的低级工作),所以你看不到很多。
您可以在联合中使用任何数据类型,没有任何限制。
至于结构在结构上的使用,结构在存储器中依次布置它们的数据。这意味着它们的所有子组件都是分开的。
另一方面,工会对所有子组件使用相同的内存,因此一次只能存在一个。
例如:
+-----+-----+
struct { int a; float b } gives | a | b |
+-----+-----+
^ ^
| |
memory location: 150 154
|
V
+-----+
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标准):
联合类型描述了一组重叠的非成员对象,每个成员对象 它具有可选的指定名称和可能不同的类型。
简而言之,union成员的内存空间重叠,您为union成员提供的名称允许您在该位置读取内存大小。考虑:
#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));
}
在第一个printf中,我们正在做的是打印出32位整数的8位部分。希望当然没有填充匿名结构。
在第二个printf?我不得不单步使用gdb来理解,但我做到了:
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
- 这是一个人为的例子,我很确定会破产。