精华内容
参与话题
问答
  • 共用体union详解

    万次阅读 多人点赞 2014-07-28 13:23:36
    需要使用共用体数据结构 例把一个整型变量一个字符型变量一个实型变量放在同一个地址开始的内存单元中 共用体的定义形式 union 共用体名 成员列表 变量列表 注意区分 共用体各成员占相同的起始地址所占内存长度等于...

    共用体的概念

    当需要把不同类型的变量存放到同一段内存单元或对同一段内存单元的数据按不同类型处理则

    需要使用共用体数据结构

    例把一个整型变量一个字符型变量一个实型变量放在同一个地址开始的内存单元中

    共用体的定义形式

    union 共用体名

    成员列表

    变量列表

    注意区分

    共用体各成员占相同的起始地址所占内存长度等于最长的成员所占内存

    结构体各成员占不同的地址所占内存长度等于全部成员所占内存之和

     

    共用体变量的引用

    只能引用共用体变量的成员如

     union data a;

     a.i;

     a.ch;

     a.f;

    共用体类型数据的特点

    共用体变量中的值是最后一次存放的成员的值如

    a.i = 1;

    a.ch = 'a';

    a.f = 1.5;

    完成以上三个赋值语句后共用体边量的值是 1.5而 a.i=1 和 a.ch='a'已无意义

    共用体变量不能初始化例

    union data

    {

    int i;

    char ch;

    float f;

    }a={1,'a', 1.5}  错误!!!

     

    共用体常用来节省内存,特别是一些嵌入式编程,内存是非常宝贵的!

    共用体也常用于操作系统数据结构或硬件数据结构!

    union在操作系统底层的代码中用的比较多,因为它在内存共赏布局上方便且直观。所以网络编程,协议分析,内核代码上有一些用到union都比较好懂,简化了设计。

     

     

     

    妙用实例

     

    1. 为了方便看懂代码。

    比如说想写一个3 * 3的矩阵,可以这样写:
    [ 注:下面用红色部分标记的地方是后来添加上去的,谢谢yrqing718的提醒!]

    1. struct  Matrix
    2. {
    3.     union
    4.     {
    5.         struct
    6.         {
    7.             float  _f11, _f12, _f13, _f21, _f22, _f23, _f31, _f32, _f33;
    8.         };
    9.         float  f[3][3];
    10.     }_matrix;
    11. };
    12.  
    13. struct  Matrix m;
    14.  


    这两个东西共同使用相同的空间,所以没有空间浪费,在需要整体用矩阵的时候可以用
    m._matrix.f
    (比如说传参,或者是整体赋值等);需要用其中的几个元素的时候可以用m._matrix._f11那样可以避免用m.f[0][0](这样不大直观,而且容易出错)。

    2. 用在强制类型转换上(比强制类型转换更加容易看懂)
    下面举几个例子:

    (1). 判断系统用的是big endian 还是 little endian(其定义大家可以到网上查相关资料,此略)


    1. #define TRUE 1
    2. #define FALSE 0
    3. #define BOOL int


    4.  
    5. BOOL  isBigEndian()
    6. {
    7.     int  i = 1;   /* i = 0x00000001*/
    8.     char  c = *(char  *)&i; /* 注意不能写成 char c = (char)i; */
    9.     return  (int )c != i;
    10. }

    如果是little endian字节序的话,那个i = 1;的内存从小到大依次放的是:0x01 0x00 0x00 0x00,如是,按照i的起始地址变成按照char *方式(1字节)存取,即得c = 0x01
    反之亦然

    也许看起来不是很清晰,下面来看一下这个:

    1. BOOL  isBigEndian()
    2. {
    3.     union
    4.     {
    5.         int  i;
    6.         char  c;
    7.     }test;
    8.     
    9.     test.c = 2;
    10.  
    11.     return  test.i != 2;
    12. }

    这里用的是union来控制这个共享布局,有个知识点就是union里面的成员ci都是从低地址开始对齐的。同样可以得到如此结果,而且不用转换,清晰一些。

    什么,不觉得清晰??那再看下面的例子:

    2.little endian下的long long类型的值换成 big endian类型的值。已经知道系统提供了下面的apilong htonl(long lg);作用是把所有的字节序换成大端字节序。因此得出下面做法:

    1. long  long  htonLL(long  long  lg)
    2. {
    3.     union  
    4.     {
    5.         struct  
    6.         { 
    7.             long  low;
    8.             long  high;
    9.         }val_1;
    10.         long  long  val_2;
    11.     }val_arg, val_ret;
    12.  
    13.  
    14.     if ( isBigEndian() )
    15.         return  lg;
    16.     val_arg.val_2 = lg;
    17.  
    18.  
    19.     val_ret.val_1.low = htonl( val_arg.val_1.high );
    20.     val_ret.val_1.high = htonl( val_arg.val_1.low );    
    21.  
    22.     return  val_ret.val_2;
    23. }

    只要把内存结构的草图画出来就比较容易明白了。

    (3).
    为了理解c++类的布局,再看下面一个例子。有如下类:

    1. class  Test
    2. {
    3. public :
    4.     float  getFVal(){ return  f;}
    5. private :
    6.     int  i;
    7.     char  c;
    8.     float  f;
    9. };
    10. Test t;

     

    不能在类Test中增加代码,给对象中的f赋值7.0f.

    1. class  Test_Cpy
    2. {
    3.  public :
    4.     float  getVal(){ return  f;}
    5.     float  setVal(float  f){ this ->f = f;}
    6. private :
    7.     int  i;
    8.     char  c;
    9.     float  f;
    10. };
    11.  
    12. ....
    13.  
    14. int  main()
    15. {
    16.     Test t;
    17.     union
    18.     {
    19.          Test t1, 
    20.          Test_Cpy t2;
    21.     }test;
    22.  
    23.     test.t2.setVal(7.0f);
    24.     t = test.t1;
    25.     assert( t.getVal() == 7.0f );   
    26.  
    27.     return  0;
    28. }

    说明:因为在增加类的成员函数时候,那个类的对象的布局基本不变。因此可以写一个与Test类一样结构的类Test_Cpy,而多了一个成员函数setVal,再用uinon结构对齐,就可以给私有变量赋值了。(这种方法在有虚机类和虚函数机制时可能失灵,故不可移植)至于详细的讨论,网上有,这个例子在实际中没有用途,只是用来考察这个内存布局的使用而已.

     4 

    1. 在嵌入式系统开发中,有时需要将一些变量存储在EEPROM中,变量类型若是char、int就很好办,可是如果要存储float、double类型的变量怎么办呢?

      这个问题可以用共用体解决:

      union myfloat

      {

          char i[4];

          float j;

      }Test;

      因为float是四个字节,因此我们定义一个4个元素的char数组和float公用一段内存,接下来就是EEPROM存取了

    2. 2

      在程序中要使用 j 的地方使用Test.j就行了,

      想把 j 存入EEPROM可以这样:

      EEPROM_WRITE(0,myfloat.i[0]);

      EEPROM_WRITE(1,myfloat.i[1]);

      EEPROM_WRITE(2,myfloat.i[2]);

      EEPROM_WRITE(3,myfloat.i[3]);

      注:上面参数0、1、2、3为EEPROM地址,上面的EEPROM_WRITE只是示意,有时需要对地址使用(void*)进行类型转换

    3. 3

      想把 j 从EEPROM读出可以这样:

      myfloat.i[0]=EEPROM_READ(0);

      myfloat.i[1]=EEPROM_READ(1);

      myfloat.i[2]=EEPROM_READ(2);

      myfloat.i[3]=EEPROM_READ(3);

      然后在程序中继续使用Test.j就可以了

      是不是很简单呢

    展开全文
  • C 语言 共用体(联合体)union

    千次阅读 多人点赞 2018-06-07 14:23:14
    几个不同的变量共享一段内存的结构,称为“共用体”类型的结构。 定义共用体类型变量的一般形式为: union 共用体名 {  成员表列 }变量表列; 例如: union Data { int i; //表示不同类型的变量i,ch,f可以...

    几个不同的变量共享一段内存的结构,称为“共用体”类型的结构。

    定义共用体类型变量的一般形式为:

    union 共用体名
    {
        成员表列
    }变量表列;

    例如:

    union Data
    {
        int i;        //表示不同类型的变量i,ch,f可以存放到同一段存储单元中
        char ch;
        float f;
    }a, b, c;        //变量

    在地址空间中表示如下图:

    以上3个变量在内存中占的字节数不同,但都是从同一地址开始(图中设为1000)存放,也就是使用覆盖技术,后一个数据覆盖了前面的数据。

      共用体类型数据的特点:

    (1)同一内存段可以用来存放几种不同类型的成员,但在每一瞬间只能存放其中一个成员,而不是同时存放几个。

    union Data
    {
        int i;        //表示不同类型的变量i,ch,f可以存放到同一段存储单元中
        char ch;
        float f;
    }a, b, c;        //变量
    a.i = 97;

    表示将整数97存放在共用体变量中,输出结果如下。

            

    97换成16进制为0x00000061,又因为电脑的存储方式为小端格式,所以在地址中存在的方式如下图

            

    因为float的存储方式不同,解码时会按照独自的方式计算解码(可自行搜索float类型数据在内存中的存储方式),所以输出为0.00000。

    当a.f = 0x61;时,输出入下图:(打印a.ch时,因为0x0不能用字符打印,所以用的整型,效果一样)

            

    存储方式为:

            

    所以float类型97存储的十六进制为0x42C20000。

    (2)可以对共用体变量初始化,但初始化表中只能有一个常量。

    union Data
    {
        int i;        //表示不同类型的变量i,ch,f可以存放到同一段存储单元中
        char ch;
        float f;
    }a = {1,'a',1.5};              //不能初始化3个成员,他们占用同一段存储单元
    union Data a = {16};           //正确,对第一个成员初始化
    union Data a = {.ch = 'j'};    //C99允许对指定的一个成员初始化
    

    (3)共用体变量中起作用的成员是最后一次被赋值的成员,在对共同体变量中的一个成员赋值后,原有变量存储单元中的值就被取代。

    (4)共用体变量的地址和它的个成员的地址都是同一个地址。例如:&a.i,&a.ch,&a.f都是同一值。

            

    (6)共用体类型可以出现结构体类型定义中,也可以定义共用体数组。结构体中也可以出现在共用体类型定义中,数组也可以作为共用体成员。

    用途:

    在数据处理中,需要对同一空间安排不同的用途,使用共同体比较方便。

        例:有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一表格来处理。

        可以看出:学生和老师的数据的项目大多数是相同的,只有一个不同,学生的班级,教师的职位。

    struct{
        int num;          //成员 编号
        char name[10];    //成员 姓名
        char sex;         //成员 性别
        union{            //声明无名共用体类型
            int class;    //成员 班级
            char position[10];//成员 职务
        }category;
    }person[2];

     

    展开全文
  • C语言基础:共用体

    2019-02-23 20:30:57
    共用体和结构体不同点:1,同一时刻,共用体中只存放一个被选中的成员,结构体的所有成员都存在,  2,对共用体的不同成员赋值,将会对其他成员重写,原来的值就不存在了,结构体不影响 共用体数据中所有成员占用...

            共用体和结构体不同点:1,同一时刻,共用体中只存放一个被选中的成员,结构体的所有成员都存在,

                                                         2,对共用体的不同成员赋值,将会对其他成员重写,原来的值就不存在了,结构体不影响

    共用体数据中所有成员占用相同的内存单元。关键字:union

    示例代码:

    1. union stu{           //定义共用体
    2.     char *name;
    3.     int num; 
    4. };
    5. void main(){
    6.     union stu *p,stuone;       //共用体指针,共用体变量
    7.     p=&stuone;                     //共用体指针,指向共用体变量
    8.     stuone.num=101;           //赋值给共用体变量的num
    9.     printf("%d\n",p->num);  //用指针输出num的值
    10. }
    11. ---------------------------------------------------------------------------------------------------
    12. //共用体指针的强制类型转换
    13. union worker{             //定义共用体
    14.     float salary;
    15.     int number;
    16. };
    17. void main(){
    18.     union worker *p, personone;       //共用体指针,共用体变量
    19.     p=&personone;                            //指针指向共用体变量
    20.     *(float *)p=4567.0;                       //强制转换为 float类型的指针
    21.     printf("\n%.2f\n",personone.salary);
    22.     *(int *)p=112;                                //强制转换为int类型的指针
    23.     printf("%d",personone.number);
    24. }
    25. ------------------------------------------------------------------------------------------------------
    26. //共用体变量的成员,共用体指针作为函数的参数传递
    27. union traffic{           //定义共用体
    28.     char *name;
    29.     int num;
    30. };
    31. void road(char *x){              //road()函数 传递char 类型指针
    32.     printf("The name of traffic is %s!\n",x);
    33. }
    34. void air(union traffic *x){    //air()函数 传递共用体指针
    35.     printf("The name of traffic is %s!\n",x->name);
    36. }
    37. void main(){
    38.     union traffic *p,traone;      //共用体指针,共用体变量
    39.     p=&traone;                        //指针指向共用体变量
    40.     traone.name="Car";         //为name赋值 
    41.     road(traone.name);          //调用road()函数
    42.     air(p);                                //调用air()函数
    43. }
    展开全文
  • 共用体

    2019-09-04 22:27:09
    共用体例题程序 《数据结构》陈越老师 #include<stdio.h> int main() { union key { int k; char ch[2]; }u; u.k=258; printf("%d\n%d\n",u.ch[0],u.ch[1]); return 0; }//编译结果如下图 课本:...

    共用体例题程序 《数据结构》陈越老师

    #include<stdio.h>
    int main()
    {
    union key
    {
    int k;
    char ch[2];
    }u;
    u.k=258;
    printf("%d\n%d\n",u.ch[0],u.ch[1]);
    return 0;
    }//编译结果如下图
    课本:看看输出结果是什么?为什么?
    我:一脸懵逼。并没有对字符数组赋值呀?
    查阅资料:

    1. 在进行某些算法的C语言编程的时候,需要把几种不同类型的变量存放到同一段内存单元中。也就是利用覆盖技术,使几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构类型,在C语言中,被称作“共用体”类型结构,简称共用体。
    2. 共用体变量中起作用的成员是最后一次存放的成员,在存入一个新成员后,原有成员就失去作用。共用体变量的地址和它的各成员的地址都是同一地址。

    说人话:共用体类型就是指将不同的数据项组织成一个整体,他们在内存中占用同一段存储单元。本程序中,共用体有两项–int变量,char数组。程序中对int赋值258.他的存储形式应为100000010.一个char字符的大小是一个字节就是8为。故char【0】=00000100.按%d输出就是2.同理char【1】=00000001.按%d输出就是1.
    在这里插入图片描述

    展开全文
  • 共用体的使用实例

    千次阅读 2018-12-07 14:21:53
    共用体的使用实例 2012年02月19日 08:48:57 yi_bunny 阅读数:1188 标签: struct编程c 更多 个人分类: C语言应用 转自http://home.eeworld.com.cn/my/space.php?uid=139222&amp;do=blog&amp;id=...
  • 共用体(联合体)

    2018-11-14 22:14:42
    共用体(联合体) #include &lt;stdio.h&gt; union Test { unsigned char a; unsigned short b; unsigned int c; }; int main(int argc, char const *argv[]) { //1、结构体的大小可以简单认为成员...
  • 共用体数据类型是指将不同的数据项组织为一个整体,它和结构体有些相似之处,但是共用体在内存中占用首地址相同的一段存储单元。 共用体的定义与声明 1. 共用体的一般定义形式 union typename { type1 var1 ; type...
  • C语言共用体(Union)

    千次阅读 多人点赞 2018-10-18 18:06:20
    C语言共用体(Union) 在C语言中,有一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: union 共用体名{  成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 ...
  • C语言第10课——共用体

    千次阅读 2018-11-24 21:59:27
    共用体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。 可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。 共用体提供了一种使用相同的内存位置的有效方式。 #include &...
  • 共用体的定义与应用详细解析

    千次阅读 2013-10-07 11:45:30
    共同的定义类似结构体,不过共同的所有成员都在同一段内存中存放,起始地址一样,并且同一时刻只能使用其中的一个成员变量 定义: 使用覆盖技术,几个变量相互覆盖,从而使几个不同变量共...
  • C语言共用体

    2019-03-15 00:01:31
    共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。 union 共用体和...
  • C语言共用体的作用

    2018-04-04 13:07:00
    C语言共用体的作用 一、介绍 1、共用体(Union),它的定义格式为: union 共用体名{ 成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 2、结构体和共用体的...
  • C语言共用体类型(union)

    千次阅读 2017-06-20 22:33:06
    共用体类型的定义:用同一段内存单元存放不同类型的指针变量。 使用类似覆盖技术,后一个数据覆盖了前面的数据,使几个不同的变量共享同一段同一段内存的结构。 定义共用体类型变量的一般形式为: union ...
  • c语言共用体对齐

    千次阅读 2010-10-10 15:42:00
    还从网上找到共用体内存分配原则的文章,下面列几个例子说明:1.Union data1{ double d;...在编译器默认设置的情况下,该共用体最大基本类型为double,它占8字节,所以此共用体以8来对齐。字符数组c2占9个字节
  • C语言 结构体、共用体

    千次阅读 多人点赞 2018-07-21 15:30:15
    C语言 结构体、共用体 一、简述  对结构体、共用体的认识。  结构体是一种自定义的复合数据类型。  类比数组,数组也算一种复合数据类型,数组是由多个由相同数据类型的元素组成,(比如需要记录描述100个人的...
  • C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: union 共用体名{ 成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 结构体和共用体的...
  • C语言共用体和与结构体的区别

    千次阅读 2016-12-21 22:58:23
    共用体与结构体的区别共用体: 使用union 关键字 共用体内存长度是内部最长的数据类型的长度。 共用体的地址和内部各成员变量的地址都是同一个地址结构体大小: 结构体内部的成员,大小等于最后一个成员的偏移量...
  • #include main() { union data { long w; float x; char c; }; 执行下列语句后a的十进制值是多少? union data a; a.x=3.1416; a.w=123456; a.c='x';
  • *5. (选做题) 给定n个描述,每个描述包含一个类型标志和- -组相应的数据。类型 标志共3种: NT DOUBLE STRING,然后对应- -组相应的数据。要求输出第m个描述的 类型输出数据。 要求:输入的第一行为两个整数,n和m,(n...
  • c语言共用体的内存分布

    千次阅读 2013-05-18 23:45:19
    #include using namespace std; union { unsigned char a; unsigned int i; }u; int main() { u.i = 0xf0f1f2f3; cout; cout(u.a); return 0; }   程序的输
  • C语言 共用体

    2017-09-14 10:49:12
    几个不同各类型的变量共占一段内存,他们是重叠的关系# include <stdio.h>//引用函数库 # include ... //共用体大小必须大于最大成员类型,且一定是最小类型的整数倍 printf("%d\n",sizeof(union
  • C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: union 共用体名{ 成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 结构体和共用体的...
  • C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为: union 共用体名{ 成员列表 }; 共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。 结构体和共用体的区别...
  • 共用体,也叫联合体,使不同类型的变量共占一段内存的空间(相互覆盖) 共用体的定义: union 共用体 { }; 共用体的初始化与赋值方式与结构体相同。 但任何时刻,共用体只有一个成员变量能够存在。 共用体的大小...
  • C语言共用体

    2018-07-13 11:22:22
    共用体作用节省内存,有两个很长的数据结构,不会同时使用,比如一个表示老师,一个表示学生,如果要统计教师和学生的情况用结构体的话就有点浪费了!用共用体的话,只占用最长的那个数据结构所占用的空间,就足够了...
  • 共用体类型同结构体类型一样,都属于构造类型,它在定义上与结构体类型十分相似,定义共用体类型的语法格式如下: union 共用体类型名称 { 数据类型 成员1; 数据类型 成员2; 。。。 数据类型 成员n; }...
  • C语言共用体类型)

    2017-12-27 07:09:52
    使几个不同的变量共享同一段内存的结构,称为 “共用体” 类型的结构。 1、不同类型的变量共同占用一段内存(相互覆盖),联合变量任何时刻只有一个成员存在,节省内存 2、联合体变量的大小=最大的成员所占的字节数 ...
  • C语言中的共用体

    千次阅读 2018-05-10 16:51:15
    这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体。 也叫 联合体。 共用体变量的地址和它的各成员的地址都是同一地址。其所占内存,与占用内存最大的成...
  • C语言_共用体类型

    2020-07-07 14:50:48
    1.什么是共用体类型 使用同一段内存单元存放不同类型的变量称为共用体 union 共用体 { 成员列表 }变量表列; 三种方式定义 union Data { int i; char ch; float f; }a,b,c; union Data { int i; char ...
  • C语言共用体

    千次阅读 2014-05-16 10:03:27
    原文链接:... 定义 使几个不同的变量共占同一段内存的结构称为 “共用体”类型的结构.   定义共用体类型变量: union 共用体名  {   成员表列  

空空如也

1 2 3 4 5 ... 20
收藏数 45,454
精华内容 18,181
关键字:

共用体