共用体的使用实例

共用体的使用实例

2012年02月19日 08:48:57 yi_bunny 阅读数:1188 标签: struct编程c 更多

个人分类: C语言应用

转自http://home.eeworld.com.cn/my/space.php?uid=139222&do=blog&id=28244

1、共用体的概念

在编程过程中,有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可以把一个整型变量,一个字符型变量,一个实型变量放在同一个地址开始的内存单元中。

这样的话,不同类型的变量在内存中占据的字节数不同,但是都从同一个地址开始。也就是使用覆盖技术,几个变量互相覆盖。这种使几个不同的变量共同占用同一段内存的结构,称为“共用体”类型的结构。

结构体变量占用的内存空间大小是其各个成员所占的字节长度的总和。如果同一时刻只存放其中的一个成员数据,会浪费单片机有限的内存空间.而共用体所占的内存空间的长度是其中最长的成员的字节长度。这样就有效的提高了内存的利用效率。

2、共用体类型的定义

共用体类型的定义也有三种方式:

1)先定义共用体类型再定义变量名。一般格式如下:

union 共用体名

{

成员列表;

};

定义好一个共用体类型之后,就可以像定义变量一样来定义共用体变量。一般格式为:

union 共用体名 共用体变量名1,共用体变量名2,...共用体变量名n;

2)在定义共用体类型的同时定义共用体变量名。一般格式为:

union 共用体名

{

成员列表;

}共用体变量名1,共用体变量名2,...共用体变量名n;

3)直接定义共用体变量。一般格式为:

union

{

成员列表;

}共用体变量名1,共用体变量名2,...共用体变量名n;

由上可见,共用体类型与结构体类型有很多相似之处,只是将关键字struct改成了union,但是在内存分配上两者却有本质的区别。

3、共用体变量的引用

与结构体变量类似,对共用体变量的引用也是通过对其成员的引用来实现的。

引用共用体变量成员的一般格式为:

共用体变量名.共用体成员

使用共用体类型数据是需要注意:

1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬间只能存放其中一种,而不能同时存放几种,也就是说,每一瞬时只有一个成员起作用,其他的成员都不起作用;

2)共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后,原有的成员就失去作用。因此在引用共用体变量是因注意当前存放在共用体变量中的到底是哪个成员。

3)共用体变量的地址和它的各成员的地址都是同一地址;

4)不能对共用体变量名赋值,也不能企图引用共用体变量名来得到一个值,更不能在定义共用体变量时对它初始化。

      (也不能在共用内对成员进行的赋值,赋值后的语句就不能作为共用体的成员了,譬如:int a = 3;作为共用体的成员列表中的成员,编译器会把a=3作为一个成员名在内存中开辟空间,这样就出现了空间名是一个“a=3”的名字,是不符号C语言的规定,所以在共用体内出现int a =3;的成员时会报错:error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
  int a=  3;在之后定义的成员char c;编译器也会报错没有成员名:error: ‘union myunion’ has no member named ‘c’
  x.c=4;


        ^

5)不能把共用体变量作为函数参数,也不能使函数返回共用体变量,但可以使用指向共用体变量的指针

6)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组,反之亦然。

4、本实例演示共用体类型的定义、共用体变量的定义以及共用体成员的引用。

5、在keil c51中新建项目文件ex34,编写如下程序代码,编译并生成ex34.hex文件。

//实例34:共用体数据类型演示实例

#include <reg51.h>   //  包含头文件
 
void main(void)
{
    union numdata
  {
   unsigned int dat1;
  unsigned char dat2;
  unsigned int dat3;
  };//定义共用体数据类型

 union numdata num1;   // 定义共用体变量

 num1.dat1 = 0xf0;     //给共用体的元素赋初值
 num1.dat2 = 0x0f;    //
 num1.dat3 = 0x55;    
                           // 完成以上三个赋值运算后,只有num1.dat3是有效的。
                          // 前两个元素的值已经无意义了

 P0 = num1.dat3;     //送到P0口显示
 while(1)
 {       //无限循环,防止程序跑飞
 }
}

6、在proteus中新建仿真文件ex34.dsn,原理图如下图所示:

7、将ex34.hex文件载入at89c51中,启动仿真,运行结果如下

(PS:目前,我认为union型数据就是用来节省不必要的内存开销,将不在同一时间使用的各类型数据进行封装。)

猜你喜欢

转载自blog.csdn.net/weixin_41632560/article/details/84872343