学C51的基础 10《 联 合(union) 》

发布者:江上HZ最新更新时间:2015-03-10 来源: laogu关键字:C51  union 手机看文章 扫描二维码
随时随地手机看文章
联     合(union)
    1. 联合说明和联合变量定义
    联合也是一种新的数据类型, 它是一种特殊形式的变量。
    联合说明和联合变量定义与结构十分相似。其形式为:
     union 联合名{
          数据类型 成员名;
          数据类型 成员名;
          ...
     } 联合变量名;
    联合表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型和不同长度的变量。
    下例表示说明一个联合a_bc:
     union a_bc{
          int i;
          char mm;
     };
    再用已说明的联合可定义联合变量。例如用上面说明的联合定义一个名为lgc的联合变量, 可写成:

      union a_bc lgc;

    在联合变量lgc中, 整型量i和字符mm公用同一内存位置。
    当一个联合被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。
    联合访问其成员的方法与结构相同。同样联合变量也可以定义成数组或指针,但定义为指针时, 也要用"->"符号, 此时联合访问
成员可表示成:

     联合名->成员名

    另外, 联合既可以出现在结构内, 它的成员也可以是结构。
    例如:
     struct{
          int age;
          char *addr;
          union{
               int i;
               char *ch;
          }x;
     }y[10];

    若要访问结构变量y[1]中联合x的成员i, 可以写成:

      y[1].x.i;

    若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:

      *y[2].x.ch;

    若写成"y[2].x.*ch;"是错误的。

    2. 结构和联合的区别
    结构和联合有下列区别:
    1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员, 而结构的所有成
员都存在。
    2. 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。
    下面举一个例了来加对深联合的理解。
    例4:

     main()
     {
          union{                   /*定义一个联合*/
               int i;
               struct{             /*在联合中定义一个结构*/
                    char first;
                    char second;
               }half;
          }number;
          number.i=0x4241;         /*联合成员赋值*/
          printf("%c%c ", number.half.first, mumber.half.second);
          number.half.first='a';   /*联合中结构成员赋值*/
          number.half.second='b';
          printf("%x ", number.i);
          getch();
     }

    输出结果为:
     AB
     6261

    从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII
码也将作为i 的低八位和高八位。
  ................................................................................................................
                      学C51的基础 10a《 结构(struct) 》 [cmh]
                               结构(struct)

    结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。结构中可以使用不同的数据类型。

    1. 结构说明和结构变量定义
    在Turbo C中, 结构也是一种数据类型, 可以使用结构变量, 因此, 象其它类型的变量一样, 在使用结构变量时要先对其定义。
    定义结构变量的一般格式为:
     struct 结构名
     {
          类型  变量名;
          类型  变量名;
          ...
     } 结构变量;
    结构名是结构的标识符不是变量名。
    类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。
    构成结构的每一个类型变量称为结构成员, 它象数组的元素一样, 但数组中元素是以下标来访问的, 而结构是按变量名字来访
问成员的。
    下面举一个例子来说明怎样定义结构变量。
     struct string
     {
          char name[8];
          int age;
          char sex[2];
          char depart[20];
          float wage1, wage2, wage3, wage4, wage5;
     } person;
    这个例子定义了一个结构名为string的结构变量person, 如果省略变量名person, 则变成对结构的说明。用已说明的结构名也
可定义结构变量。这样定义时上例变成:
     struct string
     {
          char name[8];
          int age;
          char sex[2];
          char depart[20];
          float wage1, wage2, wage3, wage4, wage5;
     };
     struct string person;
    如果需要定义多个具有相同形式的结构变量时用这种方法比较方便, 它先作结构说明, 再用结构名来定义变量。
    例如:
     struct string Tianyr, Liuqi, ...;
    如果省略结构名, 则称之为无名结构, 这种情况常常出现在函数内部, 用这种结构时前面的例子变成:
     struct
     {
          char name[8];
          int age;
          char sex[2];
          char depart[20];
          float wage1, wage2, wage3, wage4, wage5;
     } Tianyr, Liuqi;


    2. 结构变量的使用
    结构是一个新的数据类型, 因此结构变量也可以象其它类型的变量一样赋值、运算, 不同的是结构变量以成员作为基本变量。
    结构成员的表示方式为:
          结构变量.成员名
    如果将"结构变量.成员名"看成一个整体, 则这个整体的数据类型与结构中该成员的数据类型相同, 这样就可象前面所讲的变量
