#C数据结构  联合体union

来源:互联网 发布:淘宝积分有什么用处 编辑:程序博客网 时间:2024/06/05 21:12
1.联合体概述      
      联合体在C语言中是一种数据结构,它在形式上与结构体相似,与结构体的区别在于:编译器为结构体分配的内存为结构体内各变量内存之和,为联合体分配的内存为联合体里面内存占用最大的变量的内存。这就意味着你只能为联合体中的某一个变量赋值,现赋值现用,如果再为其它变量赋值时,之前那个变量的值也就不存在了。而在结构体中,你可以为每一个成员赋值,需要哪个就用哪个。

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

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

main()
{
   struct
   {
     char name[10];
      intage;
     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\tagejob 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{        

    charbj[5];

    intbh[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


 

原创粉丝点击