一个结构和联盟之间的区别一个结构和联盟之间的区别(Difference between a Stru

2019-05-11 06:36发布

有没有什么好的例子给予的区别structunion ? 基本上我知道struct使用其成员的所有内存和union使用的最大的成员的内存空间。 是否有任何其他操作系统级别的区别?

Answer 1:

有了工会,你只应该使用的元素之一,因为他们都储存在同一个地方。 这使得它非常有用,当你想存储的东西,可能是多种类型之一。 一个结构,在另一方面,具有用于它的每个元素的单独的存储器位置,它们都可以一次使用。

为了给自己使用的一个具体的例子,我在一个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

编辑:如果你想知道什么设置XB到“C” XA改变它的值,从技术上讲这是不确定的。 在大多数现代机器炭是1个字节和一个int是4个字节,所以给予XB的值“C”也给出XA相同的值的第一个字节:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

版画

99, 99

为什么这两个值相同? 因为最后3个字节INT 3都为零,因此它也理解为99。如果我们把在XA数量较多,你会看到,这是情况并非总是如此:

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。

在C中,在一个int字节的顺序没有限定。 这项计划覆盖了0xEF与为0x22我的Mac上,但也有其他平台的地方将覆盖写0xDE,而不是因为组成的int字节的顺序被颠倒。 因此,在编写程序时,你不应该依赖于工会覆盖特定的数据,因为它不是便携式的行为。

有关字节顺序多读书,看看字节序 。



Answer 2:

这里的答案很简单:一个结构是一个创纪录的结构:在结构中的每个元素分配新的空间。 所以,一个结构类似

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

分配至少(sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))字节在存储器中用于每个实例。 (“至少”,因为架构对准约束可强制编译器垫的结构体。)

另一方面,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

分配存储一个数据块,并给它4个个别。 所以sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double))再以一些另外的路线的可能性。



Answer 3:

有没有什么很好的例子给一个“结构”和“联盟”之间的区别?

一个假想的通信协议

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

在该假想的协议,已经sepecified,基于“消息类型”,在头部中的以下位置要么是一个请求数,或四个字符代码,但不能同时使用。 总之,工会允许在同一个存储位置来表示多个数据类型,它是保证你只需要存储的数据类型之一在任何一个时间。

工会很大程度上是基于用C的遗产作为系统程序设计语言,其中,“重叠”的存储位置以这种方式有时使用一个低级别的细节。 有时你可以使用工会保存,你有一个数据结构,其中只有几种类型的人会在同一时间被保存记忆。

在一般情况下,OS不关心或了解结构和工会 - 它们都是简单的内存阻塞。 一个结构是存储器,其存储多个数据对象,其中这些对象不重叠的块。 联合是,其存储多个数据对象的存储器的块,但只具有最大的这些存储,因此可以只存储数据对象中的一个在任一个时刻。



Answer 4:

因为你已经在你的问题的状态,区别主要unionstructunion成员相互叠加的内存,使得工会的sizeof是一个,而struct成员制定了一个后对方(带有可选的填充在两者之间)。 另外一个工会是大到足以容纳所有成员,并有适合其所有成员的对齐。 所以我们可以说int只能存放在2个字节的地址,为2个字节宽,长,只能存放在4个字节地址和4个字节长。 下面工会

union test {
    int a;
    long b;
}; 

可以有一个sizeof的4和4既是工会的对齐要求和结构可以在年底进行填充,而不是在他们开始。 写一个结构变化写入成员才有价值。 写一个工会的成员会使无效的所有其他成员的值。 您不能访问他们,如果你以前没有写信给他们,否则该行为是不确定的。 GCC提供的,你实际上可以从工会成员阅读的延伸,即使你没有写他们最近。 对于一个操作系统,它并不具有重要用户程序是否写入一个工会或结构。 这实际上是只编译器的问题。

工会和结构的另一个重要特性是,他们允许一个指向他们可以指向类型的任何成员 。 所以下面是有效的:

struct test {
    int a;
    double b;
} * some_test_pointer;

some_test_pointer可以指向int*bool* 。 如果你施放类型的地址testint* ,它将指向它的第一个成员, a ,其实。 这同样是一个真正的工会太。 因此,因为工会总会有正确的定位,你可以使用一个联盟,使指向某种类型的有效的:

union a {
    int a;
    double b;
};

该联盟将真正能够指向一个int和一个双:

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 )。



Answer 5:

一个union是一对夫妇的情况下非常有用。 union可以成为像一个内核编写设备驱动程序非常低的水平操作的工具。

这方面的一个例子是一个解剖float通过使用数union一个的struct与位域和一个float 。 我保存了许多在float的,后来我可以访问的特定部分float通过该struct 。 这个例子说明了如何union使用有不同的角度来看待数据。

#include <stdio.h>                                                                                                                                       

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

看看单精度维基百科的描述。 我使用的示例和幻数0.15625从那里。


