C语言第七章结构体共用体枚举类型数据.docx
《C语言第七章结构体共用体枚举类型数据.docx》由会员分享,可在线阅读,更多相关《C语言第七章结构体共用体枚举类型数据.docx(41页珍藏版)》请在冰豆网上搜索。
C语言第七章结构体共用体枚举类型数据
第七章结构体、共用体和枚举类型数据
1.教学内容:
§7.1结构体类型概述
7.1.1结构体的概念及其定义
§7.2结构体类型变量的定义和引用
7.2.1定义结构体类型变量的方法
7.2.2结构体变量的初始化
7.2.3结构体变量的引用
7.2.4结构体的输入和输出
§7.3结构体数组
7.3.1结构体数组的定义方法
7.3.2结构体数组的初始化
7.3.3结构体数组的引用
§7.4结构体变量作为函数参数以及返回的结构体类型值的函数
7.4.1结构体变量作为函数参数
7.4.2返回的结构体类型值的函数
§7.5结构体变量与指针
7.5.1指向结构体变量的指针
7.5.2指向结构体数组的指针
7.5.3用指向结构体变量的指针作函数参数
§7.6动态存储分配---链表
7.6.1动态存储分配和链表的概念
7.6.2用包含指针项的结构体变量构成结点
7.6.3用于动态存储分配的函数
7.6.4链表应用举例
§7.7共用体类型数据
7.7.1共用体的概念
7.7.2共用体变量的引用
7.7.3共用体变量的应用
§7.8枚举类型数据
§7.9用TYPEDEF定义类型
2.教学目的及要求:
1)掌握结构体类型的概念和定义方法,结构体变量的定义和引用
2)掌握指向结构体变量的指针变量的概念和应用
3)掌握链表的概念和应用
2)掌握共用体类型的概念和应用
3)掌握枚举类型的概念和应用
3.教学重点:
结构体变量的定义和引用,结构体变量与指针,共用体引用
第七章结构体、共用体和枚举类型数据
§7.1结构体类型概述
7.1.1结构体的概念及其定义
结构体(structure)是一种数据类型,它把互相联系的数据组合成一个整体。
其定义形式:
结构体类型不同于基本数据类型,其特点有:
⑴由若干数据项组成,每一个数据项都属于一种已有定义的类型。
每个数据项称为一个结构体的成员,也可称为“域”。
它不是一个变量。
⑵结构体类型并非只有一种,它是由若干不同类型数据项组成的复合类型。
⑶定义一个结构体类型,并不意味着系统将分配一段内存单元来存放各数据项成员。
只是告诉系统成员的类型、各占的字节数、存储方式,并把它们当作一个整体来处理。
⑷凡需使用结构体类型数据,都必须在程序中自己定义。
【例】:
一个学生的学号、姓名、性别、年龄、成绩、地址,是互相联系的数据,在C语言中用“结构体(structure)”来定义。
structstudent
{
int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30];/*地址*/
};
struct 是关键字,不能省略。
student 是定义的结构体类型名。
结构体中的每一项数据,称为结构体“成员”(member)或“域”。
§7.2结构体类型变量的定义和引用
7.2.1定义结构体类型变量的方法
结构体是一种数据类型(像int、char、flaot是数据类型一样),可以用它定义变量。
用结构体类型定义变量的方式有三种:
一、在定义了一个结构体类型之后,再定义该类型变量。
【例】:
structstudent
{
int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30]; /*地址*/
};
structstudentstudent1,student2;
二、在定义一个结构体类型的同时定义结构体变量
structstudent
{
int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30]; /*地址*/
}student1,student2;
三、直接定义结构体类型的变量
struct
{
int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30]; /*地址*/
}student1,student2;
说明:
⒈结构体变量中的各成员,在内存中顺序存放。
结构体变量所占内存大小用运算符sizeof计算。
如:
printf("%d%d\n",sizeof(structstudent),sizeof(student1));
⒉结构体成员是另一个结构体变量
structdate/* 日期结构*/
{
intmonth;/*月*/
intday; /*日*/
intyear; /*年*/
};
structstudent
{
int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
structdatebirthday;/*成员是另一个结构体变量*/
char addr[30]; /*地址*/
}student1,student2;
7.2.2结构体变量的初始化
按结构体成员的数据类型,依次写出各初始值,在编译时就将它们赋给此变量中各成员。
如:
structstudent
{
longintnum; /*学号*/
charname[20]; /*姓名*/
charsex; /*性别*/
charaddr[20]; /*地址*/
}a={89031,"LiLin",'M',"123BeijingRoad"};
注意:
⑴不能在结构体内赋初值。
如:
structstudent
{
longintnum=89031;
char name[20]="LiLin";
char sex='M';
char addr[30]="123BejingRoad";
}a;
⑵如果结构体类型嵌套另一个结构体类型,则初始化时,仍然是对各个基本类型的成员给予初值。
如:
学生出生日期情况。
如:
Structstudentstudent1={89031,"LiLin",'M',12,15,1973,"123BeijingRoad"};
7.2.3结构体变量的引用
1、引用结构体变量中的一个成员
结构体变量是一个整,要访问其中的成员,必须先找到结构体变量,然后再从中找出要访问的成员。
引用结构体成员的方式:
结构体变量名.成员名
.是“成员运算符”,运算优先级最高。
如:
student1.num,student1.age
2、两个同类型的结构体变量之间赋值。
如:
student2=student1;
student2.score=student1.score;
sum=student1.score+student2.score;
3、当结构体成员是另一个结构体类型变量时,应逐级引用成员。
如:
student1.num;
student1.birthday.year;
student1.birthday=student2.birthday;
4、仅在以下两种情况下,可以把结构体变量作为一个整体来访问。
(1)结构体变量整体赋值,例、
student2=student1;
(2)取结构体变量地址,例、
printf("%x",&student1);/*输出student1的地址*/
5、不允许用赋值语句将一组常量直接赋给一个结构体变量。
Student1={89031,"LiLin",'M',"123BeijingRoad"};
7.2.4结构体的输入和输出
C语言不允许把一个结构体作为一个整体进行输入或输出。
如:
Printf("%d\n",student1);和scanf("%d\n",&student1);
如果要输出student1变量,可用语句:
printf("%d,%s,%c,%d,%f,%s",student1.num,student1.name,student1.sex,student1.age,student1.score,sutdent1.addr);
如果要输入student1变量各成员值,可用语句:
scanf("%d,%s,%c,%d,%f,%s",student1.num,student1.name,student1.sex,student1.age,student1.score,sutdent1.addr);
对字符串数组的输入和输出,可用语句:
gest(student1.name);
puts(sutdent1.addr);
§7.3结构体数组
数组中的每一个元素都是一个结构体变量。
三、举例
[例10.2] 对候选人得票的统计程序。
设有三个候选人,每次输入一个得票的候选人的名字,要求最后输出各候选人得票结果。
#include"stdio.h"
#include"string.h"
structperson /* 候选人信息结构体*/
{
charname[20];/*姓名 */
intcount;/*得票数*/
}leader[3]=
{"Li",0, "Zhang",0, "Fun",0};
voidmain()
{
inti,j;
charleader_name[20];/* 输入得票人姓名*/
for(i=1;i<=10;i++)/*设有10个人参加投票*/
{
scanf("%s",leader_name);
for(j=0;j<3;j++)/*得票人姓名与3个候选人姓名比较*/
if(strcmp(leader_name,stu[i].name)==0)
stu[i].count++;
}
printf("\n");
for(i=0;i<3;i++)/*输出3个候选人的姓名和得票数*/
printf("%5s:
%d\n",stu[i].name,stu[i].count);
}
7.3.1结构体数组的定义方法
结构体数组的定义方法与结构体变量定义方法基本相同。
可采取下列方法之一进行定义:
⑴先定义结构体类型,再定义结构体数组。
如:
structstudent
{
intnum;
charname[20];
charsex;
intage;
floatscore;
charaddr[30];
};
structstudentstu[3];/*3个元素的结构体数组*/
⑵在定义结构体类型同时定义结构体数组。
如:
structstudent
{
intnum;
charname[20];
charsex;
intage;
floatscore;
charaddr[30];
}stu[3];/*3个元素的结构体数组*/
⑶直接定义结构体数组而不定义结构体类型名。
struct
{
intnum;
charname[20];
charsex;
intage;
floatscore;
charaddr[30];
}stu[3];/*3个元素的结构体数组*/
7.3.2结构体数组的初始化
二、结构体数组的初始化
structstudent
{
intnum;
charname[20];
charsex;
intage;
floatscore;
charaddr[30];
}stu[]={/*对3个元素的结构体数组赋值*/
{10101,"LiLin", 'M',18,87.5,"103BejingRoad"},
{10102,"ZhangFun",'M',19,99, "130ShanghaiRoaad"},
{10104,"WangMin",'F',20,78.5,"1010ZhongshanRoad"}};
说明:
如果提供的初始化数据组的个数少于数组元素的个数,则方括号内的元素个数不能省略。
如:
stu[3]={{10101,"LiLin", 'M',18,87.5,"103BejingRoad"},
{10102,"ZhangFun",'M',19,99, "130ShanghaiRoaad"}}
只对前二个元素赋初值,第三个元素未赋初值,系统将对数值型的成员赋以0,对字符型数据赋以“空”(NULL)。
即“\0“。
7.3.3结构体数组的引用
结构体数组的元素相当于结构体变量,因此它的引用与结构体变量的引用方法相同。
即:
⑴引用某一元素中的成员。
如:
stu[i].num
⑵可将一个结构体数组元素赋值给同一缘木求鱼体类型的数组中另一个元素,或赋给同一类型的变量。
如:
structstudentstu[3],stu;
stu=student[0];
student[1]=student[1];
student[1]=stu;
⑶不能把结构体数组作为一个整体址接进行输入输出。
如:
printf(“%d”,stu[0]);或scanf(“%d”,stu[0]);
只能以单个成员为一个整体址接进行输入输出。
如:
scanf(“%d”,stu[0].num);
scanf(“%d”,&stu[0].num);
printf(“%d,%s,%c,%d,%f,%s”,stu[0].num;stu[0].name[20];
stu[0].sex,stu[0].age,stu[0].score,stu[0].addr[30]);
注意:
在用scanf函数输入不同类型数据时有时会出现预料不到的情况,如使用语句:
printf(“%d,%s,%c,%d,%f,%s”,&stu[0].num;stu[0].name[20];
stu[0].sex,&stu[0].age,&stu[0].score,stu[0].addr[30]);
从键盘输入:
10102,ZhangFun,M,19,99,130ShanghaiRoaad
时,出现错误,或会给出出错信息,或得到莫名其妙的信息。
这是因为输入字符串数据时,遇到空格就认为字符串结束了。
此外字符型变量接收数据时往往把其前面的间隔符(如空格)当作有效字符接收,这各错误很隐藏。
建议:
尽量不要用scanf()输入包含字符数据在内的一组不同类型的数据。
解决方法:
先用gets()输入数据,再把不同类型进行相应转换。
【例】:
#include“stdlib.h”
#include“stdio.h”
main()
{inti;
charch1,ch2,ch;
charnumstr[10];
gets(numstr);
i=stoi(numstr);/*将字符串转换成相应整数*/
ch1=getchar();
ch=getchar();/*接收ch1后输入的“回车换行符”*/
ch2=getchar();
printf(“i=%d,ch1=%c,ch2=%c\n”,i,ch1,ch2);
}
运行结果:
123←┘
a←┘
b←┘
i=123,ch1=a,ch2=b
C语言标准函数库提供了一些转换函数:
atoi()将字符串转换为整数
atof()将字符串转换为实数(双精度型,即double型)
atol()将字符串转换为长整数
【例】:
输入3个学生的信息并打印出来。
#include“stdlid.h”
#include“stdio.h”
structstud_type
{charname[20];
longnum;
intage;
charsex;
floatscore;
};
main()
{structstud_typestudent[3];
inti;
charch,numstr[20];
for(i=0;I<3;i++)
{printf(“\nenteralldataofstudent[%d]:
\n”,i);
gest(student[i].name);
gets(numstr);student[i].num=atoll(numstr);
gets(numstr);student[i].age=atoll(numstr);
student[i].sex=getchar();ch=getchar();
gets(numstr);student[i].score=atoll(numstr);
}
printf(“\nrecordname\t\tnumagesexscore\n”)
for(i=0;i<3;i++)
print(“%3d%-20s%8d%6d%3c%6.2f\n”,i,student[i].name,
student[i].num,student[i].age,student[i].sex,
student[i].score);
}
说明:
⑴getchar()吸收输入的“回车键”字符。
⑵%-20s左对齐20个字符组成的串。
§7.4结构体变量作为函数参数以及返回的结构体类型值的函数
7.4.1结构体变量作为函数参数
直接将实参结构变量的各个成员的值全部传递给形参的结构体变量。
【例】:
输入3个学生的信息并打印出来。
#include“stdlid.h”
#include“stdio.h”
structstud_type
{charname[20];
longnum;
intage;
charsex;
floatscore;
};
main()
{viodlist(structstud_typestudent);
structstud_typestudent[3];
inti;
charch,numstr[20];
for(i=0;i<3;i++)
{printf(“\nenteralldataofstudent[%d]:
\n”,i);
gest(student[i].name);
gets(numstr);student[i].num=atoll(numstr);
gets(numstr);student[i].age=atoll(numstr);
student[i].sex=getchar();ch=getchar();
gets(numstr);student[i].score=atoll(numstr);
}
printf(“\nrecordname\t\tnumagesexscore\n”)
}
viodlist(structstud_typestudent)
{print(“%3d%-20s%8d%6d%3c%6.2f\n”,i,student[i].name,
student[i].num,student[i].age,student[i].sex,
student[i].score);
}
说明:
结果与上例相同。
7.4.2返回的结构体类型值的函数
一个函数可返回一个函数值(整型、实形、字符型、指针型等)。
新的C标准允许函数返回一个结构类型的值。
【例】:
输入3个学生的信息并打印出来。
#include“stdlid.h”
#include“stdio.h”
structstud_type
{charname[20];
longnum;
intage;
charsex;
floatscore;
};
main()
{voidlist(structstud_typestudent);
structstud_typenew_element(void);
structstud_typestudent[3];
inti;
for(i=0;i<3;i++)
student[i]=new_element();/*函数调用输入*/
printf(“\nname\t\tnumagesexscore\n”)
for(i=0;i<3;i++)
list(student[i]);/*函数调用输出*/
}
structstud_typenew_element(void)
{structstud_typestudent
charch,numstr[20];
printf(“\nenteralldataofstudent[%d]:
\n”,i);
gest(student[i].name);
gets(numstr);student[i].num=atoll(numstr);
gets(numstr);student[i].age=atoll(numstr);
student[i].sex=getchar();ch=getchar();
gets(numstr);student[i].score=atoll(numstr);
return(student);
}
voidlist(structstud_typestudent)
{printf(“\nrecordname\t\tnumagesexscore\n”)
print(“%3d%-20s%8d%6d%3c%6.2f\n”,i,student.name,
student.num,student.age,student.sex,
student.score);
注意:
类型structstud_type的定义写在所有函数之前,使得在所有函数中都可利用它来定义所需的变量。
§7.5结构体变量与指针
在C中可以定义一个指针变量指向一个结构变量。
7.5.1指向结构体变量的指针
结构体变量的指针是这个结构体变