有什么好的例子可以说明结构体和联合体的区别吗? 基本上我知道struct使用了它成员的所有内存,而union使用了最大的成员内存空间。还有其他操作系统级别的差异吗?
当前回答
结构和联合的区别是什么?
简单的回答是:区别在于内存分配。 解释: 在结构中,将为结构内部的所有成员创建内存空间。 在联合内存空间将只为需要最大内存空间的成员创建。 考虑下面的代码:
struct s_tag
{
int a;
long int b;
} x;
union u_tag
{
int a;
long int b;
} y;
这里在struct和union内部有两个成员:int和long int。在32位操作系统中,int的内存空间为:4字节,long int的内存空间为:8。
因此,对于struct, 4+8=12个字节将被创建,而对于union,将创建8个字节
代码示例:
#include<stdio.h>
struct s_tag
{
int a;
long int b;
} x;
union u_tag
{
int a;
long int b;
} y;
int main()
{
printf("Memory allocation for structure = %d", sizeof(x));
printf("\nMemory allocation for union = %d", sizeof(y));
return 0;
}
裁判:http://www.codingpractise.com/home/c-programming/structure-and-union/
其他回答
是的,struct和union之间的主要区别和你说的一样。 Struct使用其成员的所有内存,union使用最大的成员内存空间。
但所有的区别在于使用内存的需要。 在unix的进程中可以看到联合的最佳使用,在那里我们使用信号。 比如一个进程一次只能作用于一个信号。 所以一般声明是:
union SIGSELECT
{
SIGNAL_1 signal1;
SIGNAL_2 signal2;
.....
};
在这种情况下,进程只使用所有信号中最高的内存。 但如果在这种情况下使用struct,内存使用量将是所有信号的总和。 有很大的不同。
总之,如果您知道一次访问任何一个成员,则应该选择Union。
As you already state in your question, the main difference between union and struct is that union members overlay the memory of each other so that the sizeof of a union is the one , while struct members are laid out one after each other (with optional padding in between). Also an union is large enough to contain all its members, and have an alignment that fits all its members. So let's say int can only be stored at 2 byte addresses and is 2 bytes wide, and long can only be stored at 4 byte addresses and is 4 bytes long. The following union
union test {
int a;
long b;
};
could have a sizeof of 4, and an alignment requirement of 4. Both an union and a struct can have padding at the end, but not at their beginning. Writing to a struct changes only the value of the member written to. Writing to a member of an union will render the value of all other members invalid. You cannot access them if you haven't written to them before, otherwise the behavior is undefined. GCC provides as an extension that you can actually read from members of an union, even though you haven't written to them most recently. For an Operation System, it doesn't have to matter whether a user program writes to an union or to a structure. This actually is only an issue of the compiler.
union和struct的另一个重要属性是,它们允许指向它们的指针可以指向其任何成员的类型。因此,以下是有效的:
struct test {
int a;
double b;
} * some_test_pointer;
Some_test_pointer可以指向int*或double*。如果将一个test类型的地址转换为int*,它将指向它的第一个成员,实际上是a。工会也是如此。因此,因为联合将始终具有正确的对齐方式,您可以使用联合来使指向某些类型的指针有效:
union a {
int a;
double b;
};
这个联合实际上可以指向int型和double型:
union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;
实际上是有效的,正如C99标准所述:
对象的存储值只能由具有以下类型之一的左值表达式访问: 与对象的有效类型兼容的类型 ... 在其成员中包含上述类型之一的聚合或联合类型
编译器不会优化出v->a = 10;因为它可能会影响*some_int_pointer的值(该函数将返回10而不是5)。
结构和联合的区别是什么?
简单的回答是:区别在于内存分配。 解释: 在结构中,将为结构内部的所有成员创建内存空间。 在联合内存空间将只为需要最大内存空间的成员创建。 考虑下面的代码:
struct s_tag
{
int a;
long int b;
} x;
union u_tag
{
int a;
long int b;
} y;
这里在struct和union内部有两个成员:int和long int。在32位操作系统中,int的内存空间为:4字节,long int的内存空间为:8。
因此,对于struct, 4+8=12个字节将被创建,而对于union,将创建8个字节
代码示例:
#include<stdio.h>
struct s_tag
{
int a;
long int b;
} x;
union u_tag
{
int a;
long int b;
} y;
int main()
{
printf("Memory allocation for structure = %d", sizeof(x));
printf("\nMemory allocation for union = %d", sizeof(y));
return 0;
}
裁判:http://www.codingpractise.com/home/c-programming/structure-and-union/
对于联合,您只应该使用其中一个元素,因为它们都存储在同一个位置。这在您想要存储可能是几种类型之一的内容时非常有用。另一方面,结构体的每个元素都有单独的内存位置,并且它们都可以一次使用。
为了给出它们使用的一个具体例子,我不久前正在研究一个Scheme解释器,我实际上是将Scheme数据类型覆盖到C数据类型上。这涉及到在一个结构体中存储一个指明值类型的枚举和一个用于存储该值的联合。
union foo {
int a; // can't use both a and b at once
char b;
} foo;
struct bar {
int a; // can use both a and b simultaneously
char b;
} bar;
union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!
struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK
编辑:如果你想知道将x.b设置为“c”会改变x.a的值,从技术上讲,这是未定义的。在大多数现代机器上,char是1字节,int是4字节,所以给x.b的值'c'也给x.a的第一个字节相同的值:
union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
打印
99, 99
为什么这两个值是一样的?因为int 3的最后3个字节都是0,所以它也被读为99。如果我们为x.a输入一个更大的数字,你会发现情况并非总是如此:
union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
打印
387427, 99
为了更仔细地查看实际的内存值,让我们设置并打印十六进制的值:
union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);
打印
deadbe22, 22
您可以清楚地看到0x22覆盖了0xEF的位置。
BUT
在C语言中,int类型的字节顺序没有定义。这个程序在我的Mac上用0x22覆盖了0xEF,但是在其他平台上它会覆盖0xDE,因为组成int的字节的顺序颠倒了。因此,在编写程序时,永远不要依赖于覆盖联合中特定数据的行为,因为它是不可移植的。
有关字节排序的更多信息,请参阅endianness。
从技术上讲,非指:
假设:椅子=记忆块,人=变量
结构:如果有3个人,他们可以坐在相应大小的椅子上。
工会:如果有3个人,只有一张椅子可以坐,所有人都需要在他们想坐的时候使用同一把椅子。
技术上讲是指:
下面提到的程序对结构和联合进行了深入研究。
struct MAIN_STRUCT
{
UINT64 bufferaddr;
union {
UINT32 data;
struct INNER_STRUCT{
UINT16 length;
UINT8 cso;
UINT8 cmd;
} flags;
} data1;
};
MAIN_STRUCT size =sizeof(UINT64) for bufferaddr + sizeof(UNIT32) for union + 32 bit for padding(取决于处理器架构)= 128 bits。 对于结构,所有成员连续获取内存块。
Union获得一个最大大小成员的内存块(这里是32位)。 在联合内部还有一个结构体(INNER_STRUCT),它的成员获得一个总大小为32位(16+8+8)的内存块。在联合中,可以访问INNER_STRUCT(32位)成员或data(32位)。