那样使用。
    下面这个例子定义了一个结构变量, 其中每个成员都从键盘接收数据, 然后对结构中的浮点数求和, 并显示运算结果, 同时将
数据以文本方式存入一个名为wage.dat的磁盘文件中。请注意这个例子中不同结构成员的访问。
    例3:
     #include < stdio.h >
     main()
     {
          struct{                       /*定义一个结构变量*/
               char name[8];
               int age;
               char sex[2];
               char depart[20];
               float wage1, wage2, wage3, wage4, wage5;
          }a;
          FILE *fp;
          float wage;
          char c='Y';
          fp=fopen("wage.dat", "w");    /*创建一个文件只写*/
          while(c=='Y' c=='y')         /*判断是否继续循环*/
          {
               printf(" Name:");
               scanf("%s", a.name);     /*输入姓名*/
               printf("Age:");
               scanf("%d", &a.wage);    /*输入年龄*/
               printf("Sex:");
               scanf("%d", a.sex);
               printf("Dept:");
               scanf("%s", a.depart);
               printf("Wage1:");
               scanf("%f", &a.wage1);   /*输入工资*/
               printf("Wage2:");
               scanf("%f", &a.wage2);
               printf("Wage3:");
               scanf("%f", &a.wage3);
               printf("Wage4:");
               scanf("%f", &a.wage4);
               printf("Wage5:");
               scanf("%f", &a.wage5);
               wage=a.wage1+a.wage2+a.wage3+a.wage4+a.wage5;
               printf("The sum of wage is %6.2f ", wage);      /*显示结果*/
               fprintf(fp, "%10s%4d%4s%30s%10.2f ",            /*结果写入文件*/
                            a.name, a.age, a.sex, a.depart, wage);
               while(1)
               {
                    printf("Continue?");
                    c=getche();
                    if(c=='Y' c=='y' c=='N' c=='n')
                         break;
               }
          }
          fclose(fp);
     }
[page]

    3. 结构数组和结构指针
    结构是一种新的数据类型, 同样可以有结构数组和结构指针。
    一、结构数组
    结构数组就是具有相同结构类型的变量集合。假如要定义一个班级40个同学的姓名、性别、年龄和住址, 可以定义成一个结构
数组。如下所示:
     struct{
          char name[8];
          char sex[2];
          int age;
          char addr[40];
     }student[40];
    也可定义为:
     struct string{
          char name[8];
          char sex[2];
          int age;
          char addr[40];
     };
     struct string student[40];
    需要指出的是结构数组成员的访问是以数组元素为结构变量的, 其形式为:
          结构数组元素.成员名
    例如:
      student[0].name
      student[30].age
    实际上结构数组相当于一个二维构造, 第一维是结构数组元素, 每个元素是一个结构变量, 第二维是结构成员。
    注意:
    结构数组的成员也可以是数组变量。
    例如:
     struct a
     {
          int m[3][5];
          float f;
          char s[20];
     }y[4];
    为了访问结构a中结构变量y[2]的这个变量, 可写成
       y[2].m[1][4]

    二、结构指针
    结构指针是指向结构的指针。它由一个加在结构变量名前的"*"操作符来定义, 例如用前面已说明的结构定义一个结构指针如下:
     struct string{
          char name[8];
          char sex[2];
          int age;
          char addr[40];
     }*student;
    也可省略结构指针名只作结构说明, 然后再用下面的语句定义结构指针。
      struct string *student;
    使用结构指针对结构成员的访问, 与结构变量对结构成员的访问在表达方式上有所不同。结构指针对结构成员的访问表示为:
       结构指针名->结构成员
    其中"->"是两个符号"-"和">"的组合, 好象一个箭头指向结构成员。例如要给上面定义的结构中name和age赋值, 可以用下面语
句:
     strcpy(student->name, "Lu G.C");
     student->age=18;
    实际上, student->name就是(*student).name的缩写形式。
    需要指出的是结构指针是指向结构的一个指针, 即结构中第一个成员的首地址, 因此在使用之前应该对结构指针初始化, 即分
配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下:
     student=(struct string*)malloc(size of (struct string));
    size of (struct string)自动求取string结构的字节长度, malloc() 函数定义了一个大小为结构长度的内存区域, 然后将其
