#C数据结构  联合体union

本文详细介绍了C语言中的联合体(Union),包括其定义、使用方法及实例,并通过实例展示了联合体如何帮助节省内存。此外,还探讨了联合体与结构体在内存分配上的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.联合体概述      
       联合体在C语言中是一种数据结构,它在形式上与结构体相似,与结构体的区别在于:编译器为结构体分配的内存为结构体内各变量内存之和,为联合体分配的内存为联合体里面内存占用最大的变量的内存。这就意味着你只能为联合体中的某一个变量赋值,现赋值现用,如果再为其它变量赋值时,之前那个变量的值也就不存在了。而在结构体中,你可以为每一个成员赋值,需要哪个就用哪个。

2.常用的使用方法
 第一种,先定义联合体类型,再定义联合体变量:
    union 类型名
{
  成员表列;
   
};
union 类型名  变量名; 
第二种,定义联合体类型的同时声明联合体变量
union 类型名
成员表列;
}变量名;

3.联合体例程
       设有一个教师与学生通用的表格,教师数据有姓名,年龄,职业,教研室四项。学生有姓名,年龄,职业,班级四项。编程输入人员数据, 再以表格输出。

main()
{
   struct
   {
      char name[10];
      int age;
      char job;                                  //一个字符型变量,老师为't',学生为's'
      union
      {
         int class;
         char office[10];
      } depa;                                    //定义depa为联合体,代表地点,老师的地点是教研室,学生的地点为教室    
   }body[2];
   int n,i;
   for(i=0;i<2;i++)
   {
      printf("input name,age,job and department\n");  
      scanf("%s %d %c",body[i].name,&body[i].age,&body[i].job);               //输入姓名、年龄、职业
      if(body[i].job=='s')                            
         scanf("%d",&body[i].depa.class);                             //如果输入为s,则继续输入教室的编号,类型为整型
      else
         scanf("%s",body[i].depa.office);                                //否则继续输入办公室名称,类型为字符型
   }
   printf("name\tage job class/office\n");                             //打印上面输入的各项内容
   for(i=0;i<2;i++)
   {
   if(body[i].job=='s')                                                          //如果job是s,即学生,则打印的内容包含教室的编号
      printf("%s\t= < %d\n",body[i].name,body[i].age ,body[i].job,body[i].depa.class);
   else                                                                                  //否则,即老师,则打印的内容包含办公室名称
      printf("%s\t= < %s\n",body[i].name,body[i].age, body[i].job,body[i].depa.office);
   }    //请大家不要被这个if语句迷惑了,不要认为class和office这两个变量都存在,就等着我们去选择了,
}         //它们中只能存在一个,我们在之前的输入中也只是输入了一个变量
 
       在这个例程中,我们就可以发现联合体的优点了,如果上述例程中不用联合体,那么就得定义两个数组,这明显浪费内存。
       关于联合体的优点我只是在上面的程序里找到了答案,但我认为联合体存在的意义不只是这些,欢迎有兴趣的朋友和我讨论,欢迎对联合体理解较深刻的游客赐教。

4.联合体的内存分配(结合结构体讲解)
要理解这个问题,首先要明白“对齐”的概念,为了提高 CPU 的存储速度,编译器会对一些变量的起始地址做了“对齐”处理。
规则1.每一个成员的偏移量必须是自己单位内存长度的倍数,不是的话在前面补齐后再分配地址
规则2.数据整体的长度必须是最大分配内存成员长度的倍数,分配到最后一个变量时,如果此时数据整体的长度不是最大分配内存成员长度的倍数,那么在其后分配空地址进行补齐。
这么讲比较抽象,看下面例子:

struct stu 

  union{          

    char bj[5];

    int bh[2];

  }class; 

  char xm[8];    

  float cj;     

}xc;

请问这个结构体占用多少字节呢?

分析:首先看联合体中分配的是占用内存最大的成员 bj[5],所以是5个字节,但是整型是2个字节,应用规则2,所以必须补齐值6个字节,然后联合体后面又为xm[8]分配8个字节,因为单位char是1个字节,而位移量6是1的倍数,所以此时用不到规则1,然后继续向后分配,float浮点型数据是4个字节,但是此时偏移量为14,并不是4的倍数,应用规则1,将偏移量补至16,然后再为cj分配4个字节,所以整个结构体的字节数为20.


注:此博文参考地址

http://www.360doc.com/content/15/1017/00/28355801_506186137.shtml

http://www.vcan123.com/forum.php?mod=viewthread&tid=1111


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值