第7章 结构体与共用体.docx
《第7章 结构体与共用体.docx》由会员分享,可在线阅读,更多相关《第7章 结构体与共用体.docx(15页珍藏版)》请在冰豆网上搜索。
![第7章 结构体与共用体.docx](https://file1.bdocx.com/fileroot1/2023-7/12/edfdfc97-ef20-42d9-9f55-68f62e82bd67/edfdfc97-ef20-42d9-9f55-68f62e82bd671.gif)
第7章结构体与共用体
第7章 结构体与共用体
知识网络图
考点分析
7.1概述
数组只能存放一组类型完全相同的数据,无法实现对不同类型的一组数据的存放。
因此需要使用结构体。
结构体(structure)是一种数据类型,它把互相联系的数据组合成一个整体。
例、
一个学生的学号、姓名、性别、年龄、成绩、地址,是互相联系的数据,在C语言中用“结构体(structure)”来定义。
structstudent
{int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30]; /*地址*/
};
structstudenta,b;
struct 是关键字,不能省略。
student 是定义的结构体类型名。
结构体中的每一项数据,称为结构体“成员”。
structYG
{intbh;
charxm[20];
floatgz,jj,sf;};
structYGx,y;
7.2结构体变量的定义
结构体是一种数据类型(像int、char、float是数据类型一样),可以用它定义变量。
用结构体类型定义变量的方式有两种:
一、先定义结构体类型,再定义变量:
struct类型名变量名;
例:
structstudent
{int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char addr[30]; /*地址*/ };
structstudentstudent1,student2;
结构体变量中的各成员,在内存中顺序存放。
结构体变量所占内存大小用运算符sizeof计算(结构体变量长度=所有成员长度之和)。
例:
printf("%d%d\n",sizeof(structstudent),sizeof(student1));
结果为:
5959
二、在定义类型的同时定义变量(此时可省略类型名)
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;
三、结构体类型的嵌套定义
structstudent
{int num; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
structdate
{intyear,month,day;}birthday;/*成员是另一个结构体变量*/
char addr[30]; /*地址*/
}student1,student2;
7.3结构体变量的引用
1、结构体变量成员的引用方法
结构体变量名.成员名
.是“成员运算符”
例1:
printf("%d,%s,%c,%d,%f,%s",student1.num,student1.name,student1.sex, student1.age,student1.score,sutdent1.addr);
printf("%d,%s,%c,%d,%f,%s",student1);是错误的。
例2:
student2.score=student1.score;
sum=student1.score+student2.score;
student1.age++;
++student1.age;
例3:
scanf("%d",&student1.num);scanf("%s",student1.name);
scanf("%d%s",&student1.num,student1.name);
2、当结构体类型嵌套定义时,内层成员的引用
例4:
student1.birthday.month;
student1.birthday.day;
student1.birthday.year;
3、仅在以下两种情况下,可以把结构体变量作为一个整体来访问
结构体变量整体赋值
例:
student2=student1;
student2.num=student1.num;
strcpy(student2.name,student1.name);
student2.sex=student1.sex;
student2.age=student1.age;
student2.birthday.year=student1.birthday.year;
取结构体变量地址:
&student1
7.4结构体变量的初始化
structstudent
{longnum; /*学号*/
charname[20]; /*姓名*/
charsex; /*性别*/
charaddr[20]; /*地址*/
};
structstudenta={89031,"LiLin",'M',"123BeijingRoad"},b={12121,"Lining",'M',"123xinfuRoad"};
7.5结构体数组
一、结构体数组的定义
structstudent
{intnum;
charname[20];
charsex;
intage;
floatscore;
charaddr[30];
};
structstudentstu[3];/* 3个元素的结构体数组*/
二、结构体数组的初始化
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"}};
三、举例
[例] 对候选人得票的统计程序。
设有三个候选人,每次输入一个得票的候选人的名字,要求最后输出各候选人得票结果。
#defineN10
#include"stdio.h"
#include"string.h"
structhxr
{charname[20];
intcount;}a[3]={{"Li",0},{"zhang",0},{"wang",0}};
main()
{inti,j;
charb[20];
for(i=1;i<=N;i++)
{scanf("%s",b);
if(strcmp(b,a[0].name)==0)a[0].count++;
if(strcmp(b,a[1].name)==0)a[1].count++;
if(strcmp(b,a[2].name)==0)a[2].count++;}
printf("\n");
for(i=0;i<3;i++)
printf("%5s:
%d\n",a[i].name,a[i].count);}
7.6结构体指针
一、结构体指针
结构体指针:
指向结构体变量的指针。
例:
structstudent
{
longnum;
char name[20];
char sex;
float score;
};
structstudentstu_1;
/*结构体变量*/
structstudent*p;
/*结构体指针*/
p=&stu_1;*pstu_1
结构体指针,通过指向运算符->引用结构体中的成员:
指针变量->成员名
p->num(*p).numstu_1.num
p->name(*p).namestu_1.name
p->sex(*p).sexstu_1.sex
p->score(*p).scorestu_1.score
(*p).num方式几乎不用。
注意:
()[].->的优先级别并列第一
二、指向结构体数组的指针
structstudentstu[3];
structstudent*p=stu;/*指向stu[0]*/
stu[i]*(stu+i)p[i]*(p+i)
三、举例
[例1]有4个学生,每个学生包括学号、姓名和成绩。
要求找出成绩最高者的姓名和成绩。
方法一:
structstudent
{intnum;
charname[20];
intscore;};
main()
{structstudentstu[4],max;
inti;
for(i=0;i<4;i++)
scanf("%d%s%d",&stu[i].num,stu[i].name,&stu[i].score);
max=stu[0];
for(i=1;i<4;i++)
if(max.scoreprintf("\nmax:
\n");
printf("No.:
%d\nname:
%s\nscore:
%d\n",max.num,max.name,max.score);
}
方法二:
structstudent
{intnum;
charname[20];
intscore;};
main()
{structstudentstu[4],*p;
inti;
printf("\ninput4students:
");
for(i=0;i<4;i++)
scanf("%d%s%d",&stu[i].num,stu[i].name,&stu[i].score);
for(p=&stu[0],i=1;i<4;i++)
if(p->scoreprintf("\nmax:
\n");
printf("No.:
%d\nname:
%s\nscore:
%d\n",p->num,p->name,p->score);
}
7.7共用体
一、共用体的概念
共用体的定义形式:
union共用体名
{成员列表;};
a.w[0]
a.w[1]
union共用体名变量列表;
unionqq
{longx;
charw[2];};
unionqqa;
注意区分:
“共用体”:
各成员占相同的起始地址(有共处存储单元的特点,故称为共用类型),所占内存长度等于最长的成员所占字节数。
“结构体”:
各成员占不同的地址,所占内存长度等于全部成员所占字节数之和。
二、共用体变量成员的引用变量名.成员名
uniondata
{shortx;
shorty;}a;
变量a的成员为:
a.xa.y
三、共用体类型数据的特点
1、共用体变量中的值是最后一次存放的成员的值,如:
uniondata
{shortx;
shorty;}a;
a.x
a.y
00000111
00000000
a.x=6;a.y=7;
完成以上两个赋值语句后,a.x与a.y的值均是7。
2、共用体变量不能初始化,例、
uniondata
{intx;
chary;}a={6,7};
注意:
1.共用类型数据长度的求解:
长度等于最长的成员所占字节数。
2.共用类型数据成员值的求解。
例1:
写出程序的运行结果:
#include"stdio.h"
main()
{uniondata
{shortx;
shorty;}a;
a.x=3;a.y=4;
printf(“%d”,a.x+a.y);}结果:
8
例2:
写出程序的运行结果:
#include"stdio.h"
main()
{uniondata
{shortx;
charw[2];}a;
a.x=0x1213;
printf(“%d,%d”,a.w[0],a.w[1]);
printf(“\n%x,%x”,a.w[0],a.w[1]);}
a.x
a.w[0]0x13
a.w[1]0x12
结果:
19,18
13,12
例3:
写出程序的运行结果:
#include"stdio.h"
main()
{uniondata
{shortx;
charw[2];}a;
a.w[0]=0x03;a.w[1]=0x01;
printf(“%d,%d”,a.x,a.w[0]);}
a.x
a.w[0]0x03
a.w[1]0x01
a.x=0x0103
a.w[0]=0x03
结果为:
259,3
例4:
写出程序的运行结果:
#include"stdio.h"
main()
{unionaa
{doublex[3];
floaty[2];
charw[6];};
structbb
{longx,y;
unionaaz;
charw[2];}a,b[2];
printf(“%d”,sizeof(a)+sizeof(structbb)+sizeof(b));}
结果为:
13634+34+68
7.8枚举类型
如果一个变量只有几种可能的值,可以定义为枚举类型。
“枚举”:
将变量可能的值一一列举出来。
变量的值只能取列举出来的值之一。
用关键字enum定义枚举类型:
例:
enumweekday{sun,mon,tue,wed,thu,fri,sat};
weekday是枚举类型名,可以用于定义变量,如、
enumweekdaywork,rest;
定义了两个枚举变量:
work与rest,它们只能取sun到sat之一,如、
work=mon;
rest=sun;
sun、mon、....、sat称为“枚举常量”。
说明:
1、枚举常量在C编译器中,按定义的顺序取值0、1、2、...。
例:
work=mon;
printf("%d",work);输出整数1。
2、枚举常量不能被赋值。
sun=0;mon=1;
但在定义枚举类型时,可以指定枚举常量的值,如:
enumweekday{sun=6,mon=0,tue,wed,thu,fri,sat};
此时,未指定值的枚举常量比前一枚举常量大1。
如,tue的值为1。
enumww{three=3,two,one=1};two为4
3、枚举值可以作判断,例:
if(work==mon)....
if(work>sun)....
4、整型与枚举类型是不同的数据类型,不能直接赋值(在turboC中例外),如、
work=2;
/*work是枚举类型,在turboC中正确*/
但可以通过强制类型转换赋值,如、
work=(enumweekday)2;work=wed;
5枚举常量必须是满足用户标识符的命名规则,不能是已存在的常量。
如:
enumww{1,2,3,4};
enumww{“aa”,“bb”,“cc”};
enumww{‘a’,‘b’,‘c’};
例:
#include"stdio.h"
main()
{inta[5]={100,200,300,400,500},s=0;
enumcolor{red,yellow,blue,white,black}i;
for(i=red;i<=black;i++)s=s+a[i];
printf(“\n%d”,s);}
结果为:
1500
7.9用typedef定义类型
用户自定义类型是为了将已经存在的类型重新取一个新的名字,以便于书写。
(1)对基本类型的自定义
typedef unsignedlongAA;
AAx,y,a[10],*p;等价于unsignedlongx,y,a[10],*p;
(2)对指针类型的自定义
typedef int *W;
Wp,q;等价于int*p,*q;
(3)对结构类型的自定义
typedef structstu STU;
STUx,a[4];等价于structstux,a[4];
typedefstruct
{intmonth;
intday;
intyear;}DATE;
DATEbirthday,*p,d[7];等价于
struct
{intmonth;
intday;
intyear;}birthday,*p,d[7];
(4)对数组类型的自定义
typedef doubleBB[10];
BBx,y;等价于doublex[10],y[10];