地址作为结构指针返回。

    注意:
    1. 结构作为一种数据类型, 因此定义的结构变量或结构指针变量同样有局部变量和全程变量, 视定义的位置而定。
    2. 结构变量名不是指向该结构的地址, 这与数组名的含义不同, 因此若需要求结构中第一个成员的首地址应该是&[结构变量
名]。
    4. 结构的复杂形式
    一、嵌套结构
    嵌套结构是指在一个结构成员中可以包括其它一个结构, Turbo C 允许这种嵌套。
    例如: 下面是一个有嵌套的结构
     struct string{
          char name[8];
          int age;
          struct addr address;
     } student;
    其中: addr为另一个结构的结构名, 必须要先进行, 说明, 即
     struct addr{
          char city[20];
          unsigned lon zipcode;
          char tel[14];
     }
    如果要给student结构中成员address结构中的zipcode赋值, 则可写成:

      student.address.zipcode=200001;

    每个结构成员名从最外层直到最内层逐个被列出, 即嵌套式结构成员的表达方式是:

      结构变量名.嵌套结构变量名.结构成员名

    其中: 嵌套结构可以有很多, 结构成员名为最内层结构中不是结构的成员名。

    二、位结构
    位结构是一种特殊的结构,在需按位访问一个字节或字的多个位时,位结构比按位运算符更加方便。
    位结构定义的一般形式为:

     struct位结构名{
          数据类型 变量名: 整型常数;
          数据类型 变量名: 整型常数;
     } 位结构变量;

    其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整数, 范围是0~15, 表示二进制位的个数, 即表示有
多少位。
    变量名是选择项, 可以不命名, 这样规定是为了排列需要。
    例如: 下面定义了一个位结构。

     struct{
          unsigned incon: 8;  /*incon占用低字节的0~7共8位*/
          unsigned txcolor: 4;/*txcolor占用高字节的0~3位共4位*/
          unsigned bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/
          unsigned blink: 1;  /*blink占用高字节的第7位*/
     }ch;

    位结构成员的访问与结构成员的访问相同。
    例如: 访问上例位结构中的bgcolor成员可写成:

      ch.bgcolor

    注意:
    1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长度为1时, 会被认为是unsigned类型。因为单个位不
可能具有符号。
    2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针, 如果是指针, 其成员访问方式同结构指针。
    3. 位结构总长度(位数), 是各个位成员定义的位数之和,  可以超过两个字节。
    4. 位结构成员可以与其它结构成员一起使用。
    例如:

     struct info{
          char name[8];
          int age;
          struct addr address;
          float pay;
          unsigned state: 1;
          unsigned pay: 1;
          }workers;'

    上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结构成员只有一位, 因此只占一个字节但保存了两个
信息, 该字节中第一位表示工人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。
关键字:C51  union 引用地址:学C51的基础 10《 联 合(union) 》

上一篇:学C51的基础 11《 枚 举(enum) 》
下一篇:学C51的基础 9 《 指针、结构、联合和枚举 》

推荐阅读最新更新时间:2024-03-16 13:54

