C 语言 共用体
共用体 是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。C 语言允许我们定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。
定义共用体
可以使用 union 关键字定义共用体,方式与定义结构类似。
union 语句定义了一个新的数据类型,带有多个成员。
union 语句的格式如下:
union [union tag] { member definition; member definition; ... member definition; } [one or more union variables];
- union tag 是可选的
-
每个 member definition 是标准的变量定义,比如
int i;
或者float f;
或者其他有效的变量定义。 -
在共用体定义的末尾,最后一个分号之前,您可以指定一个或多个共用体变量,这是可选的。
下面的代码定义了一个名为 Data 的共用体类型,有三个成员 i、f 和 str
union Data { int i; float f; char str[20]; } data;
Data 类型的变量可以存储一个整数、一个浮点数,或者一个字符串。这意味着一个变量(相同的内存位置)可以存储多个多种类型的数据。我们可以根据需要在一个共用体内使用任何内置的或者用户自定义的数据类型。
共用体占用的内存大小是共用体中最大的成员的占用的内存大小。例如,在上面的代码中,Data 将占用 20 个字节的内存空间,因为在各个成员中,字符串所占用的空间是最大的。
我们用一个范例来计算上面定义的共用体占用的总内存大小
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; printf( "Memory size occupied by data : %ld\n", sizeof(data)); return 0; }
编译和运行上面的程序,输出结果如下
$ gcc main.c && a.out Memory size occupied by data : 20
访问共用体成员
使用 成员访问运算符(.) 可以访问共用体的成员。
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 13; // 不管我们怎么改变这个值,最后的输出都一样 data.f = 3.14159; // 不管我们怎么改变这个值,之后的输出都一样 strcpy( data.str, "Hello www.twle.cn"); printf( "data.i : %d\n", data.i); printf( "data.f : %f\n", data.f); printf( "data.str : %s\n", data.str); return 0; }
编译和运行上面的程序,输出结果如下
$ gcc main.c && a.out data.i : 1819043144 data.f : 1143139122437582505939828736.000000 data.str : Hello www.twle.cn
我们可以看到共用体的 i 和 f 成员的值有损坏,因为最后赋给变量 sstr 的值占用了内存位置,这也是 str 成员能够完好输出的原因。
现在让我们再来看一个相同的范例,但这次我们在同一时间只使用一个变量,这也演示了设计共用体的主要目的
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 13; printf( "data.i : %d\n", data.i); data.f = 3.14159; printf( "data.f : %f\n", data.f); strcpy( data.str, "Hello www.twle.cn"); printf( "data.str : %s\n", data.str); return 0; }
编译和运行上面的范例,输出结果如下
$ gcc main.c && a.out data.i : 13 data.f : 3.141590 data.str : Hello www.twle.cn
看到了没有,看到了没有,所有的成员都能完好输出,因为同一时间只用到一个成员。