C语言结构体与共用体.ppt
第九章,结构体与共用体,内容提要,1 结构体类型2 结构体数组3 结构体指针变量4 链表5 共用体6 枚举类型7 典型例题,结构体结构体是一种构造数据类型(自定义类型)。结构体的使用分三步:(1)定义结构体类型(2)定义结构体变量(3)使用结构体变量,9.1结构体类型,9.1结构体类型,结构体类型定义,struct 结构体名 类型标识符 成员名1;类型标识符 成员名2;.;,struct是关键字,不能省略,合法标识符可省:无名结构体,成员类型可以是基本型或构造型,“;”不能省略,结构体类型定义,例如:struct stu/struct是关键字,stu是结构体名/该结构体类型由5个成员组成,分别属于不同的数据类型 long num;char name20;char sex;int age;char addr30;,结构体类型变量的定义,1先定义结构体类型再定义变量其一般形式为:struct 结构体名 变量名列表;例如:struct stu student1,student2;定义两个stu类型的变量student1和student2,结构体类型变量的定义,2在定义结构体类型的同时定义变量其一般形式为:struct 结构体名/中的内容是可选项 成员列表;变量名列表;,例 struct stu long num;char name20;char sex;int age;char addr30;student1,student2;,结构体类型变量的定义,注意:(1)类型和变量是不同的概念,编译时只对变量分配空间,对类型不分配空间。(2)结构体中的成员可以是普通变量,也可以是除自身之外的其它结构体变量。(3)成员名可与程序中其它变量同名,二者不代表同一对象,互不干扰。(4)结构体变量定义以后,系统为其分配存储空间,在VC+环境下分配存储空间的大小与所设置的字节对齐有关。,例 struct date/声明一个结构体变量 int month;int day;int year;struct stu long num;char name20;char sex;struct date birthday;/成员birthday是struct data类型 char addr30;student1,student2;,例#pragma pack(1)/设置为1字节对齐 main()struct test char m1;int m2;double m3;m;printf(变量m所占字节数为:%d,sizeof(m);#pragma pack()/恢复对齐状态,结构体变量的使用,结构体变量名引用成员(1)结构体变量的使用方式是分别使用变量中的各个成员,而不能整体使用。引用的一般形式:结构体变量名.成员名 其中,“.”运算符是成员运算符。(2)如果成员本身又是结构体类型,则需使用成员运算符逐级访问。,结构体变量的使用,(3)同一种类型的结构体变量之间可以整体赋值。例如:student2=student1;(4)可以使用结构体变量成员的地址,也可以使用结构体变量的地址。例如:scanf(%d,/输出student1的首地址,结构体变量的初始化,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.;struct 结构体名 结构体变量=初始数据;,例 struct stu long num;char name20;char sex;int age;char addr30;struct stu stu1=11301,“Wang Lin”,M,19,“200 Beijing Road”;,形式一,结构体变量的初始化,例 struct stu long num;char name20;char sex;int age;char addr30;stu1=11301,“Wang Lin”,M,19,“200 Beijing Road”;,struct 结构体名 类型标识符 成员名;类型标识符 成员名;.结构体变量=初始数据;,形式二,结构体变量的赋值,例 struct stu long num;char name20;char sex;void main()struct stu stu1;stu1.num=11201;strcpy(stu1.name,Li Ping);/字符串复制函数 stu1.sex=M;注:stu1.name=“Li Ping”;是错误的。,9.2 结构体数组,结构体数组的定义(1)先定义结构体类型在定义结构体数组,例 struct stu long num;char name20;char sex;int age;char addr30;struct stu student5;,结构体数组的定义,(2)在定义结构体类型的同时定义结构体数组,例 struct stu long num;char name20;char sex;int age;char addr30;student5;,注:结构体数组中某元素成员的使用格式为:数组名下标.成员名。,结构体数组的初始化,形式一,例 struct stu long num;char name20;char sex;float score;;struct stu student5=11001,Li ping,M,45,11002,Zhang ping,M,62.5,11003,He fang,F,92.5,11004,Chen bing,F,87,11005,Wang ming,M,58;,结构体数组的初始化,形式二,例 struct stu long num;char name20;char sex;float score;;student5=11001,Li ping,M,45,11002,Zhang ping,M,62.5,11003,He fang,F,92.5,11004,Chen bing,F,87,11005,Wang ming,M,58;,9.3 结构体指针变量,1结构体指针变量定义的一般形式 struct 结构体名*结构体指针变量名;2通过结构体指针变量访问结构体变量成员的形式(1)(*结构体指针变量名).成员名。注意:.运算符优先级比*运算符高。(2)结构体指针变量名-成员名。其中:-是指向成员运算符,很简洁,更常用。,指向结构体的指针,例 struct stu long num;char name20;char sex;float score;student=11001,Liping,M,45;struct stu*p;p=,指向结构体数组的指针,struct stu long num;char name20;char sex;float score;stu3=11001,Li Ping,M,45,11002,Zhang Ping,M,62.5,11003,Wang Ming,F,92.5;main()struct stu*p;for(p=stu;pnum,p-name,p-sex,p-score);,结构体变量作函数参数,结构体变量作函数参数是采用“传值”方式,即分别为形参和实参分配内存空间,“形实参结合”是将实参各成员值传递给形参所对应成员。注:实参和形参的结构体变量类型应当完全一致,#include#include struct stu long num;char name20;char sex;float score;void main()void print(struct stu);struct stu student1=11001,Li ping,M,45;print(student1);void print(struct stu student)/输出结构体student中各成员值 printf(no=%ld,name=%s,sex=%c,score=%fn,student.num,student.name,student.sex,student.score);,指向结构体变量的指针作函数参数,结构体指针变量作函数参数是采用“传址”方式,“形实参结合”是指将实参值(一个结构体变量的指针)传递给形参指针变量。通过指针来传递结构体变量的地址给形参,再通过形参指针变量引用结构体变量中成员的值。,#include#include struct stu long num;char name20;char sex;float score;void main()void print(struct stu*);struct stu student5=11001,Li ping,M,45,11002,Zhang ping,M,62.5,11003,He fang,F,92.5,11004,Cheng ling,F,87,11005,Wang ming,M,58;struct stu*p1;printf(num name sex score n);for(p1=student;p1num,p-name,p-sex,p-score);,9.4 链表,什么是链表?所谓链表是指若干个数据项(每个数据项称为一个“结点”)按一定的原则连接起来。每个数据项都包含有若干个数据和一个指向下一个数据项的指针,依靠这些指针将所有的数据项连接成一个链表。,9.4 链表,链表结构,struct stu long num;char*name;sturct stu*next;struct stu*head;,单向链表结构示意图,注:链表必须有一个头指针,任何操作都是在表头开始。,动态存储分配函数,动态分配存储根据需要开辟或释放存储单元相关函数malloc函数calloc函数free函数注:应包含malloc.h或stdlib.h,动态存储分配函数,(1)malloc函数。void*malloc(unsigned int size)功能:在内存动态存储区中分配一个长度为size的连续(2)calloc函数。void*realloc(void*mem_address,unsigned int newsize)功能:改变mem_address所指内存空间的大小为newsize长度。(3)free函数。void free(void*ptr)功能:将指针变量ptr指向的存储空间释放。,链表的操作,基本操作 建立链表 输出链表 插入结点 删除结点 查找一个结点,建立链表,struct stu*p1,*p2;head=(struct stu*)malloc(LEN);/建立头结点head-next=NULL;p1=head;p2=(struct stu*)malloc(LEN);/建立第一个结点scanf(%ld,%f,建立链表,while(p2-num!=0)/将建立的结点依次插入到链表中 p2-next=p1-next;p1-next=p2;p1=p2;/p1始终指向链尾结点 p2=(struct stu*)malloc(LEN);scanf(%ld,%f,输出链表,while(p!=NULL)/依次输出链表中各结点的值 printf(%ld%5.1fn,p-num,p-score);p=p-next;/p指针后移,.,.,插入一个结点,p1=head-next;p2=head;while(p0-nump1-num),删除一个结点,while(num!=p1-num/将删除结点从链表中摘除,9.5 共用体,几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构。类型定义 union 共用体名 成员列表;,例 union data char cval;int inal;float fval;,共用体类型变量的定义,(1)先定义共用体类型,后定义变量。例:union data a,b,c;(2)定义类型的同时定义变量。,例 union data char cval;int inal;float fval;a,b,c;,注:在字节对齐方式为一个字节的情况下,分配给共用体的存储空间大小为成员中所占字节数最大的一个,字节对齐方式设置同例9.1。,共用体变量的使用,共用体变量的使用方式和结构体相同,都是在定义了变量以后,用“变量名.成员名”的形式引用变量中的成员,而不能作为整体使用。例如:union data a,*p;printf(%c,%d,%f,a.cval,a.inal,a.fval);printf(%c,%d,%f,p-cval,p-inal,p-fval);,9.6 枚举类型,如果一个变量只有几种可能的值,则可以定义为枚举类型。所谓枚举是指将变量可能的取值一一列举出来,变量值只限于此范围内。只能取预先定义值的数据类型是枚举类型。类型定义 enum 枚举类型名枚举元素列表;例如:enum weekdaysun,mon,tue,wed,thu,fri,sat;,枚举变量定义,(1)定义枚举类型的同时定义变量:enum 枚举类型名枚举常量列表枚举变量列表;(2)先定义类型后定义变量:enum 枚举类型名 枚举变量列表;例如:enum weekdaysun,mon,tue,wed,thu,fri,sat;定义枚举类型enum weekday;enum weekday week1,week2;注:可以用枚举常量给枚举变量赋值,例如:week1=wed;week2=fri。,枚举变量的使用,#include main()enum seasonSpring,Summer,Autumn,Winter;enum season sea;for(sea=Spring;sea=Winter;sea+)switch(sea)case Spring:printf(Springn);break;case Summer:printf(Summern);break;case Autumn:printf(Autumnn);break;case Winter:printf(Wintern);break;,9.7 枚举类型,【例9.15】有以下程序#include#include string.h typedef structchar name9;char sex;float score2;STU;void f(STU a)STU b=Zhao,m,85.0,90.0;int i;strcpy(a.name,b.name);a.sex=b.sex;for(i=0;i2;i+)a.scorei=b.scorei;main()STU c=Qian,f,95.0,92.0;f(c);printf(%s,%c,%2.0f,%2.0fn,c.name,c.sex,c.score0,c.score1);,程序的运行结果是()。A.Qian,f,95,92 B.Qian,m,85,90 C.Zhao,f,95,92 D.Zhao,m,85,90 程序分析:此题目主要考查参数的传递问题,函数中形参的值改变不会影响实参,因此在函数调用f(c)中形参a的值不会改变实参c的值,答案为A。,9.7 枚举类型,【例9.16】以下程序中函数 fun 的功能是:统计 person 所指结构体数组中所有性别(sex)为 M的记录的个数,存入变量 n 中,并作为函数值返回。请填空。#include#define N 3 typedef struct int num;char nam10;char sex;SS;int fun(SS person)int i,n=0;for(i=0;iN;i+)if(=M)n+;return n;main()SS WN=1,AA,F,2,BB,M,3,CC,M;int n;n=fun(W);printf(n=%dn,n);,程序分析:此题目主要考查结构体中成员的引用,因为题目中要求统计性别为M的记录的个数,每次循环时都要判断结构体W中成员sex的值是否等于M,因此if语句判断的条件应该为personi.sex=M。,The end!,