【时时三省】(C语言基础)共用体类型数据的特点
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省
在使用共用体类型数据时要注意以下一些特点:
( 1 )同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。其道理是显然的,因为在每一个瞬时,存储单元只能有唯一的内容,也就是说,在共用体变量中只能存放一个值。如果有以下程序段:
union Date
{ int i ;
char ch ;
float f ;
}a;
a.i = 97 ;
表示将整数97存放在共用体变量中,可以用以下的输出语句:
printf (”% d”,a.i );(输出整数97)
printf ( " % c”, a.ch ) ;(输出字符’a ')
printf ( " % f”,a.f );(输出实数0.000000)
其执行情况是:由于97是赋给a.i的,因此按整数形式存储在变量单元中,最后一个字节是“01100001”。如果用“% d”格式符输出a.i,就会输出整数97。如果想用“% c”格式符输出a.ch ,系统会把存储单元中的信息按字符输出' a '。如果想用“% f”格式符输出a.f ,系统会将存储单元中的信息按浮点数形式来处理,其数值部分为0,故输出0.000000。
( 2 )可以对共用体变量初始化,但初始化表中只能有一个常量。下面用法不对:
union Data
{ int i;
schar ch ;
float f ;
}a={1,'a',1.5};//不能初始化3个成员,它们占用同一段存储单元)
union Data a = ( 16 );//正确,对第1个成员初始化
union Data a = ( .ch = ' j ' );//C99允许对指定的一个成员初始化
( 3 )共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就被取代。如果执行以下赋值语句:
a.ch = ' a ';
a. f = 1.5;
a.i = 40;
在完成以上3个赋值运算以后,变量存储单元存放的是最后存入的40,原来的' a '和1.5都被覆盖了。此时如用“printf ( " % d”,a.i );”输出a.i的值是40。而用“printf ( " % c”,a.ch );”。输出的不是字符’a ',而是字符’( '。因为在共用的存储单元中,按整数形式存放了40,现在要按%c格式输出a.ch ,系统就到共用的存储单元去读数据,蒋存储单元中的内容按存储字符数据的规则解释,40是字符(的ASCII码,因此输出字符’(’。
因此在引用共用体变量时应十分注意当前存放在共用体变量中的究竟是哪个成员的值。
( 4 )共用体变量的地址和它的各成员的地址都是同一地址。例如,&a .i , &a .c , &a .f都是同一值,其原因是显然的。
( 5 )不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。例如,下面这些都是不对的:
①a = 1 ;
②m=a;
C99允许同类型的共用体变量互相赋值。如:
b = a ;
( 6 )以前的C规定不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针作函数参数。C99允许用共用体变量作为函数参数。
( 7 )共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
在什么情况下会用到共用体类型的数据呢?往往在数据处理中,有时需要对同一段空间安排不同的用途,这时用共用体类型比较方便,能增加程序处理的灵活性。请分析下例。
例题1:
有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。
解题思路:
可以看出:学生和教师的数据的项目大多数是相同的,但有一项不同。现要求把它们放在同一表格中。如果job项为s(学生),则第5项为class(班)。即Li是501班的。如果job项是t(教师),则第5项为position(职务)。Wang是prof(教授)。显然对第5项可以用共用体来处理(将class和position放在同一段存储单元中)。
先输入人员的数据,然后再输出。为简化起见,只设两个人(一个学生、一个教师)。
编写程序:
运行结果:
程序分析:
main函数之前定义了外部的结构体数组person,在结构体类型声明中包括了共用体类型category(分类)成员,在这个共用体成员中又包括两个成员:成员clas(由于class是C++的关键字,用VisualC++时不应该用class作成员名,故用clas代表)和成员position,前者为整型,后者为字符数组(存放“职位”的内容——字符串)。也可以不在结构体类型的声明中声明共用体类型,而把它放在结构体类型的声明之前。
在程序运行过程中需要输入数据,在输入前4项数据(编号、姓名、性别、职业)时,对于学生和教师来说,输入的数据类型是一样的,但在输入第5项数据(人员类别)时二者就有区别了,对于学生应输入班级号(整数),对于教师则应输入职位(字符串),程序应作分别处理。在程序中是这样处理的:先输入前4项数据,然后用if语句检查刚才输入的职业( job成员),如果是' s ',表示是学生,则第5项应输入一个班级号(整数),用输入格式符%d把一个整数送到共用体数组元素中的成员category .clas中。如果职业是' t ',表示是教师,则输入第5项时应该用输入格式符%s把一个字符串(职位)送到共用体数组元素中的成员category . position中。请注意:这样处理后,结构体数组元素person [ 0 ]中的共用体成员category的存储空间中,存放的是整数,而person [ 1 ]中的共用体成员category的存储空间中,存放的是字符串。
在输出数据时的处理方法是类似的,如果是学生,第5项以整数形式输出班号,如果是教师,则第5项以字符串形式输出职位。在printf语句中,格式符“% - 6d”表示以十进制整数形式输出,占6列,数据向左对齐,其他如%- 10s , % - 4c , % - 4c , % - 10s的含义与此类似。
在数据处理中,用同一个栏目来表示不同内容的情况是不少的。