240 likes | 437 Views
单元 10 项目中结构体的应用 ---- 结构体类型与变量定义和访问. 学习目标: (1) 能力目标 ①能将学生信息定义成结构体类型。 ②能根据该类型定义结构体变量并进行初始化。 ③能计算结构变量占用空间大小。 ④能利用“ .” 运算符和“ ->” 运算符正确引用结构体变量成员。 (2) 知识目标 ①理解为什么会产生结构体类型的数据。 ②掌握结构体类型和变量定义的三种格式。 ③理解结构体变量和结构体变量成员的区别与联系。 ④理解结构体变量成员引用方法。 能力训练:
E N D
单元10 项目中结构体的应用----结构体类型与变量定义和访问 • 学习目标: (1)能力目标 ①能将学生信息定义成结构体类型。 ②能根据该类型定义结构体变量并进行初始化。 ③能计算结构变量占用空间大小。 ④能利用“.”运算符和“->”运算符正确引用结构体变量成员。 (2)知识目标 ①理解为什么会产生结构体类型的数据。 ②掌握结构体类型和变量定义的三种格式。 ③理解结构体变量和结构体变量成员的区别与联系。 ④理解结构体变量成员引用方法。 • 能力训练: 1.将现实中的学生信息定义成结构体类型和结构体变量。 2.用“.”运算符和“->”运算符访问学生结构体成员变量。
单元10 项目中结构体的应用----10.1必备知识与理论 • 学习提示 结构体与共用体是程序设计应用最为广泛的一种数据类型,它主要应用于不同类型的若干数据整体存储与访问。由于结构体与共用体类型是用户自定义类型,所以,学习结构体、共用体与前面学习简单类型有些不一样,结构体与共用体要先定义类型,再定义变量、数组等,然后才能访问其成员,访问成员方法又分为变量访问方法和指针访问方法。 • 10.1必备知识与理论 10.1.1 结构体概述 我们在前面学习了一些基本类型(也叫简单类型),如整型、实型、字符型等,这些类型都是系统定义好的,程序员可以直接拿来定义变量。我们知道世界是复杂的,事务的内在关系也是复杂的。例如一个学生的属性包括学号、姓名、性别、出生日期、学习成绩、家庭住址等,这些数据虽然可以用基本类型来定义,但是这样定义不是一个有机的整体,不符合客观实际。因此,只用基本类型来表述这些事务显然是不够的,也就是说基本类型不能全面反映客观世界。 既然系统没有定义这些复杂的类型,那么用户能不能根据客观实际来定义数据类型呢?C语言提供了自定义数据类型的方法,通过自定义类型将不同类型的数据组合成一个有机的整体,以便访问,这些数据在这个整体中是互相联系的,这种自定义的数据类型叫构造类型。实际上我们在前面已经学习了一种构造类型——数组,数组是具有相同数据类型的一组元素集合。除了数组之外还有结构体和共用体,它们主要用来处理不同类型若干数据的整体存储与访问。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 • 10.1.2 结构体类型的应用 1.结构体类型的定义 结构体类型就是将不同类型的数据组合成一个有机的整体,以便于访问。请看下面的示意图10.1。 设一个学生的属性:学号(num)、姓名(name)、性别(sex)、年龄(age)、成绩(score)、家庭住址(addr)。 很显然,C语言没有提供这种现成的数据类型,因此用户必须要在程序中自己建立所需的结构体类型,这种类型就是用户自定义的结构体类型。 定义一个结构体类型的一般形式: num name sex age score addr 10010 Li Fun M 18 87.5 Beijing (将不同类型的数据组合成一个有机的整体) 图10.1 设计学生属性 struct 结构体类型名 { 成员列表 };
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 其中,struct是定义结构体类型关键字,结构体类型名由用户自己设计,但要遵循C语言标识符的命名原则,成员列表可以是简单类型变量、指针变量、数组和除自身类型之外的已定义的结构体类型变量。 以上述学生属性为例,来建立一个结构体类型: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; 上面定义了一个叫struct student的结构体类型,它包括num、name、sex、age、score、addr等不同类型的数据项,定义结构体类型时一定要注意下面几个问题: ①结构体类型名是struct student,而不是student。它和系统提供的基本类型一样具有同样的地位和作用,都是可以用来定义变量的类型。 ②在大括号中定义的变量我们叫做成员,其定义方法和前面变量定义的方法一样,只是我们不能忽略右大括号后面的分号。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 2.结构体变量的定义与初始化 (1)结构体变量的定义 定义好结构体类型之后,就可以定义结构体变量了。定义结构体变量有三种方法: ①先定义结构体类型再定义结构体变量 格式如下: 例如: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; struct 结构体类型名 { 成员列表 }; struct 结构体类型名 变量名列表;
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 struct student stu1,stu2; 结构体类型只是一个模型,并无具体的数据,系统也不对它分配内存单元,系统只对变量分配内存空间。即系统对stu1和stu2分配内存空间。 下面的问题是系统为stu1和stu2分配多大的空间? 结构体变量所占存贮空间的大小,是成员列表中所有成员所占内存空间之和。例如: 占用字节数=4+20+1+4+4+30=63,即stu1和stu2各占内存空间63个字节。 ② 定义结构体类型的同时定义结构体变量 格式如下: struct 结构体类型名 { 成员列表; }变量名列表;
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 例如: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; 定义后变量在内存中开辟的空间与第1种定义方法相同。 ③直接定义结构体类型变量(匿名定义) 格式如下: struct { 成员列表 }变量名列表;
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 其特点是在定义时不出现结构体类型名。 例如: struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; 定义后变量在内存中开辟的空间与第1种定义方法相同。 关于结构体类型说明如下: ·类型与变量是两个不同的概念,不能混淆。变量分配内存空间,类型不分配空间。 ·结构体成员可以单独使用,相当于普通变量,访问方法后面具体讲述。 ·结构体成员也可以是一个已定义好类型的结构体变量。如将上述结构体年龄成员改为生日成员。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 struct date//日期结构体 { int year; int month; int day; }; struct student1 { int num; char name[20]; char sex; float score; struct date birthday;/*birthday是struct date类型*/ char addr[30]; }stu3,stu4; 上述结构体可以由图10.2直观地表示出来。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 图10.2 结构体变量做成员示意图 变量stu3和stu4占用内存空间都是71字节。 成员名可以与程序中的变量名相同,二者不代表同一对象。程序中的num与struct student中的num是两回事,互不干扰。同学们想一想这是为什么? (2)结构体变量的初始化 结构体变量和其它简单类型变量一样,也可以初始化。 由于有三种定义变量的方法,变量初始化也有三种格式: 格式1: 例如:struct student stu1={10001,"Liming",'M',18,95.0,"HubeiEnshi"}; struct student1 stu3={10001,"Liming",'M', 95.0,1990,5,1, "HubeiEnshi"}; struct 结构体类型名 变量名={成员1初值,成员2初值,……,成员n初值};
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 格式2: 例如: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1={10001,"Liming",'M',18,95.0,"Enshi"},stu2={10002,"Wang",'F',17,93," YiChang"}; struct 结构体类型名 { 成员列表; }变量名={成员1初值,成员2初值,……,成员n初值};
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 struct date//日期结构体 { int year; int month; int day; }; struct student1 { int num; char name[20]; char sex; float score; struct date birthday;/*birthday是struct date类型*/ char addr[30]; }stu3={10001,"Liming",'M', 95.0,1990,5,1,"Enshi"}, stu4={10002,"Wang",'F',93,1991,7,23," YiChang"};
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 格式3: 初始化结构体变量时,一定要注意成员初始值顺序应当与成员定义的顺序一致,否则会出现错误。 例如: struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1={10001,"Liming",'M',18,95.0,"Enshi"}, stu2={10002,"Wang",'F',17,93," YiChang"}; struct { 成员列表; }变量名={成员1初值,成员2初值,……,成员n初值};
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 3.结构体变量的访问方法 定义变量的目的就是为了访问,结构体变量如何访问呢? C语言不允许访问结构体变量。 例如: scanf(“%d,%s,%c,%d,%f,%s”,&stu1);//错误 printf (“%d,%s,%c,%d,%f,%s”,stu1); //错误 只允许访问结构体成员变量。结构体成员变量两种访问方式: (1)结构体变量访问结构体成员变量 访问格式: “.”是成员(又叫分量)运算符,它的优先级最高。 stu1.num=10001; num左右各有一个运算符,num先和哪个运算符结合呢? 根据优先级num应先和“.”左边的stu1结合,及将stu1.num看成一个整体,也可以这样理解:num是stu1的num。 结构体变量名.成员名
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 (2)结构体指针变量访问结构体成员变量 指针可以指向变量,也可以指向结构体变量。指向结构体变量的指针叫结构体指针变量。定义结构体指针变量的方法与定义其它指向变量的指针一样。 例如: struct stuent stu1,*sp; sp=&stu;//stu是结构体变量,&stu是变量stu的首地址。 指针变量访问格式: “->”是指向运算符,它的优先级与“.”运算符的优先级相同。 sp->num=10001;与stu1.num=10001;等价。使用指针变量访问结构体成员比使用结构体变量名更方便。 【例10.1】结构体变量和结构体指针变量访问结构体成员。 程序代码: 1 struct student 2 { 3 int num; 结构体指针变量名->成员名
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 4 char name[20]; 5 char sex; 6 int age; 7 char addr[30]; 8 }stu1={10001,"Liming",'M',18,"HubeiEnshi"}; 9 #include <stdio.h> 10 void main() 11 { 12 struct student *sp=&stu1; 13 printf("结构体变量访问结构体成员\n"); 14 printf("NO.:%d\nName:%s\nSex:%c\nAge:%d\nAddr:%s", stu1.num,stu1.name,stu1.sex,stu1.age,stu1.addr); 15 printf("\n\n结构体指针变量访问结构体成员\n"); 16 printf("NO.:%d\nName:%s\nSex:%c\nAge:%d\nAddr:%s", sp->num,sp->name,sp->sex,sp->age,sp->addr); 17 printf("\n"); 18 }
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 程序运行结果: 结构体变量访问结构体成员 NO.:10001 Nmae:Liming Sex:M Age:18 Addr:HubeiEnshi 结构体指针变量访问结构体成员 NO.:10001 Nmae:Liming Sex:M Age:18 Addr:HubeiEnshi 从上述实例可以看出,用结构体变量访问结构体成员与用结构体指针变量访问结构体成员结果是一样的。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 结构体变量、结构体指针变量与其它简单类型变量、指针变量一样,也有垂直方向上的相等关系。 在有定义struct student stu,*sp=&stu;之下,&stu与sp等价,stu与*sp等价。指针变量也可以当变量使用(*sp).num,变量也可以当指针变量使用(&stu)->num。 【例10.2】结构体成员变量四种访问方法。 程序代码: 1 #include <string.h> 2 #include <stdio.h> 3 struct student 4 { 5 int num; 6 char name[20]; 7 char sex; 8 int age; 9 float score;
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 10 char addr[30]; 11 }; 12 void main() 13 { 14 struct student stu1,*sp; 15 sp=&stu1; 16 stu1.num=10001; 17 strcpy(stu1.name,"LiMing"); 18 stu1.sex='M'; 19 stu1.age=18; 20 stu1.score=89.5; 21 strcpy(stu1.addr,"HubeiEnshi"); 22 printf("No.:%d\nname:%s\nsex:%c\nage:%d\nscore:%.1f\naddr:%s\n", stu1.num,stu1.name,stu1.sex,stu1.age,stu1.score,stu1.addr); 23 printf("\n"); 24 printf("No.:%d\nname:%s\nsex:%c\nage:%d\nscore:%.1f\naddr:%s\n", (*sp).num,(*sp).name, (*sp).sex,(*sp).age, (*sp).score,(*sp).addr);
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 25 printf("\n"); 26 printf("No.:%d\nname:%s\nsex:%c\nage:%d\nscore:%.1f\naddr:%s\n", sp->num,sp->name, sp->sex,sp->age, sp->score, sp->addr); 27 printf("\n"); 28 printf("No.:%d\nname:%s\nsex:%c\nage:%d\nscore:%.1f\naddr:%s\n", (&stu1)->num,(&stu1)->name,(&stu1)->sex,(&stu1)->age, (&stu1)->score,(&stu1)->addr); 29 } 程序运行结果: No. :10001 name:LiMing sex:M age:18 score:89.5 addr:HubeiEnshi No. :10001 name:LiMing sex:M
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 age:18 score:89.5 addr:HubeiEnshi No. :10001 name:LiMing sex:M age:18 score:89.5 addr:HubeiEnshi No. :10001 name:LiMing sex:M age:18 score:89.5 addr:HubeiEnshi 从上述实例可以看出,四种访问方法结果是一样的。
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 (3)说明 ①如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级地找到最低一级的成员。只能对最低的成员进行赋值或存取操作。 例如: stu1.birthday.year=1983; stu1.birthday.month=06; stu1.birthday.day=25; ②结构体变量虽然不能进行输入输出操作,但可以进行赋值操作。 例如: struct student stu1,stu2; stu2=stu1; 该赋值语句能将stu1的所有成员按结构体专员变量顺序分别赋给stu2中的成员。结构体变量的赋值操作,要求两变量的类型相同,否则将不能得到正确的结果。 ③结构体成员变量可以像普通变量一样进行各种运算。 例如: stu1.num++; stu1.score=stu2.score; stu1.age+=2;
单元10 项目中结构体的应用---- 10.1.2 结构体类型的应用 ④可以访问结构体成员变量的地址,也可以访问结构体变量的地址。 例如: scanf(“%d”,&stu1.num); //输入一个整数送给结构体成员stu1.num printf(“%x”,&stu1);//输出结构体变量的首地址
单元10 项目中结构体的应用---- 课后作业与思考 1.填空题: (1)构造体要先定义再定义。 (2)定义结构体类型的关键字是。 (3)结构体变量占用内存空间的大小是。 2.选择题: (1)当说明一个结构体变量时系统分配给它的内存是。 A.各成员所需内存量的总和 B.结构中第一个成员所需内存量 C.成员中占内存量最大者所需的容量 D.结构中最后一个成员所需内存量 (2)有关结构体的正确描述是。 A.结构体成员必须是同一数据类型 B.结构体成员只能是不同数据类型 C.成员运算符“.”和“->”作用是等价的 D.成员就是数组元素 3.编程题: (1)自定义一个结构体类型的变量,其成员包括学号、姓名、年龄、性别,并将其类型声明为student,然后用该类型定义一个学生类型的变量,进行赋值操作,并输出其值。 (2)利用结构体类型编制一程序,实现输入一个学生的数学期中和期末成绩,然后计算并输出平均成绩。