C 语言中的联合体



C 语言中的联合体

在 C 语言中,联合体是一种特殊的数据类型,它允许在同一个内存位置存储不同的数据类型。您可以定义一个包含多个成员的联合体,但在任何给定时间,只有一个成员可以包含值。联合体提供了一种有效的方式,可以使用同一个内存位置来实现多种用途。

联合体的所有成员共享同一个内存位置。因此,如果我们需要对两个或多个成员使用同一个内存位置,那么联合体就是最适合的数据类型。最大的联合体成员决定了联合体的大小。

定义联合体

联合体变量的创建方式与结构体变量相同。关键字union用于在 C 语言中定义联合体。

语法

以下是 C 语言中定义联合体的语法:

union [union tag]{
   member definition;
   member definition;
   ...
   member definition;
} [one or more union variables];  

“联合体标签”是可选的,每个成员定义都是一个正常的变量定义,例如“int i;”、“float f;”或任何其他有效的变量定义。

在联合体定义的末尾,在最后一个分号之前,您可以指定一个或多个联合体变量。

访问联合体成员

要访问联合体的任何成员,我们使用成员访问运算符(.)。成员访问运算符被编码为联合体变量名和我们想要访问的联合体成员之间的句点。您将使用关键字 union 来定义联合体类型的变量。

语法

以下是 C 语言中访问联合体成员的语法:

union_name.member_name;

联合体成员的初始化

您可以通过使用赋值 (=) 运算符为其赋值来初始化联合体的成员。

语法

以下是初始化联合体成员的语法:

union_variable.member_name = value;

示例

以下代码语句显示了如何初始化联合体“data”的成员“i”:

data.i = 10;

联合体的示例

示例 1

以下示例演示了如何在程序中使用联合体:

#include <stdio.h>
#include <string.h>

union Data{
   int i;
   float f;
   char str[20];
};

int main(){
   union Data data;        
   
   data.i = 10;
   data.f = 220.5;
   strcpy(data.str, "C Programming");
   
   printf("data.i: %d \n", data.i);
   printf("data.f: %f \n", data.f);
   printf("data.str: %s \n", data.str); 
   return 0;
}

输出

当编译并执行上述代码时,会产生以下结果:

data.i: 1917853763 
data.f: 4122360580327794860452759994368.000000 
data.str: C Programming

在这里,我们可以看到if(联合体的成员)的值显示为垃圾值,因为分配给变量的最终值已占据了内存位置,这就是str成员的值能够正确打印的原因。

示例 2

现在让我们再次看看同一个示例,在其中我们将一次使用一个变量,这是使用联合体的主要目的:

#include <stdio.h>
#include <string.h>

union Data{
   int i;
   float f;
   char str[20];
};

int main(){
   
   union Data data;        
   
   data.i = 10;
   printf("data.i: %d \n", data.i);
   
   data.f = 220.5;
   printf("data.f: %f \n", data.f);
   
   strcpy(data.str, "C Programming");
   printf("data.str: %s \n", data.str);
   return 0;
}

输出

当编译并执行上述代码时,会产生以下结果:

data.i: 10 
data.f: 220.500000 
data.str: C Programming

在这里,所有联合体成员的值都能够正确打印,因为每次只使用了一个成员。

联合体的大小

联合体的大小是其最大成员的大小。例如,如果一个联合体包含两个charint类型的成员。在这种情况下,联合体的大小将是int的大小,因为int是最大的成员。

您可以使用sizeof() 运算符来获取联合体的大小。

示例

在下面的示例中,我们打印了一个联合体的大小:

#include <stdio.h>

// Define a union
union Data {
   int a;
   float b;
   char c[20];
};

int main() {
   union Data data;

   // Printing the size of the each member of union
   printf("Size of a: %lu bytes\n", sizeof(data.a));
   printf("Size of b: %lu bytes\n", sizeof(data.b));
   printf("Size of c: %lu bytes\n", sizeof(data.c));

   // Printing the size of the union
   printf("Size of union: %lu bytes\n", sizeof(data));

   return 0;
}

输出

当您编译并执行代码时,它将产生以下输出:

Size of a: 4 bytes
Size of b: 4 bytes
Size of c: 20 bytes
Size of union: 20 bytes

结构体和联合体的区别

在 C 编程中,结构体和联合体都是复合数据类型。结构体和联合体之间最显著的区别在于它们存储数据的方式。结构体将每个成员存储在单独的内存位置,而联合体将所有成员存储在同一个内存位置。

以下是一个名为myunion的联合体类型的定义:

union myunion{ 
   int a;
   double b;
   char c;
};

联合体的定义类似于结构体的定义。具有相同元素的“struct type mystruct”的定义如下所示:

struct mystruct{
   int a;
   double b;
   char c;
};

结构体和联合体之间的主要区别在于变量的大小。编译器为结构体变量分配内存,以便能够存储所有元素的值。在mystruct中,有三个元素:一个 int、一个 double 和一个 char,需要 13 个字节 (4 + 8 + 1)。因此,sizeof(struct mystruct)返回 13。

另一方面,对于联合体类型变量,编译器分配一块内存,其大小足以容纳字节大小最大的元素。myunion类型具有 int、double 和 char 元素。在这三个元素中,double 变量的大小最大,即 8。因此,sizeof(union myunion)返回 8。

另一个需要考虑的要点是,联合体变量只能保存其一个元素的值。当您为一个元素赋值时,其他元素未定义。如果您尝试使用其他元素,则会导致一些垃圾数据。

示例 1:联合体占用的内存

在下面的代码中,我们定义了一个名为Data的联合体类型,它具有三个成员ifstrData类型的变量可以存储一个整数、一个浮点数或一个字符字符串。这意味着单个变量(即同一个内存位置)可以用来存储多种类型的数据。您可以根据需要在联合体中使用任何内置或用户定义的数据类型。

联合体占用的内存将足够大,以容纳联合体中最大的成员。例如,在上面的示例中,Data将占用 20 个字节的内存空间,因为这是字符字符串可以占用的最大空间。

以下示例显示了上述联合体占用的总内存大小:

#include <stdio.h>
#include <string.h>

union Data{
   int i;
   float f;
   char str[20];
};

int main(){
   union Data data;        
   printf("Memory occupied by Union Data: %d \n", sizeof(data));
   return 0;
}

输出

当您编译并执行代码时,它将产生以下输出:

Memory occupied by Union Data: 20

示例 2:结构体占用的内存

现在,让我们创建一个具有相同元素的结构体,并检查它在内存中占用了多少空间。

#include <stdio.h>
#include <string.h>

struct Data{
   int i;
   float f;
   char str[20];
};

int main(){
   struct Data data;        
   printf("Memory occupied by Struct Data: %d \n", sizeof(data));
   return 0;
}

输出

此结构体将占用 28 个字节 (4 + 4 + 20)。运行代码并检查其输出:

Memory occupied by Struct Data: 28
广告