union也可以用于实现具有多个替代代数数据类型。 我发现在由奥沙利文,斯图尔特和Goerzen的“真实世界哈斯克尔”一书中的一个例子。 检查出来的的区分联合部分。

干杯!



Answer 6:

联盟 ”和“ 结构 ”是C语言的结构 。 它们之间的“操作系统级别”差的谈话很不合适的,因为它是,如果你使用一个或另一个关键字产生不同的代码编译器



Answer 7:

非技术上讲是指:

假设:椅子=内存块,人们=可变

结构 :如果有3人,他们可以在自己的大小坐在椅子上相应。

联盟 :如果有3人只有一个椅子将在那里坐,都需要使用同一张椅子上时,他们想坐。

从技术上讲是指:

下面提到的方案给出了一个深入了解结构和联合在一起。

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

总MAIN_STRUCT大小=的sizeof(UINT64),用于bufferaddr +的sizeof(UNIT32)工会+ 32位用于填充(取决于处理器架构)= 128个比特。 对于结构中的所有成员得到的内存块连续。

联盟得到最大尺寸构件(在此其32位)中的一个存储器块中。 内联合多一个结构所在(INNER_STRUCT)其成员得到总大小为32位(16 + 8 + 8)的存储块。 在联合任INNER_STRUCT(32位)成员数据(32位)可被访问。



Answer 8:

是的,结构和联盟之间的主要区别是一样的,你说。 结构使用其成员的所有内存和联合使用的最大的成员的内存空间。

但是,所有的不同之处在于通过使用需要的内存。 工会的最佳使用可以在我们使用的信号UNIX的过程中可以看出。 像的处理可以一次在只有一个信号采取行动。 所以,一般的声明将是:

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

在这种情况下,过程只利用所有信号的最高内存。 但如果你在这种情况下使用结构,内存使用量将是所有信号的总和。 使得很多差异的。

总之,联盟应,如果你知道你访问一次成员中的任何一个进行选择。



Answer 9:

你拥有了它,这就是全部。 但是,这样,基本上,什么是工会的意义呢?

你可以把不同类型的同一位置的内容。 你必须知道的你已经存储在工会的类型(所以往往你把它放在一个struct与类型标签......)。

为什么这很重要? 没有真正的空间收益。 是的,你可以得到一些位或做一些填充,但是这并不是一个主要问题了。

它是类型安全,它可以让你做一些一种“动态类型”的:编译器知道你的内容可能有不同的含义,它是由你在运行时你是如何解释的确切含义。 如果你有一个指针可以指向不同的类型,你必须使用一个工会,否则,你的代码可能是不正确的,由于色彩失真问题(编译器对自己说:“哦,仅此指针可以指向这种类型的,这样我就可以优化从这些访问......“,而坏事情都可能发生)。



Answer 10:

一种结构,在分配它的所有元素的总大小。

一名工会只能作为其最大的成员需要分配尽可能多的内存。



Answer 11:

联合工会的用途是经常使用的,需要特殊类型的谈话时。 为了得到工会的有用的想法。 的C / C标准库定义没有专门设计用于写短整数到一个文件的功能。 使用fwrite()将招致encurs操作简单过多的开销。 然而,使用工会您可以轻松创建它一次写一个短整型的二进制文件一个字节的功能。 我认为short整数是2字节长

这个例子:

#include<stdio.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

虽然putw()1短整数叫,这是possble使用putc将()和fwrite()。 但我想展示一个例子来dominstrate工会如何使用



Answer 12:

结构是不同的数据类型的集合,其中不同类型的数据可以驻留在它和每一个获得自己的内存块

我们平时使用时,工会我们确信,只有变量的一个会被立即使用,并且希望充分利用当前内存的,因为它只能得到一个内存块等于最大的类型。

struct emp
{
    char x;//1 byte
    float y; //4 byte
} e;

总存储器它获得=> 5字节

union emp
{
    char x;//1 byte
    float y; //4 byte
} e;

总存储器它获得= 4字节



Answer 13:

是什么结构和工会之间的区别?

剪短回答是:尊重是在内存分配。 说明:在结构上,内存空间会为内部结构的所有成员创建。 在工会的存储空间将仅适用于需要大存储空间的成员创建。 考虑下面的代码:

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

这里面有struct和union两个成员:int和长整型。 对于int存储器空间为:对于长整型4字节和存储空间是:8在32位操作系统。

因此,对于结构而8个字节将用于联合创建4 + 8 = 12个字节将被创建

代码示例:

#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/



Answer 14:

工会来得心应手,而写这在下文中给出一个字节排序功能。 这是不可能的结构。

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.


Answer 15:

甲联盟是从一个结构不同的联盟再次比其他:它重新定义相同的存储器,同时该结构限定了一个在另一个之后,没有重叠或重新定义。



文章来源: Difference between a Structure and a Union
标签: c struct unions