第 9章 结构体,共用体及枚举型第九章 结构体,共用体及枚举型
9.1 结构体
9.2指向结构体类型数据的指针
9.3共用体及枚举型第 9章 结构体,共用体及枚举型
9.1 结构体
9.1.1 结构体类型的定义结构体类型实际上就是使用不同类型的数据描述数据对象时的结构模式 。 例如,学生的综合信息可使用下面的数据结构模式进行描述,图 9.1描述了学生,xiao
ming”的信息 。
学号 用整型数据描述 即,int num;
姓名 用字符串数据描述 即,char name[20];
性别 用字符数据描述 即,char sex;
成绩 用实型数据描述 即,float score;
住址 用字符串数据描述 即,char address[30];
第 9章 结构体,共用体及枚举型使用结构体类型与使用标准数据类型的区别在于:
C语言为用户提供了标准数据类型说明符 (如 int,char,
float等 )供用户使用;但是却没有为用户提供通用的结构体类型说明符,因此用户需要根据编程要求自己说明所需要的结构体类型。
第 9章 结构体,共用体及枚举型下面说明学生综合信息结构体类型 struct student:
struct student
{
int num;
char name[20];
char sex;
float score;
char address[30];
};
第 9章 结构体,共用体及枚举型上面定义了一个结构体类型,struct student(struct是关键字,不能省略 ),表示这是一个,结构体类型,。它包括
num,name,sex,age,score,address等不同类型的数据项。
应当注意,struct student是程序设计者自己定义的类型名。
它和系统已定义了的标准类型 (如 int,char,float,double
等 )一样可以用来作为定义变量的类型。
第 9章 结构体,共用体及枚举型定义一个结构体类型的一般形式为:
struct 结构体类型名 /* struct是结构类型关键字
*/
{
数据类型 数据项 1;
数据类型 数据项 2;
…… ……
数据类型 数据项n;
}; /* 此行分号不能少! */
第 9章 结构体,共用体及枚举型花括号内是该结构体中的各个成员 (或称分量 ),由它们组成一个结构体。例如,上例中的 num,name,
sex等都是成员。对各成员都应进行类型说明,即类型标识符 成员名也可以把花括号内容称为,域表,。每一个成员称为结构体中的一个域。成员名定名规则与变量名同。
成员变量的个数不限。所以用户可以根据自己的需要,
说明各种不同的结构体类型。然后,用户就可像使用标准类型那样,用结构体类型说明结构体类型变量。
第 9章 结构体,共用体及枚举型
9.1.2 结构体变量的定义和引用一、结构体变量的定义要定义一个结构体类型的变量,可以采取以下三种方法。
(1) 先定义结构体类型在定义变量名如上面已定义了一个结构体类型 struct student,可以用它来定义变量。如,
struct student student1,student2;
定义 student1和 student2为 struct student类型变量,
即它们具有 struct strudent类型的结构。
第 9章 结构体,共用体及枚举型
(2) 在定义类型的同时定义变量例如,
struct student
{
int num;
char name[20];
char sex;
float score;
char address[30];
}student1,student2;
第 9章 结构体,共用体及枚举型
(3) 直接定义结构类型变量其一般形式为,
struct
{
成员表列 ;
}变量名表列;
即不出现结构体名。
第 9章 结构体,共用体及枚举型关于结构体类型,有几点要说明,
a.类型与变量是不同的概念,不要混淆。对结构体变量来说,在定义时一般先定义一个结构体类型,然后定义变量为该类型。只能对变量赋值,存取或运算,而不能对一个类型赋值,存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
b.对结构体中的成员 (即,域,),可以单独使用,它的作用与地位相当于普通变量。
c.成员也可以是一个结构体变量。
d.成员名可以与程序中的变量名相同,二者不代表同一个对象。例如,程序中可以另定义一个变量 num,它与
struct student中的 num是两回事,互不干扰。
第 9章 结构体,共用体及枚举型二、结构体变量的引用
(1)在定义了结构体变量以后,当然可以引用这个变量。
(2)如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。
(3)对成员变量可以像普通变量一样进行各种运算 (根据其类型决定可以进行的运算 )。
(4)可以引用成员的地址,也可以引用结构体变量的地址。
第 9章 结构体,共用体及枚举型
9.1.3 简化结构体类型名为了使用方便,人们通常用一个符号常量代表一个结构体类型。在程序开头,用以下表示方式,
#define STUDENT struct student
这样,在程序中的 STUDENT 与 struct student完全等效,
可以直接用 STUDENT定义变量。如
STUDENT student1,student2;
第 9章 结构体,共用体及枚举型
9.1.4 结构体数组
1,结构体数组的定义和定义结构体变量方法相仿,只需说明其为数组即可。如:
struct student
{
int num;
char name[20];
char sex;
float score;
char address[30];
};
struct student stu[3];
第 9章 结构体,共用体及枚举型
2,结构体数组的初始化结构体数组可以初始化,如:
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
}stu[3]={{101,"liling",’ M’,18,92,"Beijing"},
{102,"zhaoling",’ F’,20,85,"shanghai"},{103,
"zhanghua",’ F’,21,79,"tianjin"}};
第 9章 结构体,共用体及枚举型定义数组 stu时,元素个数可以不指定,即写成以下形式:
stu[]={{… },{… },{… }};
当然,数组的初始化也可以用以下形式:
struct student
{
int num;

};
struct student stu[]={{… },{… },{… }};
即先定义结构体类型,然后定义数组为该结构体类型,在定义数组时初始化。
第 9章 结构体,共用体及枚举型
9.2 指向结构体类型数据的指针
9.2.1指向结构体变量的指针对应结构体类型变量的三种说明方式,也可使用三种方式说明结构体指针变量:
1,先说明结构体类型,再说明结构体变量指针。
假定使用前面的学生综合信息结构体类型 struct
student,则 struct student stu1,*p1;
说明了一个结构体变量 stu1和一个结构体指针变量
p1,p1可用于指向具有结构体类型 struct student所描述的任何结构体变量,如 stu1等。
第 9章 结构体,共用体及枚举型
2,在说明结构体类型时,同时说明结构体指针变量。
3,直接按结构体类型的结构模式说明结构体指针变量。
利用结构体指针变量 p1引用所指的结构体变量 stu1成员时可以使用下面两种方法:
(1)(*指针变量名 ).成员名如,(*p1).num,(*p1).name,(*p1).sex,(*p1).score,
(*p1).address等,
(2)指针变量名 ->成员变量名如,p1->num,p1->name,p1->sex,p1->score,p1-
>address等,
第 9章 结构体,共用体及枚举型注意,,->”和,,”都是涉及结构体的运算符,并且具有最高的运算优先级,因此,在类似 (*p1).sex和
&((*p1).sex)的引用时,必须正确使用括号 ().而对类似 &(p1->sex)的引用可不用括号 (),直接使用 &p1-
>sex形似即可,
第 9章 结构体,共用体及枚举型
9.2.2 指向结构体类型数据的指针在使用数组时,要求指向数组的指针变量的类型与数组的基类型一致,对于结构体数组及指向结构体数组的结构体指针变量也不例外,
第 9章 结构体,共用体及枚举型如,struct
{
int num;
char name[20];
char sex;
float score;
char address[30];
}stu[5],*p1; /*说明 5个元素的结构数组 stu[5]*/
由于结构体指针变量 p1和结构数组 stu[5]的基类型一致,故,
(1)p1可以指向数组 stu的起始地址,p1=stu;
(2)p1也可以指向数组 stu的不同元素的地址,p1=&stu[0]或
p1=&stu[4]等,
第 9章 结构体,共用体及枚举型
9.3 共用体及枚举型
9.3.1共用体
1,共用体类型定义形式,
union 共用体类型名
{共用体成员表列;
}
例如,union data_type
{
char char_a;
int int_b;
}
第 9章 结构体,共用体及枚举型上面定义了名字为 data_type的共用体类型,该类型允许字符型变量 char_a和整型变量 int_b共用同一个起始地址的存储单元,
2,共用体类型变量类似于结构体变量的说明形式,也可用三种方式说明共用体类型的变量,但应将关键字 struct换为 union.
下面三种方式说明的共用体类型变量 value_1和
value_2是完全相同的,
第 9章 结构体,共用体及枚举型
(1) 先说明共用体类型,再说明共用体变量,如,
union data_type value_1,value_2;
(2) 在说明共用体类型的同时说明共用体变量,如,
union data_type
{
char char_a;
int int_b;
}value_1,value_2;
注意,这里既说明了共用体类型 union data_type,同时又说明了共用体类型变量 value_1和 value_2.
第 9章 结构体,共用体及枚举型
(3) 直接按共用体类型的结构模式说明共用体变量,
union
{char char_a;
int int_b;
} value_1,value_2;
注意,这里没有说明共用体类型名 (如前面的 union
data_type),而只说明了共用体类型变量 value_1和
value_2.
第 9章 结构体,共用体及枚举型
3.共用体类型变量的引用方式在通常使用中,只引用共用体的成员变量,引用方式与结构体变量的引用方式相同,
例如,假定有如下说明和赋值,
union data_type value_1,*p;
p=&value_1;
则可用,,”或,->”运算符引用共用体变量的成员变量,如,
value_1.char_a或 p->char_a
value_1.int_b或 p->int_b
printf("%c,%d",p->char_a,value_1.int_b);
第 9章 结构体,共用体及枚举型
4,共用体类型变量的存储方式共用体变量占用的字节数与长度最长的成员变量所占用的字节数相同,
5,特点
( 1) 系统采用覆盖技术,实现共用变量各成员的内存共享,所以在某一时刻,存放的和起作用的是最后一次存入的成员值 。
( 2) 由于所有成员共享同一内存空间,故共用变量与其各成员的地址相同 。
第 9章 结构体,共用体及枚举型
( 3) 不能对共用变量进行初始化 ( 注意:结构变量可以 ) ;也不能将共用变量作为函数参数,以及使函数返回一个共用数据,但可以使用指向共用变量的指针 。
( 4)共用类型可以出现在结构类型定义中,反之亦然。
第 9章 结构体,共用体及枚举型
9.3.2枚举型
1.枚举类型定义形式,
enum 枚举类型名
{
枚举表列 ;
}
例如,enum weekday{sun,mon.tue,wed,thu,fri,
sat};
上面定义了名字为 weekday的枚举类型,该类型的构造模式对应了整型常数集合 {0,1,2,3,4,5,6},即,
枚举标识符 sun的值为整数值 0,枚举标识符 mon的值为整数值 1,…,枚举标识符 sat的值为整数值 6,
第 9章 结构体,共用体及枚举型
2.枚举类型变量枚举类型变量也有三种说明形式,
(1) 先说明枚举类型名,再说明枚举变量,如,
enum weekday schedule;
(2) 在说明枚举类型名时,同时说明枚举变量,如,
enum weekday{sun,mon.tue,wed,thu,fri,
sat}schedule;
(3) 直接按枚举类型的结构模式说明枚举变量,如,
enum {sun,mon.tue,wed,thu,fri,sat}schedule;
第 9章 结构体,共用体及枚举型
3.使用枚举类型变量的几点说明,
(1)枚举元素是常量,其对应的整数值可在定义时进行初始化,如未进行初始化,则枚举元素对应的整数值依次为 0,1,2… 等,若进行初始化,一般要求排列在后面的元素对应的整数值应大于排列在前面的元素对应的整数值,
(2)枚举变量可用作循环控制变量,但此时要求枚举变量所对应的整数值是增量值为 1; 枚举变量及枚举元素之间可以进行比较运算,如,mon<wed为真,
第 9章 结构体,共用体及枚举型
(3)枚举变量或枚举元素亦可用作数组元素下标,但此时要求枚举变量或枚举元素所对应的整数值不能超过数组下标界,如 comrades[Wang],comrades[person]等,
(4)枚举变量不能进行键盘输入操作 ; 枚举变量或枚举元素不能直接输出枚举元素标识符,但可以直接输出它们所对应的整数值,