C语言学习第十五天(共用体、枚举)

来源:互联网 发布:幼儿园淘宝节活动方案 编辑:程序博客网 时间:2024/05/04 17:53

使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体。


共用体定义:

union 共用体名

{

   成员表名

}变量表名

例:

/*先声明类型再定义*/union student{    int num;    char name;    float score;}xiaowang;    /*直接定义*/union{    int num;    char name;    float score;}xiaowang;

结构体变量所占内存长度是各成员占的内存长度之和,每个成员分别占有其自己的内存单元。

公用体变量所占内存长度是等于最长的成员长度。

上面的例子所占长度是各占4个字节 (实型变量占4个字节)而不是2+1+4=7个字节

一些书中把公用体也叫 -> "联合"


注意特点:

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

2.共用体变量起作用的成员是最后一次存放的成员,再存入一个新的成员后,原有成员失去作用,如:

#include <stdio.h>#include <stdlib.h>#include <string.h>union{    int num;    char name[20];    float score;}xiaowang;        main(){    xiaowang.num=1;    strcpy(xiaowang.name,"xiaowang");    xiaowang.score = 88;    printf("%d",xiaowang.num);    /*此时xiaowang.num已经失去了意义*/}


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

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

5.不能把共用体变量作为参数,也不能使函数返回时带有共用体,但可以使用指向共用体变量的指针(与结构体用法相似)

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



一组数据:有老师、学生。数据包括:学号、姓名、性别、职业、班级/职务

如果职业是s第5项就是班级,如果是t第5项就是职务:

#include <stdio.h>#include <stdlib.h>#include <string.h>struct{    int num;    char name[20];    char sex;    char job;    union    {        int classes;        char position[20];    }category;}person[2];   main(){       int i;       for(i=0;i<2;i++)    {        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.classes);        }        else if(person[i].job=='t')        {            scanf("%s",&person[i].category.position);        }        else        {            printf("input error!");        }    }       printf("");       printf("No    Name      sex    Job   class/position");       for(i=0;i<2;i++)    {        if(person[i].job=='t')        {            printf("%-6d%-10s%-8c%-6c%-s",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);        }        else        { printf("%-6d%-10s%-8c%-6c%-d",person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.classes);        }    }}


可以看出在结构体类型声明中包括了共用体类型,category是结构体成员中的一个成员名,在共用体中成员为class、position,前者为整型,后者为字符数组(存放"职务"的值--字符串).



枚举类型:

如果一个变量只有几种可能的值,可以定义为枚举类型。所谓枚举是指将变量的值一一列举出来,变量的值,只限于列举出来的值的范围内。

声明:

enum weekday(sun,mon,tue,wed,thu,fri,sat);

声明一个枚举类型enum weekday,可以用此来定义变量如:

enum weekday workday,week_end

workday和week_end被定义为枚举变量,它们的值只能是sun到sat之一。例如:

workday=mon;

week_day=sun; 

直接定义:

enum{sun,mon,tur,wed,thu,fri,sat} workday,week_end;

其中sun,mon等称为枚举常量,是用户自定义的标识符

1.枚举元素按常量处理,他们不是变量,不能对它们赋值。

2.枚举元素作为常量,他们是有值的编译按定义时的顺序使他们的值为0,1,2。。。


例:口袋中有红、黄、蓝、白、黑5种颜色球若干个。每次从口袋中取出3个球,问得到3种不同色的球可能的取法,打印出3种颜色:

#include <stdio.h>main(){   enum color{red,yellow,blue,white,black};    enum color i,j,k,pri;    int n,loop;    n=0;       for(i=red;i<=black;i++)    {        for(j=red;j<=black;j++)        {            if(i!=j)            {                for(k=red;k<=black;k++)                {                    if(k!=i&&k!=j)                    {                        n=n+1;                        printf("%d: ",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("%s ","red");break;                                case yellow:printf("%s  ","yellow");break;                                case blue:printf("%s    ","blue");break;                                case white:printf("%s   ","white");break;                                case black:printf("%s   ","black");break;                                default:break;                            }                        }                        printf("");                    }                }            }        }    }}




用typedef定义类型:

除了使用标准类型int、char、float、double、long等和自己声明的结构体、共用体、指针、枚举类型外,可以用typeof声明新的类型来代替已有的类型,如:

#include<stdio.h>void main(){    typedef int INTEGER;    typedef float REAL;       int a=3;    float b=3.45;       INTEGER c = 4;    REAL d = 4.54;       printf("a:%d,c:%d",a,c);    printf("b:%.2f,d:%.2f",b,d);}


他们是等价的。

#include<stdio.h>void main(){    typedef struct    {        int year;        int mouth;        int day;    }DATE;       DATE birthday; /*声明一个DATE类型的生日*/    DATE *p /*p为指向结构体类型数据的指针*/}


typedef int NUM[100];NUM n;/*定义n为整型数组变量*/
typedef int *STR;/*声明STR为字符指针类型*/STR p,s[10];/*p为字符指针变量,s为指针数组*/
typedef int  (*POINTER)();/*声明POINTER为指向函数的指针类型,函数返回整型值*/POINTER p1,p2; /*p1,p2为POINTER类型的指针变量*/

归纳:

1.先按定义变量的方法写出定义体。

2.将变量名换成新类型名。

3.在最前面加typedef。

4.然后用新类型名定义变量。

以数组为例说明:

1.int n[100]

2.int NUM[100]

3.typefef int NUM[100]

4.NUM arr;

以字符指针说明:

1.char *p

2.char *STR

3.typedef char *STR

4.STR p,s[10];



说明:

1.用typedef可以声明各种类型名,但不能用来定义变量。

   int a[10],b[10],c[10];

   都是一堆数组大小也相同,,可将数组类型声明为一个类型

   typedef int ARR[10];

   然后用ARR去定义数组变量。

   ARR a,b,c;

2.用typedef只是对已存在的类型增加一个类型名,而没有创造新的。

   像typedef int NUM[100] 无非是把原来用int n[10]定义的数组变量类型用一个新的名字NUM表示出来。

3.typedef与#define有相似之处

   typedef int COUNT

   #define COUNT int

   作用都是用COUNT代表int,但事实上两者是不同的。

   #define 是在预编译时处理的,只能做简单的字符串替换

   typedef 是在编译时处理的,并不是做简单的字符串替换,例如:

   typedef int NUM[10] 并不是去代替int,而是如同定义变量的方法声明一个类型

4.当不同源文件中用到同一数据类型(尤其是像定义数组、指针、结构体、共用体)等类型,常用typedef声明一些数据类型,单独放在一个文件中,需要用时导包

5.使用typedef有利于程序段通用与移植