C51中的INTRINS.H:内部函数
函数名: _crol_,_irol_,_lrol_ 原 型: unsigned char _crol_(unsigned char val,unsigned char n); unsigned int _irol_(unsigned int val,unsigned char n); unsigned int _lrol_(unsigned int val,unsigned char n); 功 能:_crol_,_irol_,_lrol_以位形式将val 左移n 位,该函数与8051 RLA 指令 相关,上面几个函数不同于参数类型。 例: #include main() { unsigned int y; C
[单片机]
C51简介及Keil的使用
前言 此文档主要是针对有一定C/C++编程基础,并打算用Keil从事C51开发的开发人员。C51涉及的知识比较多,但是入门基本的开发,还是容易的。 C51简介 1. C51概念 C51继承于C语言,主要运行于51内核的单片机平台。单片机,单片微型计算机器(SingleChipMicrocomputer)的简称,又称微控制单元(MicroControllerUnit,MCU)。MCU由CPU、RAM、ROM、I/O、中断系统、晶振等组成。51内核的单片机都是8位的,因为数据I/O是8位的,但是地址总线是16位的。基于51内核的单片机有很多种,如8051、80515等。 存储器:包括片内存储器、片外存储器。片内存储器一般包括2
[单片机]
<font color='red'>C51</font>简介及Keil的使用
C51独立键盘按键检测示例
独立按键检测很简单.就是检测单片机的i/o口哪个是低电平然后就能判断是哪个键被按下了.当然还要去抖动,也就是要延时.不然会有很多误动作. 效果图: 电路图: 说下程序实现的功能: SW16是数码管+1 SW17是数码管-1 SW18是数码管清零 SW19是数码管自动+1 源代码 #include reg52.h #define uchar unsigned char #define uint unsigned int sbit key1=P3^2; sbit key2=P3^3; sbit key3=P3^4; sbit key4=P3^5; sbit P20=P2^0; sbit P21=P
[单片机]
<font color='red'>C51</font>独立键盘按键检测示例
BOE(京东方)供货理想L8全系列“双屏+吸顶屏” 引领智能座舱人车交互新未来
BOE(京东方)供货理想L8全系列“双联屏+吸顶屏” 引领智能座舱人车交互新未来 2022年9月30日,全新一代理想ONE——理想L8正式发布,该款家庭智能豪华六座SUV搭载了由BOE(京东方)供货的近35英寸中控副驾双联屏以及后排15.7英寸吸顶屏,成为该车型的最大亮点之一。通过采用BOE(京东方)智慧显示解决方案,该款SUV不仅在低蓝光、超高清、超大尺寸车载显示技术方面达到行业领先水平,极大提升了整个座舱的智能化和科技感;更在人车交互方面为用户带来沉浸式的驾乘新体验,引领智能座舱人车交互新未来。 随着智能汽车产业快速发展,智能化和网联化成为汽车产业的发展趋势,全球主流汽车品牌更加注重人车互动升级,大屏化、个性化、
[汽车电子]
BOE(京东方)供货理想L8全系列“双<font color='red'>联</font>屏+吸顶屏” 引领智能座舱人车交互新未来
C51单片机对共阳极数码管的控制设计
这是共阳极数码管的电路图,其中JP3接到P0口,JP3的8-1对应数码管的a-dp引脚。 共阳极数码管的编码表如下,注意a---最低位,dp---最高位: 【0---3】0xco,0xf9,0xa4,0xb0, 【4---7】0x99,0x92,0x82,0xf8, 【8---B】0x80,0x90,0x88,0x83, 【C---F】0xc6,0xa1,0x86,0x8e。 C51程序显示数字0-9: #include #define uchar unsigned char void delay(); uchar smg[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
[单片机]
<font color='red'>C51</font>单片机对共阳极数码管的控制设计
C51中的reentrant
关于reentrant的使用keil的官方论坛上有详细的讨论. Andy Neil(官方工程师)建议 Are you sure that you really need to make everything reentrant?... A reading of the Keil app notes & knowledgebase articles on this subject showed that it was not necessary. 由于每一次调用被reentrant声明的函数都要把函数的参数和内部变量压栈,所以 很容易使堆栈区溢出,S52只有256Bytes的data段,一个简单的函数如果有一个参数 三个内部变
[单片机]
对于c51外部中断和程序调用的理解
首先介绍一下C51外部中断的基本概念 中断的优点: 1、实时处理。需要CPU立即做出相应或处理。 2、异常处理。运行过程中,出现断电、程序出错等问题,就需要CPU对故障源进行处理。 3、提高效率。采用中断技术可以大大提高CPU的运行效率。 中断源:C51单片机有5个中断源(2个外部中断、2个定时器中断和一个串口中断)。对中断的配置操作,主要通过控制三个寄存器就可以(中断允许寄存器IE)、定时器控制寄存器(TCON)和中断优先级寄存器(IP)。即通过控制EA EX IT 的直接赋值,即可调用中断服务程序 注:中断服务程序与while(1)中的程序调用是不一样的 中断服务函数:在CPU接收到中断后,会执行相应中断的中断服务函数
[单片机]
对于<font color='red'>c51</font>外部中断和程序调用的理解
带USB和智能读卡器接口的C51微控制器
摘要:ATMEL公司是51单片机生产厂家之一,该公司新推出的AT8xC5122系列微处理器可支持USB和读卡器,并且具有两种封装形式,可以方便地应用于多种场合和仪器中。 关键词:单片机;USB;读卡器;微控制器;AT8xC5122 1 AT8xC5122的特性结构 Atmel公司最近又生产了一系列带USB和智能读卡器接口的微处理器(如AT83C5122、AT85C5122、AT89C5122等)。这些器件是由8位微处理器80C51优化派生出来的高性能CMOS微处理器,带有USB和智能读卡器接口,其中AT8xC5122保留了Atmel 80C51的特性,带有32kB的ROM、768字节的内部RAM、一个四级中断系统、两个16
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved