资源预览内容
第1页 / 共37页
第2页 / 共37页
第3页 / 共37页
第4页 / 共37页
第5页 / 共37页
第6页 / 共37页
第7页 / 共37页
第8页 / 共37页
第9页 / 共37页
第10页 / 共37页
亲,该文档总共37页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第第8 8章章 结构体与共用体结构体与共用体概述概述在事务处理中在事务处理中,常需要将一些关系密切但类型不同的常需要将一些关系密切但类型不同的数据项组织在一起数据项组织在一起,并为其取一个整体名字,形成一并为其取一个整体名字,形成一个结构。个结构。C语言中语言中,就称其为就称其为结构体。结构体。结构体通常由不同数据类型的数据项结构体通常由不同数据类型的数据项(成员成员)组成组成一个结构体可包含若干成员一个结构体可包含若干成员,每个成员具有自己每个成员具有自己的名字及数据类型。的名字及数据类型。结构体类型的定义结构体类型的定义和简单类型不同,和简单类型不同,结构体类型是根据需要由程序员结构体类型是根据需要由程序员自行定义,自行定义,因此因此在使用之前必须先定义结构体类型在使用之前必须先定义结构体类型一般格式一般格式:struct结构体名结构体名结构体成员表结构体成员表;;struct是关键字,称为结构体定义标识符,而结构是关键字,称为结构体定义标识符,而结构体名则由程序员自己命名。大括号中的结构体成员体名则由程序员自己命名。大括号中的结构体成员表包含若干成员,每一个成员都具有如下的形式表包含若干成员,每一个成员都具有如下的形式:数据类型标识符数据类型标识符成员名;成员名;对一个学生的描述,其结构体类型定义如下:对一个学生的描述,其结构体类型定义如下:structstud_typecharname10;longnum;charsex;intage;floatscore5;charaddress10;说明说明:(1)定义定义一个结构体类型一个结构体类型只是描述了此结构体的组织形式,只是描述了此结构体的组织形式,在编译时在编译时并不为其分配存储空间并不为其分配存储空间,即仅描述此数据结构,即仅描述此数据结构的形态或者说模型,故的形态或者说模型,故不能对定义的一个结构体类型进不能对定义的一个结构体类型进行赋值、存取或运算。行赋值、存取或运算。(2)结构体的成员可以是简单变量、数组、指针、结构体等结构体的成员可以是简单变量、数组、指针、结构体等。(3)结构体类型结构体类型定义可以放在函数内部,也可以放在函数外部。定义可以放在函数内部,也可以放在函数外部。若若放在内部,则只在函数内有效放在内部,则只在函数内有效;若若放在外部,则从定义点到源文件尾之间的所有函数都有效。放在外部,则从定义点到源文件尾之间的所有函数都有效。(4)结构体成员的名字可以同程序中的其它变量同名结构体成员的名字可以同程序中的其它变量同名,二者不会相混,系统会自动识别它。二者不会相混,系统会自动识别它。结构体变量结构体变量结构体变量的定义结构体变量的定义(1)先定义类型再定义变量先定义类型再定义变量structstud_typecharname10;longnum;charsex;intage;floatscore5;structstud_typestudent1,student2;(2) (2) 在定义类型的同时定义变量在定义类型的同时定义变量structstud_typecharname10;longnum;charsex;intage;floatscore5;student1,student2;(3) (3) 直接定义结构体变量直接定义结构体变量structcharname10;longnum;charsex;intage;floatscore5;student1,student2; 说明说明:(1)在定义结构体类型时,系统并不分配内存空间,在定义结构体类型时,系统并不分配内存空间,仅仅当定义结构体变量时,系统才为被定义的每当定义结构体变量时,系统才为被定义的每一变量分配相应的存储单元。一变量分配相应的存储单元。(2)结构体变量的定义一定要在结构体类型定义之结构体变量的定义一定要在结构体类型定义之后或同时进行,后或同时进行,对尚未定义的结构体类型,不对尚未定义的结构体类型,不能用它来定义结构体变量。能用它来定义结构体变量。结构体变量的初始化结构体变量的初始化所谓结构体变量初始化,就是对其成员变量赋初值所谓结构体变量初始化,就是对其成员变量赋初值在赋值时应注意按顺序及类型依次为每个结构体成在赋值时应注意按顺序及类型依次为每个结构体成员指定初始值。员指定初始值。一般格式一般格式:struct结构体类型名结构体类型名结构体变量结构体变量=初始化值列表初始化值列表;说明说明:(1)初始化值列表中初始化数据之间初始化值列表中初始化数据之间用逗号分隔用逗号分隔。(2)初始化数据的个数初始化数据的个数一般与成员的个数相同一般与成员的个数相同,若若小于成员数,则剩余的成员将被自动初始化为小于成员数,则剩余的成员将被自动初始化为0。(3)初始化数据的类型要与相应成员变量的类型一致初始化数据的类型要与相应成员变量的类型一致。初始化时只能对整个结构体变量进行初始化时只能对整个结构体变量进行,不能仅对结,不能仅对结构体类型中的某些成员进行初始化赋值。构体类型中的某些成员进行初始化赋值。structdate_typeintyear;intmonth;intday;;structstud_typecharname10;longnum;charsex;structdate_typebirthday;floatscore;main()structstud_types1=wang,196103,m,1978,10,12,98;structstud_types2=liu,196105,m,1980,9,22,88;结构体变量的引用结构体变量的引用对结构体变量成员的引用对结构体变量成员的引用在在C语言程序中语言程序中,不允许对结构变量整体进行输入输出操不允许对结构变量整体进行输入输出操作和除赋值外的各种运算,只能是对其成员进行此类操作。作和除赋值外的各种运算,只能是对其成员进行此类操作。引用结构体变量成员的一般形式:引用结构体变量成员的一般形式:结构体变量名结构体变量名.成员名成员名其中其中“.”是结构体成员运算符是结构体成员运算符,其优先级别最高其优先级别最高,结合性是自左至右。结合性是自左至右。如如:对上例定义的结构体变量对上例定义的结构体变量s1,s2,可如下操作:可如下操作:scanf(%s,s1.name);scanf(%f,&s1.score);s1.birthday.year=1978;s1.birthday.month=10;s1.birthday.day=12;s2.birthday.year=s1.birthday.year+2;printf(%s=%f,s1.name,s1.score);【例【例8.18.1】 输入一个职工的工资信息,整体输入一个职工的工资信息,整体 赋值给另一个变量,在屏幕上输出。赋值给另一个变量,在屏幕上输出。 #include stdio.hstruct ym_type int y; int m;struct salary_type char num5; char name17; struct ym_type ym; float salary; float other; float cost;main() struct salary_type w,w0; printf(请输入姓名请输入姓名(其中可以包含空格其中可以包含空格):); gets(w0.name); printf(请输入工作证号、参加工作年、月、基本工资、其他工资、扣款请输入工作证号、参加工作年、月、基本工资、其他工资、扣款n); scanf(%s%d%d%f%f%f, w0.num,&w0.ym.y,&w0.ym.m,&w0.salary,&w0.other,&w0.cost); w=w0; printf(工号工号 姓名姓名 基本工资基本工资 其他工资其他工资 扣款扣款 实发工资实发工资n); printf(%-5s%-16s%8.2f%8.2f%8.2f%8.2fn,w.num, w.name,w.salary,w.other,w.cost,w.salary+w.other-w.cost); 结构体数组结构体数组结构体数组的定义结构体数组的定义structdate_typeintyear;intmonth;intday;;structstud_typecharname10;longnum;charsex;structdate_typebirthday;floatscore;charaddress10;s13;structstud_types25;结构体数组的初始化结构体数组的初始化stuctstud_types32=wang,196103,m,1978,10,12,98,xian,zhang,196102,f,1977,1,10,87,Beijing;【例【例8.2】用结构体数组存储学生信息,每个学生有姓名、用结构体数组存储学生信息,每个学生有姓名、 学号和成绩。从键盘按学号顺序输入学号和成绩。从键盘按学号顺序输入N名学生信息,名学生信息, 再按成绩从高到低的顺序输出各学生的全部信息。再按成绩从高到低的顺序输出各学生的全部信息。 #define N 4#include struct int num; char name11; int score;t,sN;main() int i,j,k; printf(n请输入第一个学生的学号:请输入第一个学生的学号:); scanf(%d,&k); printf(n请输入学号对应学生的姓名请输入学号对应学生的姓名(不可含空格不可含空格)、成绩、成绩n); for(i=0;iN;i+) printf(%d,si.num=k+i); scanf(%s%d,si.name,&si.score); for(i=0;iN-1;i+) k=i; for(j=i+1;jN;j+) if(sk.scoresj.score) k=j; if(k!=i) t=si;si=sk;sk=t; printf(按成绩排序输出:按成绩排序输出:n); for(i=0;iN;i+) printf(%d %-10s %5dn,si.num,si.name,si.score); 结构体和函数结构体和函数结构体成员可以作为函数的实参,而形参结构体成员可以作为函数的实参,而形参为与成员同类型的变量。此时传递的是单为与成员同类型的变量。此时传递的是单个成员值,与同类型的变量传递规则相同。个成员值,与同类型的变量传递规则相同。 【例【例8.3】 在在main() 函数中,输入一个学生信息,函数中,输入一个学生信息, 再调用再调用print函数输出。显然函数输出。显然print函数函数 的形参可以用结构体变量。的形参可以用结构体变量。 #include stdio.hstruct st_type char num7; char name21; char sex; int age; float score;void print(struct st_type s) printf(输出:学号输出:学号 姓名姓名 性别性别 年龄年龄 成绩成绩n); printf(%9s%20s%4c%6d%8.1fn, s.num,s.name,s.sex,s.age,s.score);main() struct st_type s0; printf(请输入姓名请输入姓名(可含空格可含空格):); gets(s0.name); printf(请输入学号、性别、年龄、成绩(各项用空格分开)请输入学号、性别、年龄、成绩(各项用空格分开)n); scanf(%s %c %d %f, s0.num,&s0.sex,&s0.age,&s0.score); print(s0);返回值为结构体类型的函数返回值为结构体类型的函数 定义返回值为结构体类型函数的一般形式为:定义返回值为结构体类型函数的一般形式为:结构体类型名结构体类型名 函数名函数名(形参表形参表)【例【例8.48.4】在在mainmain函数中定义一个结构体数组,函数中定义一个结构体数组, 多次调用多次调用inputinput函数输入各学生的信函数输入各学生的信 息,返回值赋给结构体数组元素,息,返回值赋给结构体数组元素, 再多次调用再多次调用printprint函数输出。函数输出。 #include stdio.hstruct st_type char num7;char name21;char sex;int age;float score;struct st_type input() struct st_type s0; printf(请输入姓名请输入姓名(其中可以包含空格其中可以包含空格):); gets(s0.name); printf(请输入学号、性别、年龄、成绩(各项用空格分开)请输入学号、性别、年龄、成绩(各项用空格分开)n); scanf(%s %c %d %f,s0.num,&s0.sex,&s0.age,&s0.score); getchar(); return s0;void print(struct st_type s0) printf(输出:学号输出:学号 姓名姓名 性别性别 年龄年龄 成绩成绩n); printf(%11s %16s %4c %6d %8.2fn, s0.num,s0.name,s0.sex,s0.age,s0.score);main() int i; struct st_type s2; for(i=0;i2;i+) si=input(); for(i=0;i2;i+) print(si); 在需要节省内存储空间时,在需要节省内存储空间时,C C语言还提供语言还提供了一种由了一种由若干个不同类型的数据项若干个不同类型的数据项组成,组成,但但共享同一存储空间共享同一存储空间的构造类型。的构造类型。共用体共用体由于共享的特性,只有由于共享的特性,只有最新最新存储的数据是有效存储的数据是有效的。的。一种一种构造构造类型数据,共用体由若干不同类型类型数据,共用体由若干不同类型的数据项组成,构成共用体的各个数据项称的数据项组成,构成共用体的各个数据项称为为共用体成员共用体成员。共用体共用体定义的一般形式定义的一般形式:union 共用体名共用体名 成员表列成员表列; 变量表列变量表列;共用体变量所占的内存长度等于共用体变量所占的内存长度等于最长最长的成员的长度的成员的长度共用体变量共用体变量只有只有先定义先定义了共用体类型,了共用体类型,才能才能定义基于该类型的变量定义基于该类型的变量不能直接引用共用体变量,不能直接引用共用体变量,只能引用共用体变量中的成员只能引用共用体变量中的成员共用体类型数据的特点共用体类型数据的特点1.同一同一个个内存内存段可以用来段可以用来存放几种不同类型的成员存放几种不同类型的成员, 但在但在每一瞬间只能存放其中一种每一瞬间只能存放其中一种,而不是同时都存放;,而不是同时都存放;2.共用体变量中共用体变量中起作用的成员是最后一次存放的成员起作用的成员是最后一次存放的成员, 在存入一个新的成员后原有的成员就失去作用;在存入一个新的成员后原有的成员就失去作用;3.共用体共用体变量的地址变量的地址和它的和它的成员的地址成员的地址都是都是同一同一地址;地址;4.共用体类型可以出现在结构体类型定义中。共用体类型可以出现在结构体类型定义中。共用体应用举例共用体应用举例 【例【例8.5】通过共用体变量,将一个整数的通过共用体变量,将一个整数的 两个字节分别按十六进制和字符方式输出。两个字节分别按十六进制和字符方式输出。 union int_char int i; char ch2;print(union int_char x) printf(i=%dni=%Xn,x.i,x.i); printf(ch0=%X,ch1=%X n ,x.ch0,x.ch1); printf(ch0=%c,ch1=%cn,x.ch0,x.ch1);main() union int_char x; x.i=25419; print(x);01100011 01001011低字节低字节高字节高字节0100101101100011ch0ch1 4B 63运行结果:运行结果:i=25419i=634B ch0=4B,ch1=63ch0=K,ch1=ci【例【例8.6】 一个班体育课成绩,男生测验一个班体育课成绩,男生测验15001500米成米成绩为绩为分分秒,女生测验柔韧性(分秒,女生测验柔韧性(分A A、B B、C C、D D和和E E 5 5等)和俯卧撑次数,将测验数据放在一张表中,表等)和俯卧撑次数,将测验数据放在一张表中,表中包括学号、姓名、性别和体育成绩。最后一项中包括学号、姓名、性别和体育成绩。最后一项“体体育成绩育成绩”的内容根据性别填写不同的内容,编写程序,的内容根据性别填写不同的内容,编写程序,若输入、输出表中的信息。若输入、输出表中的信息。#define N 2#include struct boy int m; float s;struct girl char f; int n; struct student char num7; char name10; char sex; union struct boy ms; struct girl fn; score; stN; main() int n,i; for(i=0;iN;i+) printf(请输入:学号、姓名、性别请输入:学号、姓名、性别n); scanf(%s%s%c,sti.num,sti.name,&sti.sex); if(sti.sex=m | sti.sex=M) printf(请输入他的请输入他的15001500米成绩米成绩( (分秒分秒) ):); scanf(%d,%f,&sti.score.ms.m,&sti.score.ms.s); else printf(请输入她的柔韧性等级和俯卧撑次数请输入她的柔韧性等级和俯卧撑次数:); scanf(%c,%d,&sti.score.fn.f,&sti.score.fn.n); for(i=0;iN;i+) if(sti.sex=m | sti.sex=M) printf(%-8s %-10s 男男15001500米成绩:米成绩:% %d d分分 %4.1 %4.1f f秒秒n, sti.num,sti.name,sti.score.ms.m,sti.score.ms.s); else printf(“%-8s %-10s 女女 柔韧性:柔韧性:% %c c等俯卧撑:等俯卧撑:% %d d次次 n, sti.num,sti.name,sti.score.fn.f,sti.score.fn.n);结构体与共用体的比较结构体与共用体的比较定义形式相似,但是它们的含义不同。定义形式相似,但是它们的含义不同。结构体是将多个不同类型的数据结构体是将多个不同类型的数据组合成一个整体组合成一个整体进行存储与管理。进行存储与管理。共用体则是使多个不同类型的数据使用共用体则是使多个不同类型的数据使用同一存储空间同一存储空间进行存储。进行存储。存储空间的分配方式不同存储空间的分配方式不同结构体变量所占内存长度是各个成员占的结构体变量所占内存长度是各个成员占的内存长度之和内存长度之和, 其每个成员均有自己的存储空间。其每个成员均有自己的存储空间。共用体变量所占的内存长度等于共用体变量所占的内存长度等于最长的成员的长度最长的成员的长度,任何时候,共用体变量只能存放一个成员。任何时候,共用体变量只能存放一个成员。枚枚 举举 类类 型型 枚举类型定义枚举类型定义 一般形式:一般形式:enum 类型标识符类型标识符 枚举值名表枚举值名表 ;花括号中的枚举值形式如下:花括号中的枚举值形式如下:常量标识符常量标识符1,常量标识符,常量标识符2,常量标识符,常量标识符n 例如:例如:enum weekdaysun,mon,tue,wed,thu,fri,sat; 枚举类型的变量枚举类型的变量 enum weekday d1, d2; /* /* 定义枚举变量定义枚举变量d1d1和和d2 */d2 */ 注意:一个枚举变量的值只能取该类型定义的几个枚举常量注意:一个枚举变量的值只能取该类型定义的几个枚举常量d1=sun; d2=d1; 若想将整数值赋给枚举变量,须作强制类型转换。若想将整数值赋给枚举变量,须作强制类型转换。 d1=(enum weekday)2; 相当于相当于d1=d1=tuetue; ; 【例【例8.7】输入一整数,转换为枚举类型,并存输入一整数,转换为枚举类型,并存 入枚举类型的变量,再显示与之对应的星期值。入枚举类型的变量,再显示与之对应的星期值。#include stdio.hmain() enum weeksun=7,mon=1,tue,wed,thu,fri,sta; enum week weekday; int i; printf(input integer:n); scanf(%d,&i); weekday=(enum week)i; switch(weekday) case sun: printf(Sundayn); break; case mon: printf(Mondayn); break; case tue: printf(Tuesdayn); break; case wed: printf(Wednesdayn); break; case thu: printf(Thursdayn); break; case fri: printf(Fridayn); break; case sta: printf(Saturdayn); break; default : printf(Input error!n); break; 用用typedef定义类型定义类型可以用可以用typedef声明新的类型名来声明新的类型名来代替代替已有的类型名已有的类型名typedef int INTEGER;typedef float REAL;int i,j;float a,b;INTEGER i,j;REAL a,b; typedef structint month; int day; int year; DATE;DATE birthday;作作 业业P155.8.1,8.2,8.10
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号