有什么好的例子可以说明结构体和联合体的区别吗? 基本上我知道struct使用了它成员的所有内存,而union使用了最大的成员内存空间。还有其他操作系统级别的差异吗?


当前回答

结构分配其中所有元素的总大小。

一个联合只分配它最大的成员所需要的内存。

其他回答

有什么好的例子可以说明“结构体”和“联合体”之间的区别吗?

一种假想的通信协议

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

在这个假想的协议中,已经指定了基于“消息类型”的消息头中的下面位置要么是请求号,要么是四个字符的代码,但不是两者都是。简而言之,联合允许相同的存储位置表示多个数据类型,可以保证您在任何时候只希望存储其中一种类型的数据。

联合在很大程度上是基于C作为系统编程语言的传统的低级细节,其中“重叠”存储位置有时以这种方式使用。如果数据结构一次只保存几种类型中的一种,则有时可以使用联合来节省内存。

一般来说,操作系统不关心或不知道结构体和并体——它们都只是内存块。struct是存储多个数据对象的内存块,这些对象不重叠。联合是存储多个数据对象的内存块,但只能存储其中最大的一个,因此在任何时候只能存储其中一个数据对象。

在编写下面给出的字节排序函数时,联合非常方便。这在结构体中是不可能的。

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.

联合的用法 当需要特殊类型的对话时,联合经常被使用。 来了解联合的用处。c/c标准库没有定义专门为将短整数写入文件而设计的函数。使用fwrite()会导致简单操作的开销过大。然而,使用联合可以很容易地创建一个函数,该函数将一个短整数的二进制每次一个字节写入文件。我假设短整数是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(),但可以使用putc()和fwrite()。但是我想展示一个例子来说明如何使用联合

是的,struct和union之间的主要区别和你说的一样。 Struct使用其成员的所有内存,union使用最大的成员内存空间。

但所有的区别在于使用内存的需要。 在unix的进程中可以看到联合的最佳使用,在那里我们使用信号。 比如一个进程一次只能作用于一个信号。 所以一般声明是:

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

在这种情况下,进程只使用所有信号中最高的内存。 但如果在这种情况下使用struct,内存使用量将是所有信号的总和。 有很大的不同。

总之,如果您知道一次访问任何一个成员,则应该选择Union。

你拥有它,仅此而已。 那么,工会的意义是什么呢?

您可以在相同的位置中放入不同类型的内容。你必须知道你在联合中存储的东西的类型(所以你经常把它放在一个带有type标签的结构体中…)

为什么这很重要?并不是为了获得空间。是的,你可以获得一些位或做一些填充,但这已经不是重点了。

这是为了类型安全,它允许你做某种“动态类型”:编译器知道你的内容可能有不同的含义,你如何解释它的确切含义取决于你在运行时。如果你有一个指针可以指向不同的类型,你必须使用联合,否则你的代码可能会因为别名问题而不正确(编译器会对自己说“哦,只有这个指针可以指向这种类型,所以我可以优化这些访问……”,糟糕的事情可能会发生)。