9.5 共用体类型
9.5.1 什么是共用体类型
前面我们所学习了结构体类型,结构体类型是将所有不同类型的数据联合在一起。
而我们现在学习的共用体类型,用同一段内存单元存放不同的类型的数据,是选择里面最长的一个数据,就拿这个最长的长度,作为共用体结构的长度。共用体是通过覆盖的实现的。
共用体的一般形式:
union 共用体名
{
成员列表
} 变量列表;
具体有如下三种定义形式:
union data { int i; char ch; float f; }a,b,c; /// union data { int i; char ch; float f; }; union data a,b,c; /这种定义的比较多 union { int i; char ch; float f; }a,b,c; 和结构体一样,这个定义完只能有一次定义变量的机会,因为它没有定义变量名。
9.5.2 引用共用体变量的方式
引用公用体变量看看下面
a;错误 a.i;正确 a.ch;正确 a.f;正确 printf ("%d",a);错误 printf("%d",a.i);正确
首先咱们看一下,共用体虽然是一个综合的结构体,但是呢,他是具体表示某一个变量的。你如整型 浮点型。所以你不能通过共用体名字去引用。他不具体表示哪一个变量。只有a.i等才可以,因为是具体表示某一个变量的。再看结构体,结构体名字就是本身表示一个变量。所以说结构体可以引用,但是共用体不可以引用。
9.5.3共用体类型的特点
共用体类型有以下特点:
1)共用体可以存放不同类型的数据,但是在某一瞬间只能存放其中一个成员。
在某一瞬间,共用体只能存放某一种类型的数据;
2)可以初始化,但是只能放一个数值;
union data { int i; char ch; float f; }a={1,'a',1.5};错误 union data a={16};正确 union data a={.ch='j'};正确,最好都加上.ch;之类的
3)共用体赋值时候直接按照那个数值的类型去储存,字节是类型中最大字节;
4)赋值后之前的数据会被覆盖,只有现在这个数据是有效的。
5)公用体变量的地址和他的成员的地址都是同一个地址。
&a.i=&a.c=&a.f; &a的地址没有意义
6)变量名是不可以被赋值的,也不能被使用,需要具体到什么类型;
7)C99以后可以做函数参数(只提一下,以后学习中了解)
有若干人员的数据,其中包括学生和老师。学生的数据中包括,姓名 号码 性别 职业 班级 。 教师的数据包括:姓名,号码,性别 ,职业,职务,。要求制定一个表格来处理。 #include <stdio.h> struct { int num; char name[10]; char sex; char job; union { int clas; char position[10]; }category; }person[2]; int main() { int i; for(i=0;i<2;i++) { printf("please enter the data of person:\n"); scanf("%d %s %c %c",&person[i].num,&person[i].name,&person[i].sex,&person[i].job); if(person[i].job=='s') scanf("%d",&person[i].category.clas); else if(person[i].job=='t') scanf("%d",&person[i].category.position); else printf("\n"); printf("No.name sex job class/position\n"); for(i=0;i<2;i++) { if(person[i].job=='s') printf("%-6d%-10d%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.clas); else printf("%-6d%-10d%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position); } } return 0; }
9.6 使用枚举类型
什么是枚举;就是自己去列举一些可能性,然后如果你定义一些变量;这些变量的取值,只能在这些可能性中取值。除非你改变枚举列表,否则你的变量不能取值在枚举之外的值。
怎么写一个枚举类型的结构,以及怎么去定义它
enum 枚举结构名
{
枚举表列(枚举常量)
}枚举变量;
如下:
enum weekday{sun,mon,tue,wed,thu,fri,sta}; enum weekday workday,weekend; / enum weekday{sun,mon,tue,wed,thu,fri,sta}workday,weekend; / enum {sun,mon,tue,wed,thu,fri,sta}workday,weekend; 也可以没有枚举结构名,但是相当于只能定义一次;
注意:
枚举元素是常量,他虽然也是由字符构成,看起来像变量,但是,他依旧是一个常量,所以他是不能够被直接赋值的。而且每个枚举元素都会被默认为一个整数;比如之前的sun就被默认0;mon就被默认1…以此类推。
printf("%d",sun);
他是可以被输出的,输出的数值是0;
而且每个枚举元素也可以被设置为特定的数值;然后后面没有被赋值的,就顺推加1;
#include <stdio.h> enum weekday{sun=7,mon=5,tue,wed,thu,fri,sta}; int main() { enum weekday a,b,c; a=tue; b=wed; c=sta; printf("%d %d %d",a,b,c); return 0; }
/*口袋中有红,黄,蓝,百,黑5种颜色的球若干个,每次从口袋里 先后取出三个球,问得到三种颜色球可能的取法,输出每种排列的情况*/ #include <stdio.h> int main() { enum color{red,yellow,blue,white,black}; enum color i,j,k,pri; int n,loop;//n 用来记录取法的可能。 n=0; for(i=red;i<=black;i++)//i =red for(j=red;j<=black;j++)//j=red yellow blue if(i!=j) { for(k=red;k<=black;k++) //k=red yellow blue white black; if((k!=i)&&(k!=j)) { n=n+1; //n=1 printf("%-4d",n); for(loop=1;loop<=3;loop++) { switch(loop) { case 1:pri=i;break; case 2:pri=j;break; case 3:pri=k;break; default:break; } switch(pri) { case red:printf("%-10s","red");break; case yellow:printf("%-10s","yellow");break; case blue :printf("%-10s","blue");break; case white:printf("%-10s","white");break; case black:printf("%-10s","black");break; default break; } } printf("\n"); } } printf("\ntotal:%5d\n",n); return 0; }
9.7 typedef声明新类型名
1.先按照定义变量的方法写出定义体(如int i)
2.将变量名换成新类型名(例如:将i换成count)
3.在最前面加typedef(例如:typedef int count)
4.然后就可以用新类型去定义变量;
数组: int a[100]; int num[100]; typedef int num[100]; ........ num a;
字符指针: char *p; char *string; typedef char *string; string p;
整型: int i; int num; typedef int num; num a;
struct { int a; float b; }a; /// struct { ... }num; /// typedef struct { ... } num; num a;意思就是定义一个结构体变量a;
定义一个tyoedef ;就是将原有变量名用一个新的变量名去代替,新的变量名她具有原来旧的变量名一样的结构特点;typedef只是代替原来已有的变量名,不能够定义一个全新的,未知结构的变量类型;
他有什么好处呢?
首先他修改起来很方便。你可以修改定义,那么后面所有你所定义的类型变量你都直接都随之改变。使用方便。