390 likes | 527 Views
实验八 结构体编程. 张智丰. 一、实验目的. 掌握结构的定义、初始化和引用; 掌握利用结构函数进行参数传递; 掌握结构数组和结构指针引用成员变量的区别。. 二、实验内容. 在实际问题中,一组数据往往具有不同的数据类型。例如,在学生情况登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,C语言中给出了一种构造数据类型 —“ 结构 ” 。
E N D
实验八 结构体编程 张智丰
一、实验目的 • 掌握结构的定义、初始化和引用; • 掌握利用结构函数进行参数传递; • 掌握结构数组和结构指针引用成员变量的区别。
二、实验内容 • 在实际问题中,一组数据往往具有不同的数据类型。例如,在学生情况登记表中,姓名应为字符型;学号可为整型或字符型;年龄应为整型;性别应为字符型;成绩可为整型或实型。显然不能用一个数组来存放这一组数据。因为数组中各元素的类型和长度都必须一致,以便于编译系统处理。为了解决这个问题,C语言中给出了一种构造数据类型—“结构”。 • “结构”是一种构造类型,它由若干“成员”组成。 每一个成员可以是一个基本数据类型, 也可以是一个构造类型。 • 因为是构造类型,因此要先定义,后使用。
二、实验内容 • 定义一个结构的一般形式为: struct结构名 { 成员表 }; • 个问题,C语言中给出了一种构造数据类型—“结构”。 • “结构”是一种构造类型,它由若干“成员”组成。 每一个成员可以是一个基本数据类型, 也可以是一个构造类型。 • 因为是构造类型,因此要先定义,后使用。
1.结构的定义 • 定义一个结构的一般形式为: struct结构名 { 成员表 }; 成员表由若干个成员组成,每个成员都是该结构的一个组成部分。对每个成员也必须作类型说明,其形式为: 类型说明符 成员名;
2.结构类型变量的声明与定义 • 下面的代码段声明一个定义了学号和姓名的结构。关键字struct告诉编译器已声明了一个结构。 struct stu { int num; 成员表由若干个成员组成,每个成员都是该结构的一个组成部分。对每个成员也必须作类型说明,其形式为: 类型说明符 成员名;
2.结构类型变量的声明与定义 • 下面的代码段声明一个定义了学号和姓名的结构。关键字struct告诉编译器已声明了一个结构。 struct stu { int num; char name[20]; char sex; float score; };
2.结构类型变量的声明与定义 • 注意,这个声明用分号结束。这是因为一个结构声明就是一条语句。结构的类型名是stu,stu标识了这个特殊的数据结构,并成为其类型限定符。在定义一个结构时,你正在定义一个复合变量类型,而不是一个变量。 • 要声明一个stu类型的变量,必须写成如下形式: char name[20]; char sex; float score; };
注意,这个声明用分号结束。这是因为一个结构声明就是一条语句。结构的类型名是stu,stu标识了这个特殊的数据结构,并成为其类型限定符。在定义一个结构时,你正在定义一个复合变量类型,而不是一个变量。注意,这个声明用分号结束。这是因为一个结构声明就是一条语句。结构的类型名是stu,stu标识了这个特殊的数据结构,并成为其类型限定符。在定义一个结构时,你正在定义一个复合变量类型,而不是一个变量。 • 要声明一个stu类型的变量,必须写成如下形式: struct stu stu_info; • 在上述stu结构定义中,所有的成员都是基本数据类型或数组类型。 • 成员也可以又是一个结构,构成嵌套的结构。下面代码段给出了另一个数据结构。
struct date • { • int month; • int day; • int year; • }; • 要声明一个stu类型的变量,必须写成如下形式: struct stu stu_info; • 在上述stu结构定义中,所有的成员都是基本数据类型或数组类型。 • 成员也可以又是一个结构,构成嵌套的结构。下面代码段给出了另一个数据结构。
struct date • { • int month; • int day; • int year; • }; • typedef struct boy_tag • { • int num; • char name[20]; • char sex; • struct date birthday; • float score; • }boy_info;
首先定义一个结构date,由month(月)、day(日)、year(年) 三个成员组成。在定义并说明变量 boy1和 boy2时,其中的成员birthday被说明为data结构类型。成员名可与程序中其它变量同名,互不干扰。 • typedef struct boy_tag • { • int num; • char name[20]; • char sex; • struct date birthday; • float score; • }boy_info;
首先定义一个结构date,由month(月)、day(日)、year(年) 三个成员组成。在定义并说明变量 boy1和 boy2时,其中的成员birthday被说明为data结构类型。成员名可与程序中其它变量同名,互不干扰。 • 上面的语句定义了结构struct boy_tag的一个别名:boy_info,作为类型名来使用。 • 因此可以用boy_ info作为一种数据类型来声明结构变量boy1,boy2。这里boy_tag称为结构标识。即 • boy_info boy1, boy2;
函数可以有结构类型的实际参数和返回值。下面来看两个例子。当把结构part(定义为stu类型)用作实际参数时,第一个函数显示出结构的成员: • void print_stu(struct stu stu_info) • 上面的语句定义了结构struct boy_tag的一个别名:boy_info,作为类型名来使用。 • 因此可以用boy_ info作为一种数据类型来声明结构变量boy1,boy2。这里boy_tag称为结构标识。即 • boy_info boy1, boy2;
3.结构作为函数的形参 • 函数可以有结构类型的实际参数和返回值。下面来看两个例子。当把结构part(定义为stu类型)用作实际参数时,第一个函数显示出结构的成员: • void print_stu(struct stu stu_info) • { • printf("stu number: %d\n", stu_info.num); • printf("stu name: %s\n", stu_info.name); • printf("stu sex: %c\n", stu_info.sex); • printf("stu score: %f\n", stu_info. score); • }
3.结构作为函数的形参 • 下面是 print_stu 可能的调用方法: • print_stu(part); • 第二个函数返回结构stu • printf("stu number: %d\n", stu_info.num); • printf("stu name: %s\n", stu_info.name); • printf("stu sex: %c\n", stu_info.sex); • printf("stu score: %f\n", stu_info. score); • }
下面是 print_stu 可能的调用方法: • print_stu(part); • 第二个函数返回结构stu:
struct stu build_stu(int number, const char* name, • char sex, float score) • { • struct stu stu_info; • stu_info. number = number; • strcpy (stu_info.name, name); • stu_info. sex = sex; • stu_info. score = score; • return stu_info; • }
在ANSI C标准中允许用结构变量作函数参数进行整体传送。但是这种传送要将全部成员逐个传送,特别是成员为数组时将会使传送的时间和空间开销很大,严重地降低了程序的效率。 因此最好的办法就是使用指针,即用指针变量作函数参数进行传 • strcpy (stu_info.name, name); • stu_info. sex = sex; • stu_info. score = score; • return stu_info; • }
在ANSI C标准中允许用结构变量作函数参数进行整体传送。但是这种传送要将全部成员逐个传送,特别是成员为数组时将会使传送的时间和空间开销很大,严重地降低了程序的效率。 因此最好的办法就是使用指针,即用指针变量作函数参数进行传送。这时由实参传向形参的只是地址,从而减少了时间和空间的开销。 • 下面的程序用结构指针变量作函数参数,计算学生的平均成绩和不及格的人数。 注意:用结构指针引用结构成员与用结构变量引用结构成员之间的不同。
#include <stdio.h> • struct stu • { • int num; • char *name; • char sex; • float score; • 时间和空间的开销。 • 下面的程序用结构指针变量作函数参数,计算学生的平均成绩和不及格的人数。 注意:用结构指针引用结构成员与用结构变量引用结构成员之间的不同。
应用实例 • #include <stdio.h> • struct stu • { • int num; • char *name; • char sex; • float score; • }boy[5]={ • {101,"Li ping",'M',45}, • {102,"Zhang ping",'M',62.5}, • {103,"He fang",'F',92.5}, • {104,"Cheng ling",'F',87}, • {105,"Wang ming",'M',58} • }; • void ave(struct stu *ps);
int main() { struct stu *ps; ps = boy; ave(ps); return 0; } void ave(struct stu *ps) { int c = 0, i; float ave, s = 0; for (i = 0; i < 5; i++, ps++) { s += ps->score; if (ps->score < 60) { c += 1; } } printf("s=%f\n",s); ave = s/5; printf("average=%f\ncount =%d\n", ave, c); }
例2. 以下程序中存在一些错误,请调试纠正。 • 某班有若干名学生,每一位学生的信息包括学号、姓名、3门课程的成绩。定义一个可以存放5个学生的结构体数组,实现对结构体数组的输入与输出。 • #include <stdio.h> • struct student • { //定义结构类型 • long int number; //学号 • char name[8]; //姓名 • float score[3]; //3门课成绩 • };
main() • { • struct student stud[5]; • int i,j; • for(i=0;i<5;i++) //输入 • { • { //定义结构类型 • long int number; //学号 • char name[8]; //姓名 • float score[3]; //3门课成绩 • };
main() • { • struct student stud[5]; • int i,j; • for(i=0;i<5;i++) //输入 • { • scanf("%ld",&stud[i].number); • scanf("%s",stud[i].name); • for(j=0;j<3;j++) • scanf("%f",&stud[i].score[j]); • }
printf("\n学号 姓名 数学 英语\n"); //输出 • for(i=0;i<5;i++) • { • printf("%ld",number); • printf("%7s",stud[i].name); • for(j=0;j<3;j++) • scanf("%ld",&stud[i].number); • scanf("%s",stud[i].name); • for(j=0;j<3;j++) • scanf("%f",&stud[i].score[j]); • }
printf("\n学号 姓名 数学 英语\n"); //输出 • for(i=0;i<5;i++) • { • printf("%ld",number); • printf("%7s",stud[i].name); • for(j=0;j<3;j++) • printf("%7.1f",stud[i].score[j]); • printf("\n"); • } • return 0; • }
例3.阅读以下程序,分析结果,理解结构体变量和结构体指针引用成员变量的区别。例3.阅读以下程序,分析结果,理解结构体变量和结构体指针引用成员变量的区别。 • #include <stdio.h> • #include <string.h> • struct student • { • long int num; • char name[20]; • char sex; • float score; • };
void main() • { • struct student stu1,*p; • p=&stu1; • stu1.num=89101; • strcpy(stu1.name,"Li Lin"); • p->sex='M'; • p->score=89.5; • printf("\nNo:%ld\nname: %s\nsex: • %c\nscore: %f\n", (*p).num,p->name, • stu1.sex, p->score); • }
main() • { • int i,j,max,maxi,sum; • float average; • /*********************** • 输 入 • ***********************/ • for(i=0;i<5;i++) • { • printf("\n输入学生%d的成绩:\n",i+1); • printf("学号:"); • scanf("%s",stu[i].num); • printf("姓名:"); • scanf("%s",stu[i].name);
for(j=0;j<3;j++) • { • printf("成绩%d:",j+1); • scanf("%d",&stu[i].score[j]); • } • } • /************************ • 计 算 • ************************/ • average=0; • max=0; • maxi=0; • for(i=0;i<5;i++) • { • sum=0; • for(j=0;j<3;j++) • sum+=stu[i].score[j];
stu[i].avr=sum/3.0; • average+=stu[i].avr; • if(sum>max) • { • max=sum; • maxi=i; • } • } • average/=5; • /************************ • 输 出 • *************************/
printf(" 学号 姓名 成绩1 成绩2 成绩3 平均分\n"); • for(i=0;i<5;i++) • { • printf("%8s%10s",stu[i].num,stu[i].name); • for(j=0;j<3;j++) • printf("%7d",stu[i].score[j]); • printf(" %6.2f\n",stu[i].avr); • } • printf("平均成绩为%5.2f\n",average); • printf(“平均成绩最高是学生 %s,总分是 %d\n”, • stu[maxi].name,max); • return 0; • }
要求定义一个保存学生情况的结构体,编写函数input()用结构数组来输入学生的数据,编写函数count()计算三门课的总平均成绩以及最高分的学生的数据,编写函数output采用结构指针的方式输出5个学生的数据。要求定义一个保存学生情况的结构体,编写函数input()用结构数组来输入学生的数据,编写函数count()计算三门课的总平均成绩以及最高分的学生的数据,编写函数output采用结构指针的方式输出5个学生的数据。 • 2.在屏幕上模拟显示一个数字式时钟 • 1)要求定义一个时钟结构体类型(时间以时、 • 分、秒表示); • 2)能够更新时间、显示时间; • 3)能计算两个时刻之间的时间差(二个时刻的 • 差小于24小时),并将其值返回。
提示:下面的代码取得并显示当前时间。可利用退格符’\r’来覆盖原来显示的内容。提示:下面的代码取得并显示当前时间。可利用退格符’\r’来覆盖原来显示的内容。 • #include <stdio.h> • #include <time.h> • #include <windows.h> • int main(void) • { • time_t ltime; • struct tm *today;
while(1) • { • time(<ime); • today = localtime(<ime); • printf("%2d:%2d:%2d", today->tm_hour, • today->tm_min,today->tm_sec); • printf("\r\r\r\r\r\r\r\r"); • sleep(1000); • } • return 0; • }
上面的程序用到头文件time.h里的time()函数和localtime()函数,上面的程序用到头文件time.h里的time()函数和localtime()函数, • sleep函数让本过程睡眠1秒。但此程序只能用Ctrl+c强行退出。 • 函数原型: time_t time(time_t *timer) • 函数用途: 得到机器的日历时间或者设置日历时间 • 头 文 件: time.h • 输入参数: timer:=NULL时,得到机器日历时间,=时间数时 • 用于设置日历时间; time_t是一个long类型 • 函数原型: struct tm *localtime(const time_t *timer) • 函数用途: 返回一个以tm结构表达的机器时间信息 • 头 文 件: time.h • 输入参数: timer:使用time()函数获得的机器时间;
结构tm的定义为: • struct tm • { • int tm_sec; /* Seconds: 0-59 (K&R says 0-61?)*/ • int tm_min; /* Minutes: 0-59 */ • int tm_hour; /* Hours since midnight: 0-23 */ • int tm_mday; /* Day of the month: 1-31 */ • int tm_mon; /* Months *since* january: 0-11 */ • int tm_year; /* Years since 1900 */ • int tm_wday; /* Days since Sunday (0-6) */ • int tm_yday; /* Days since Jan. 1: 0-365 */ • int tm_isdst; /* +1 Daylight Savings Time, • 0 No DST, -1 don't know */ • };