【C语言】共用体union:
- 也称联合体。同一个内存空间用于多个数据的存储。
- 同一时间只能存储一个成员数据。
- 使用内存覆盖技术。新的成员数据会覆盖原来的成员数据。
- 内存大小是最大的成员占用内存大小,且是最大对齐数的整数倍,若不足整数倍,将填充字节补齐。
1、定义共用体类型
- 关键字union。
- 包括共用体名、共用体成员。共用体成员由成员类型、成员变量名组成。
- 最后末尾的分号";"不能省略。
// 定义名为person的共用体,成员有字符串name,整数int,字符串指针job
union person
{char name[20];int age;char *job;
};2、共用体变量
(2-1)定义共用体变量
- 定义共用体类型后,定义共用体变量。可以定义一个或多个共用体变量。
union person
{char name[20];int age;char *job;
};union person p1;             // 定义一个共用体变量
union person p1, p2, p3;     // 定义多个共用体变量- 定义共用体类型时,同时定义共用体变量。可以定义一个或多个共用体变量。
union person
{char name[20];int age;char *job;
} p;                     // 定义共用体类型时,定义一个共用体变量union person
{char name[20];int age;char *job;
} p1, p2, p3;            // 定义共用体类型时,定义多个共用体变量(2-2)访问共用体成员
- 使用成员访问运算符(".")来访问共用体的成员。
#include <stdio.h>
#include <string.h>union person
{char name[20];int age;char *job;
};int main(void)
{union person p;strcpy(p.name, "John");           // 成员name的值为Johnp.age = 18;                       // 成员age的值覆盖原来成员name的值  p.job = "programer";              // 成员job的值覆盖原来成员age的值printf("p.name is %s\n", p.name);printf("p.age is %d\n", p.age);printf("p.job is %s\n", p.job);return 0;
}// 结果:
p.name is                            // 数据被新数据覆盖,该数据已损坏
p.age is 4210688                     // 数据被新数据覆盖,该数据已损坏
p.job is programer                   // 最后的数据占据内存- 若是指针,使用箭头运算符("->")来访问共用体的成员。
#include <stdio.h>
#include <string.h>union person
{char name[20];int age;char *job;
};int main(void)
{union person *p, p1;p = &p1;                           // 指针p指向共用体p1strcpy(p->name, "John");           // 成员name的值为Johnp->age = 18;                       // 成员age的值覆盖原来成员name的值  p->job = "programer";              // 成员job的值覆盖原来成员age的值printf("p point to p1, name is %s\n", p->name);printf("p point to p1, age is %d\n", p->age);printf("p point to p1, job is %s\n", p->job);return 0;
}// 结果:
p point to p1, name is                // 数据被新数据覆盖,该数据已损坏
p point to p1, age is 4210688         // 数据被新数据覆盖,该数据已损坏
p point to p1, job is programer       // 最后的数据占据内存3、共用体大小:
- 共用体的内存大小是最大的成员占用内存大小。
- 共用体的内存大小是最大对齐数的整数倍,若不足整数倍,将填充字节补齐。
#include <stdio.h>union person
{char name[20];        // 字符串name:20字节int age;              // 整数int:4字节char *job;            // 字符串指针job:8字节(64位的计算机)
};int main(void)
{union person p;printf("p memory size is %d bytes\n", sizeof(p));return 0;
}// 结果:
p memory size is 24 bytes    //最大成员内存大小为20,不足最大对齐数的整数倍,填充字节补齐4、共用体作为结构体的成员
注:数组名就是内存地址(数组第一个元素的内存地址)。整数的内存地址需用&获取(&整数变量名)。
字符数组通常用于表示字符串。字符串名也是内存地址(字符串第一个元素的内存地址)。
#include <stdio.h>
#include <string.h>struct person                 // 结构体
{char name[20];int age;char job[16];union                     // 共用体, language或者place,只能提供一个数据{char language[16];char place[16];}lp;                      // 共用体变量名lp
}p[2];                        // 结构体数组pint main(void)
{// 根据用户输入,写入数据for(int i = 0; i < 2; i++){printf("[ Input ]name age job (NO.%d): ", i+1);scanf("%s %d %s", p[i].name, &p[i].age, p[i].job);// 如果job是programmer,则提供language,否则提供placeif(strcmp(p[i].job, "programmer") == 0){printf("Input language: ");scanf("%s", p[i].lp.language);}else{printf("Input place: ");scanf("%s", p[i].lp.place);}}// 输出数据for(int i = 0; i < 2; i++){if(strcmp(p[i].job, "programmer") == 0)printf("%s, %d, %s, %s\n", p[i].name, p[i].age, p[i].job, p[i].lp.language);elseprintf("%s, %d, %s, %s\n", p[i].name, p[i].age, p[i].job, p[i].lp.place);}return 0;
}// 结果:
[ Input ]name age job (NO.1): John 18 programmer        【输入:John 18 programmer】
Input language: C                                       【输入:C】
[ Input ]name age job (NO.2): Mark 25 teacher           【输入:Mark 25 teacher】
Input place: Beijing                                    【输入:Beijing】
John, 18, programmer, C
Mark, 25, teacher, Beijing5、共用体与结构体的主要区别
| 共用体 | 结构体 | 
|---|---|
| 各成员在相同的内存位置 | 各成员在不同的内存位置 | 
| 同一时间只能存储一个成员数据 | 同一时间可以存储多个不同类型的成员数据 | 
| 新的成员数据会覆盖原来的成员数据 | 各成员的数据互不影响 | 
| 内存大小 >= 最大的成员内存大小 | 内存大小 >= 各成员内存大小之和 | 
| 关键字union | 关键字struct |