《CC++语言程序设计案例教程》课件-第6章结构体_第1页
《CC++语言程序设计案例教程》课件-第6章结构体_第2页
《CC++语言程序设计案例教程》课件-第6章结构体_第3页
《CC++语言程序设计案例教程》课件-第6章结构体_第4页
《CC++语言程序设计案例教程》课件-第6章结构体_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1第6章结构体和共用体C

语言程序设计案例教程2024/12/232第6章结构体与共用体6.1结构体类型和结构体变量6.2结构体变量的引用6.3结构体数组6.4指向结构体类型数据的指针6.5结构体与函数6.6自学共用体枚举类型要求掌握结构体类型的变量和引用方法,以及结构体数组。(6.1---6.3)重点掌握结构体类型数据的指针(6.4)了解公用体、枚举类型的定义及基本概念(6.6----6.8)学习内容

学习目标

2024/12/233一个学生的信息有学号、姓名、性别、年龄、住址、成绩等。一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等。如何描述这些类型不同的相关数据?6.1结构体结构体的引入?结构体——一种构造类型数据

结构体由若干不同类型的数据项组成,构成结构体的各个数据项称为结构体成员。在实际应用中,有时需要将不同类型的数据组合成一个有机的整体。如果将这些项分别定义为独立的基本类型变量,很难反映它们之间存在的内在联系。希望能将其有机结合为一个整体,使其易于使用和操作,既能极大提高这类数据的处理效率更能真实的反映客观世界。2024/12/234案例一完成学生基本信息的保存并输出1.问题描述完成学生基本信息的保存并输出(姓名、性别、学号、成绩、本学期综合排名等级)。2.问题分析使用结构体类型变量保存学生基本信息,注意结构体和嵌套结构体定义、赋值、输出的方式。2024/12/2353. C语言代码#include<stdio.h>structcredit /*定义结构体类型credit*/{floatscore; /*score为结构体credit成员,表示学生成绩*/chargrade;};structstudent /*定义结构体类型student*/{char*sname; /*sname为结构体student成员(指针类型)*/charssex;intsnum;structcredituser; /*user是结构体类型credit的变量,在结构体类型student定义中嵌入另一 个结构体类型credit变量为结构体类型student成员*/}stu1={"zhangxiao",'M',18091009,89.8,'B'},stu2;/*stu1、stu2是结构体类型student的变量*/main(){structcredituser; /*user是另一结构体类型credit的变量*/

stu2.sname="sunjierui";stu2.ssex='M';stu2.snum=18091019;printf("请输入stu2的学期排名等级和成绩\n");scanf("%c%f",&stu2.user.grade,&stu2.user.score);printf("stu2.sname=%s,stu2.ssex=%c,stu2.snum=%d\n",stu2.sname,stu2.ssex,stu2.snum);printf("stu2.user.score=%f,stu2.user.grade=%c\n",stu2.user.score,stu2.user.grade);}2024/12/2364.程序运行结果请输入stu2的学期排名等级和成绩C78stu2.sname=sunjierui,stu2.ssex=M,stu2.snum=18091019stu2.user.score=78.000000,stu2.user.grade=C2024/12/2376.1结构体类型与结构体变量结构体是C语言的构造类型。如案例一中,structcredit和structstudent都是结构体类型。结构体成员是有逻辑联系的变量。案例一中成员变量charssex、intsnum、structcredituser的取值都与成员变量char*sname有关,于是把这些成员封装在一起形成一个独立的类型——结构体类型。结构体成员在内存中占据连续的存储单元。把具有内在联系的数据有机的结合为一个整体有易于使用和操作,可提高这类数据的处理效率,更真实的反映客观世界。2024/12/2386.1.1结构体类型与结构体变量的定义

“结构体”是自定义的构造类型,可根据需要构造结构体中成员。由于不是系统定义的标准类型,结构体类型要先定义,再定义结构体变量。1.结构体类型定义结构体类型的一般形式为:struct结构体名{

数据类型成员变量1;数据类型成员变量2;

...

数据类型成员变量n;};结构体中的成员变量可以是基本数据类型,也可以是指针类型,或结构体类型等。2024/12/2392.结构体变量的定义结构体类型变量的定义与其他类型的变量的定义方法是一样的。因为结构体类型是根据具体问题先自行定义的,这样便给结构体类型变量的定义形式增加了灵活性。结构体变量定义共有三种形式:(1)先定义结构体类型,再定义结构体类型变量。定义格式如下:struct结构体名{

成员变量项表列};struct结构体类型名结构体变量名;例如:

structstudent /*定义结构体类型student*/{char*sname; /*结构体student类型的成员*/charssex;intsnum;structcredituser; /*user是另一结构体类型credit的变量,对成员的使用是在结构体变量的基础上*/};structstudentstu1,stu2;/*结构体变量定义*/2024/12/2310(2)定义结构体类型同时定义结构体类型变量。定义格式如下:struct结构体类型名{

成员变量项表列}结构体变量名;例如:structstudent{char*sname;charssex;intsnum;structcredituser;}stu1,stu2; /*结构体变量定义*/2024/12/2311说明:①这两种结构体类型变量定义方法可以很方便的在定义之后的任意位置说明该结构体类型变量。②结构体类型的声明可以在函数内,也可以在函数外,分别属于局部和全局结构体类型。全局的结构体类型可以定义局部和全局的结构体变量,局部的结构体类型只可以定义局部的结构体变量。(3)直接定义结构体类型变量。定义格式如下:struct{

成员项表列}结构体变量名;例如:struct /*定义无名结构体*/{char*sname;charssex;intsnum;structcredituser;}stu1,stu2;/*结构体变量定义*/说明:该定义方法由于无法记录该结构体类型,所以不能在主函数中再定义新的结构的变量(无结构体名),而其他定义方式可以在main()函数中再定义新的结构体类型变量。注意:编译系统不为结构体类型分配空间,只对结构体变量分配空间,结构体变量的存储空间大小是每个成员变量存储空间之和。2024/12/23126.1.2结构体变量的使用

如果要对结构体成员进行操作,首先要通过对结构体变量的使用。1.结构体变量的引用对结构体变量的操作,实质是对成员的操作,结构体变量对成员引用的一般形式为结构体变量.成员名例如,在案例一中通过、stu2.snum引用形式完成对、stu2.snum操作,如赋值、计算和输出。如果有一个结构成员属于另一个结构体类型时,例如在structstudent结构体类型中成员user是另一结构体类型structcredit的变量,这时引用方式是stu2.user.grade,由外向里一级一级找到最低一级。2024/12/23132.结构体变量的赋值结构变量与其他变量相同,可以在定义它的同时进行初始化,用一对大括号包围的初值表对该结构变量的每个成员变量赋初值,初值表按成员项排列的先后顺序一一对应赋值。每个初值数据类型必须与其对应的成员变量数据相符合。例如:structstudent /*定义全局结构体类型student*/{char*sname; /**sname、ssex等都是结构体student成员*/charssex;intsnum;structcredituser;/*user是另一结构体类型credit的变量*/}stu1={"zhangxiao",'M',18091009,89.8,'B'};/*定义全局结构体变量stu1,并初始化*/#include"stdio.h"main(){structstudentstu2={"sunli",'w',18991019,78,'C'};/*定义局部结构体变量stu2,并初始化*/...}注意:①不能对结构体整体赋值和整体输出;scanf("%s%c%d%f%c",stu2);或printf("%s%c%d%f%c",stu2);②不同结构体类型的结构体变量不能互相赋值。stu2=stu3;这两个结构体变量的结构体类型必须相同才可以整体赋值。2024/12/2314案例二结构体数组的使用1.问题描述根据学号查找对应学生的姓名和成绩。2.问题分析建立结构体数组,数组成员保存学生基本信息(姓名、性别、学号、成绩)。2024/12/23153.C语言代码#include<stdio.h>structstudent{char*sname;charssex;intsnum;floatscore[2];}stu[]={{"ZhaoLei",'M',18091210,{89,76.8}},{"LiLie",'M',18091201,{76.3,89.4}},{"SunZhongJie",'W',18091226,{89.5,90.4}}};/*结构体数组初始化,保存各学生信息*/main(){unsignedlongintstu_len=sizeof(stu)/sizeof(stu[0]);/*计算数组长度*/inti,num,j;printf("请输入学生学号:");scanf("%d",&num);for(i=0;i<stu_len;i++)if(num==stu[i].snum)break;printf("thename=%s,ssex=%c\n",stu[i].sname,stu[i].ssex);for(j=0;j<2;j++)printf("成绩%d是%.4f\n",j+1,stu[i].score[j]);printf("\n");}2024/12/23164.程序运行结果请输入学生学号:18091210thename=ZhaoLie,ssex=M成绩1是89.0000成绩2是76.80002024/12/23176.2结构体数组

在实际中,可能要处理多个结构体变量,这时可以使用结构体数组。结构体数组结合了“结构体”与“数组”的特点,既可以体现结构体成员的特点,又可以对数组成员进行批量处理。2024/12/23186.2.1结构体数组定义

结构体数组的定义与结构体变量的定义基本相同,也有三种形式。例如:采用结构体变量定义的第一种形式的定义格式如下:structstudent /*定义结构体类型student*/{char*sname; /*结构体类型student成员*/charssex;intsnum;structcredituser; /*user是另一结构体类型credit的变量*/};structstudentstu[4];2024/12/23196.2.2结构体数组的使用

结构体数组的使用与之前的数组使用的方法基本相同。(1)结构体数组的引用与初始化。结构体数组引用格式为结构体数组名[下标].成员名例如:采用结构体变量定义形式2定义结构体数组,并完成初始化。structstudent /*定义结构体类型student*/{char*sname; /*结构体类型student成员*/charssex;intsnum;floatscore;}stu[4]; /*定义stu为含有4个元素的全局结构体数组*/可以使用stu[0].ssex、stu[3].score引用方式。2024/12/2320(2)结构体类型数组初始化与结构体类型变量形式相同,只不过数组每个元素是结构体类型成员。说明:(1)如案例二所示,结构体数组初始化时所有数组元素要用最外层花括号括起来。为了表述清晰,一般会把每个数组元素也用花括号括起来。(2)系统开辟连续空间存放结构体数组中的元素。结构体数组名是结构体数组的首地址。(3)可以在定义结构体类型之后直接定义结构体数组并初始化。(4)可以先定义结构体数组,在程序运行过程中完成赋值。2024/12/2321例6.1完成学生信息的录入(姓名、性别、学号)。#include<stdio.h>#include<string.h>structstudent{charsname[20];charssex;intsnum;}stu[3]; /*定义stu为含有3个元素的全局结构体数组*/main(){inti,j;printf("inputthe3students'ssname,ssex,sunm\n");for(i=0;i<3;i++) /*通过循环完成对结构体数组中元素赋值*/{printf("thesname:");fflush(stdin);gets(stu[i].sname);fflush(stdin); /*避免将输入sname之后的回车键作为字符赋值给字符类型的ssex*/printf("thessexandsnum:");

scanf("%c%d",&stu[i].ssex,&stu[i].snum);printf("\n");}}2024/12/2322程序运行结果如下:inputthe3stuents'ssname,ssex,sunmthesname:ZhangJiathessexandsnum:M18010112thesname:SunJieChaothessexandsnum:W18010223thesname:ZhaoHanthessexandsnum:W180103212024/12/2323案例三指向结构体类型数组指针的使用1.问题描述查找学生成绩最低的学生信息。2.问题分析使用结构体数组保存学生信息,使用指向结构体类型数组的指针及相关算法查找出学生信息中成绩最低学生的信息。2024/12/23243. C语言代码#include<stdio.h>#include<string.h>structstudent{intsnum;charsname[20];floatscore;chargrade;}stud[]={{18091210,"ZHaolei",90.3,'A'},{18091220,"SunxiaoYang",85,'B'},{18091230,"Wanle",76.5,'C'}},*pstu1;/*利用结构体数组初始化保存3个学生信息,同时建立指针变量*/main(){unsignedlongintstu_len=sizeof(stud)/sizeof(stud[0]);/*计算数组长度*/inti;floatmin;pstu1=stud; /*指针变量pstu1获得数组首地址*/pstu1=pstu1+stu_len; /*指针变量pstu1指向第4个结构体数组元素地址,增加一个 新数组元素*/pstu1->snum=18191121; /*指针变量pstu1对结构体中的成员的赋值(数组第4个元素)*/

strcpy((*pstu1).sname,"LihanYang");

pstu1->score=67.5;

pstu1->grade='D';pstu1=stud; /*指针变量pstu1重新获得数组首地址*/min=pstu1->score; /*指针pstu1对成员的引用,将数组第一个元素中的score

假设为最低成绩*/

for(i=1;i<(stu_len+1);i++)

{++(pstu1); /*指针变量pstu1增1*/if(pstu1->score<min) /*指针变量pstu1所指score的值小于假设的score*/min=pstu1->score; /*指针变量pstu1所指score的值赋值给min*/}printf("Theninformationofthestudentis:\n");printf("snum=%d,sname=%s,minscore=%f,grade=%c\n",pstu1->snum,pstu1->sname,pstu1->

score,pstu1->grade);}2024/12/23254.程序运行结果Theninformationofthestudentis:snum=18191121,sname=LihanYang,minscore=67.500000,grade=D2024/12/23266.3结构体与指针

指针可以指向变量和数组,指针同样可以指向结构体变量和结构体数组。2024/12/23276.3.1指向结构体变量的指针

结构体变量首字节地址即为结构体变量指针,可以使用指针访问结构体变量中的成员。1.结构体变量指针定义格式与赋值结构体指针变量定义格式如下:struct结构体类型名*结构体指针变量名结构体指针变量定义后,系统仅为指针变量分配存储结构体类型的起始地址。指针变量赋值后,结构体指针变量才能对结构体成员进行操作。结构体指针变量赋值方式一:先定义结构体变量,再定义结构体指针变量。2024/12/2328例如:structstudentstu1structstudent*pu=&stu1或structstudentstu1,*pstu;pstu=&stu1结构体指针变量赋值方式二:如果没有定义结构体变量,可以使用分配内存函数malloc()按以下方式对结构体指针变量赋值。例如:structstudent*pstu=(structstudent*)malloc(sizeof(structstudent));说明:(1)不可以使用结构体类型名对结构体指针变量赋值,例如:pstu=&student。(2)可以把成员定义为本结构体相同的结构体指针变量。2024/12/2329例如:structstudent{intsnum;structstudent*point;}结构体含有一个指向自己的结构体指针变量,这种结构体在链表、树和有向图中广泛应用。2024/12/23302.结构体指针变量对成员的引用结构体指针变量对成员的引用形式有两种。(*结构体指针变量).成员名或结构体指针变量->成员名2024/12/2331例6.2使用结构体指针变量输出学生信息中的姓名、成绩和成绩等级。#include<string.h>#include<stdio.h>structstudent{charsname[10];intsnum;floatscore;chargrade;}stu1={"ZhaoLei",18091223,92.5,'A'},*pstu1;main(){pstu1=&stu1;strcpy((*pstu1).sname,"LiJie");/*为结构体变量重新赋值*/(*pstu1).score=82;pstu1->grade='B';printf("snameis%s\n",&(*pstu1).sname);

printf("scoreis%f\n",pstu1->score);printf("gradeis%c\n",(*pstu1).grade);}2024/12/2332程序运行结果如下:snameisLiJiescoreis82.000000gradeisB2024/12/23336.3.2指向结构体类型数组的指针

以基本数据类型建立的数组的首地址是指针,可以使用指针变量对数组中的基本数据类型元素进行赋值和操作。同样指针类型也可以运用于结构体数组,即指向结构体类型数组的指针。1.指向结构体数组指针定义与赋值定义指向结构体数组指针变量和之前定义数组的指针的方法是一样的。例如,案例三中在定义结构体数组的同时定义指向结构体数组的指针,通过pstu1=stud使得指针变量获得数组首地址。2.结构体数组指针引用结构体成员与之前数组成员的引用方式相同,结构体数组指针对结构体数组成员的引用方式有地址法、指针法、指针的数组表示法。例如,案例三中通过指针法pstu1->score方式完成对成员的数据操作。2024/12/2334指向结构体类型数组的指针的使用与指向基本数据类型的指针使用相同,pstu1++ 和++pstu1可以使pstu1指向结构体数组的下一个元素地址。使用指向结构体数组的指针,请注意以下表达式的含义:(1)因为“->”运算符优先级最高,所以pstu1->snum,pstu1->snum++,++pstu1->snum三个表达式都是对成员变量snum的操作。(2) (++pstu1)->snum,先使pstu1加1,指向下一个数组元素地址,然后得到该元素的snum成员的值。(3) pstu1++->snum,先得到pstu1所指的snum的值,然后使pstu1加1,指向该数组下一个元素地址。2024/12/2335案例四结构体函数的使用1.问题描述根据学生成绩,判断学生成绩的等级。(例如成绩score,当90≤score≤100时等级为A,80≤score<90时等级为B)。2.问题分析学生成绩设定为结构体变量或结构体数组,通过函数使学生成绩对应转换成等级。2024/12/23363. C语言代码#include"stdio.h"#include"string.h"structstudent{intnum;charname[15];floatscore;chargrade;}stu={18091221,"ZhangMing",75.5},/*结构体变量,其中成员grade未赋值*/stu1[]={{18091213,"LiJian",80},{18091223,"SunQiang",68},{18091231,"ZhaoShaSha",95.5}}; /*结构体数组,其中成员grade未赋值*//*函数Dengji对结构体变量stu中成员grade赋值*/Dengji(structstudent*s) /*形参s为指向结构体变量的指针,程序运行后s的值为具有相同结构体变量实参的地址*/{if(s->score>=60&&s->score<70)s->grade='D';/*地址传递,在形参s->grade赋值后,对应实参stu.grade有相同的值*/if(s->score>=70&&s->score<80)s->grade='C';if(s->score>=80&&s->score<90)s->grade='B';if(s->score>=90&&s->score<=100)s->grade='A';}2024/12/2337voidmain(){inti;printf("结构体变量stu原始数据为\n");printf("num=%d,name=%s,score=%f,grade=%c\n",stu.num,,stu.score,stu.grade);Dengji(&stu);/*调用函数Dengji完成结构体变量stu中grade赋值,使用地址传递*/printf("结构体变量stu成员成绩等级赋值后数据为\n");printf("num=%d,name=%s,score=%f,grade=%c\n",stu.num,,stu.score,stu.grade);printf("\n");printf("结构体数组stu1[]原始数据为\n");for(i=0;i<3;i++)printf("num=%d,name=%s,score=%f,grade=%c\n",stu1[i].num,stu1[i].name,stu1[i].score,stu1[i].grade);printf("\n");printf("结构体数组stu1[]元素中成员成绩等级赋值后数组数据为\n");for(i=0;i<3;i++)Dengji(&stu1[i]);/*调用函数Dengji完成结构体数组每个元素中grade赋值,使用地址传递*/for(i=0;i<3;i++)printf("num=%d,name=%s,score=%f,grade=%c\n",stu1[i].num,stu1[i].name,stu1[i].score,stu1[i].grade);}2024/12/23384.程序运行结果结构体变量stu原始数据为num=18091221,name=ZhangMing,score=75.500000,grade=结构体变量stu成员成绩等级赋值后数据为num=18091221,name=ZhangMing,score=75.50000,grade=C结构体数组stu1[]原始数据为num=18091213,name=LiJian,score=80.000000,grade=num=18091223,name=SunQiang,score=68.000000,grade=num=18091231,name=ZhaoShaSha,score=95.500000,grade=结构体数组stu1[]元素中成员成绩等级赋值后数组数据为num=18091213,name=LiJian,score=80.000000,grade=Bnum=18091223,name=SunQiang,score=68.000000,grade=Dnum=18091231,name=ZhaoShaSha,score=95.500000,grade=A2024/12/23396.4结构体与函数

结构体类型数据也可以作为函数的参数用于程序的设计,参数为结构体的函数称为结构体函数,使用结构体作为函数参数,可以提高数据传输效率。结构体类型的变量或者结构体类型的数组传递给函数有以下三种方式:(1)结构体成员作为参数。这与普通变量作为参数一样,是值传递;(2)结构体变量作为函数参数。要求形参和实参是同一种结构体类型变量,传递时采用的也是值传递的方式。这种调用方式首先形参要分配存储空间,其次实参将各成员的值依次赋值给形参的对应成员。如果成员比较多,在时间和空间上都增加了系统开销;(3)结构体变量的地址或结构体数组名为参数。形参接受实参地址,这种情况属于地址传递。例如,案例四中函数Dengji中参数采用的就是结构体变量地址为参数,是地址传递。2024/12/23406.4.1指向结构体变量的指针作为函数参数

函数参数传递方式有数值传递和地址传递,数值传递形参的改变不会影响到实参。如果想在调用函数中改变主调函数中的实参,可以用结构体变量的地址(或数组成员地址)作为实参,用指向相同结构体类型的结构体指针作为函数的形参来传递地址值,以地址传递的方式改变实参的数据值。例如,案例四中结构体变量stu在初始化时成员grade未赋值(实际值为0,输出时为空字符),通过传地址方式的函数调用在函数中完成了grade赋值,在主函数中输出grade变量的值;案例四中结构体数组stu1[]元素中的成员通过地址传递的方式,完成了数组元素中成员变量grade的赋值。2024/12/23416.4.2结构体变量作为函数的返回值

结构体变量可以作为函数的返回值,返回值为结构体类型的函数称为结构体函数。结构体变量作为函数的返回值的定义格式:struct结构体名函数名(struct结构体名参数)形参、实参数、和函数均采用相同结构体类型。例6.3完成学生基本信息的录入,并根据学生的学号输出学生的信息。#include<stdio.h>#defineN3structstudent{intnum;charname[15];floatscore;}stu[N];/*函数search完成对应学号的学生信息查询并返回学生信息,形参变量p和函数具有相同的结构体类型,形参m是学号*/structstudent*search(structstudent*p,intm){structstudent*s=NULL;for(;p<(stu+N);p++)if(p->num==m){s=p;break;}returns;/*返回查询到的地址,否则为NULL*/}/*函数完成学生信息的输入,参数p获得数组s1[]地址,参数n获得数据元素个数N*/voidinput(structstudent*p,intn){inti;printf("NumNameScore\n");for(i=0;i<n;i++){scanf("%d",&p[i].num);scanf("%s",p[i].name);

scanf("%f",&p[i].score);}}2024/12/2342/*函数完成学生信息的输出,参数s1[]为数组地址*/voidoutput(structstudents1){printf("NumNameScore\n");printf("%d,%s,%f\n",s1.num,,s1.score);}main(){intn;structstudent*s1=stu;input(s1,N);/*函数调用:完成学生信息输入,参数数组名s1(地址传递),数组元素个数N(值传递)传递给函数input*/printf("请输入查找学生的学号:\n");scanf("%d",&n);s1=search(s1,n);/*函数调用:完成学生信息查询,参数数组名s1(地址传递),参数n学号(数值传递)*/if(s1!=NULL)output(*s1);/*函数调用:完成学生信息输出,参数*s1(值传递)*/elseprintf("未查找到该学生");}2024/12/2343程序运行结果如下:NumNameScore18090212LiLu8718090109ZhaoJie7518090328SunJiaJun92请输入查找学生的学号:1809032818090328SunJiaJun92.0000002024/12/2344案例五共用体变量设计与使用1.问题描述描述若干教师的业绩,每个教师包括编号、姓名、职称、业绩;若职称是讲师,则业绩描述为其讲述的课程门数;若职称为教授,业绩描述为科研项目的金额。2.问题分析教师数据中的编号、姓名、职称是三个固定字段,分别用整型、字符数组、字符数组来存储,业绩可能是讲述的课程门数或科研项目的金额,二选一,用共用体类型描述。观察共用体变量定义、赋值方法。2024/12/23453. C语言代码/*本程序实现不同职称教师的业绩管理*/#include<stdio.h>#include<string.h>#defineTnum3 /*教师的数量*/unionyeji/*教师业绩共用体定义*/{intkechengnum; /*讲述课程门数*/floatkeyanjine; /*科研项目金额*/};structteacher /*教师结构体定义*/{intTid; /*教师编号*/charTname[20]; /*教师姓名*/charTrank[20]; /*教师职称*/unionyejiachievement; /*教师业绩,为共用体类型变量*/}Teacher[Tnum]; /*存储教师信息数组,为全局的结构体类型的数组*/2024/12/2346voidmain(){inti; /*i循环控制变量*/printf("请输入教师信息:\n");for(i=0;i<Tnum;i++) /*循环输入教师信息*/{/*循环输入教师固定字段信息*/scanf("%d%s%s",&Teacher[i].Tid,Teacher[i].Tname,Teacher[i].Trank); if(strcmp(Teacher[i].Trank,"jiangshi")==0) /*是讲师则输入课程数量*/scanf("%d",&Teacher[i].achievement.kechengnum);elseif(strcmp(Teacher[i].Trank,"jiaoshou")==0) /*是教授则输入项目金额*/scanf("%f",&Teacher[i].achievement.keyanjine);else /*职称输入错误的提示信息*/printf("dataerror!\n");}printf("编号\t姓名\t职称\t\t讲授课程或项目金额\n");for(i=0;i<Tnum;i++) /*循环输出教师信息*/{printf("%d\t%s\t%s\t",Teacher[i].Tid,Teacher[i].Tname,Teacher[i].Trank);if(strcmp(Teacher[i].Trank,"jiangshi")==0)printf("%d\n",Teacher[i].achievement.kechengnum);elseif(strcmp(Teacher[i].Trank,"jiaoshou")==0)printf("%f\n",Teacher[i].achievement.keyanjine);

else

printf("dataerror!\n");}}2024/12/23474.程序运行结果请输入教师信息:1000wangjiangshi51001lijiaoshou9.81002zhaojiaoshou10.85编号姓名职称讲授课程或项目金额1000wangjiangshi51001lijiaoshou9.8000001002zhaojiaoshou10.8500002024/12/23486.5共用体

共用体是一种与结构体类似的构造类型,可以包括数目固定、类型不同的若干数据,所有成员共享一段公共存储空间(如案例五中类型unionyeji)。所谓共享不是指把多个成员同时装入一个共用体变量内,而是指该共用体变量可被赋予任一成员值,但每次只能给其中的一个变量赋值,新赋的值会覆盖原有变量。也就是某一时刻共用体的成员变量只能有一个有正确的值。共用体类型变量所占内存空间不是各个成员所需存储空间字节数的总和,而是共用体成员中存储空间最大的成员所要求的字节数。共用体用途:使几个不同类型的变量共占一段内存(相互覆盖)。2024/12/23496.5.1共用体类型的定义

与结构体类型的定义类似,定义一个共用体类型的一般形式为union共用体名{数据类型成员名1;数据类型成员名2;...数据类型成员名n;};成员列表中含有若干成员,成员名的命名应符合标识符的规定,彼此之间不能相同。例如:uniondata{inti;charch[10];};定义了一个名为uniondata的共用体类型,它包含有两个成员,一个为整型,成员名为i;另一个为字符数组,数组名为ch。共用体定义之后,即可进行共用体变量说明。被说明为uniondata类型的变量,可以存放整型量i或存放字符数组ch,这两种数据类型的成员共享同一块内存空间。共用体变量任何时刻只有一个成员存在。2024/12/23506.5.2共用体变量的定义

共用体变量的说明和结构体变量的定义类似,也有三种形式。(1)定义共用体类型的同时定义共用体类型变量:uniondata{shortinti;

charch;floatf;}a,b;(2)先定义共用体类型,再定义共用体类型变量:uniondata{shortinti;charch;floatf;};uniondataa,b,c,*p,d[3];(3)直接定义共用体类型变量:union图6.1共用体变量的存储{shortinti;charch;

floatf;}a,b,c;2024/12/2351在内存分配时,a、b、c变量的长度等于uniondata成员中最长的长度,即等于实数f的长度,共4个字节。a、b、c变量如果赋予字符型ch值时,只使用了1个字节,而赋予f时,可用4个字节。a在内存中的存储情况如图6.1所示。2024/12/2352图6.1共用体变量的存储2024/12/23536.5.3共用体变量的引用

引用共用体变量的成员方式与结构体非常类似,方式有下面几种:(1)在定义了共用体变量之后,可以使用“.”运算符来引用它的成员。例如:a.i=5;(2)可以把共用体变量的地址赋值给同类型的指针变量,可以利用指向共用体变量的指针来引用它的成员。例如:uniondata{shortinti;charch;floatf;}a,b,c,*p,d[3];p=&a;(*p).i=9;等价于p->i=9;。2024/12/2354(3)共用体变量也可以初始化,但只是对它的成员表中的第一个成员进行初始化,不能对它所有列出的成员都赋初值。例如:uniondata{shortinti;charch;floatf;}a={8};将它的第一个成员i初始化成了8。2024/12/2355注意:①由于共用体变量的各个成员占用同一段内存空间,因此它们的起始地址都是相同的。所以,&a.i、&a.ch、&a.f与&a的值都是相同的,不过,这些地址的类型是不同的。②在任意一个时刻分配给共用体变量的内存空间中,最多只能保留共用体变量的一个成员的值。当为共用体变量的某个成员赋值时,该值将覆盖掉该共用体变量中在此之前保存的其他成员的值。因此在某个时刻联合变量存储空间中将保留最后一个被赋值的成员的值。2024/12/2356例6.4输出共用体变量成员的值。#include"stdio.h"uniondata /*定义一个共用体类型data*/{shortintstud;charteach[2];};main(){uniondataun1;

un1.stud=2;un1.teach[0]=23;un1.teach[1]=0;printf("%hd\n",un1.stud);}2024/12/2357程序运行结果如下:23共用体变量un1中的成员stud和数组成员teach都是从内存空间的同一个位置开始存储,因为短整型stud与数组teach的前两个元素共用一个2个字节的存储单元,所以数组前2个元素的值覆盖了最初给成员stud的值。共用体的类型可以出现在结构体类型的定义中,结构体也可以作为共用体的成员出现。共用体类型变量不能作为函数参数或者函数的返回值,但是可以使用指向共用体类型变量的指针来传递数据。2024/12/23586.6枚举类型如果一个变量只有几种可能的值,可以定义为枚举类型。1.什么是枚举所谓“枚举”,是指将变量的值一一列举出来,变量的值在列举出来的值的范围内。枚举数据是一个被命名为整型常数的集合,这些常数指定了所有已被定义的各种合法值。枚举在日常生活中十分常见,如一周分为7天:sun,mon,tue,wed,thu,fri,sat可按如下格式定义为枚举类型:enumday{sun,mon,tue,wed,thu,fri,sat};关键字enum表示定义一个枚举类型。2024/12/23592.枚举类型的定义和枚举变量的定义先定义枚举类型,再定义枚举变量。枚举类型定义的一般形式为enum枚举类型名{枚举表};其中,enum是定义枚举类型的关键字;“枚举表”由多个用户自定义的标识符组成,标识符之间用逗号分开。枚举变量定义的一般形式为enum枚举类型名枚举变量表;例如:定义一个称之为day的枚举类型,并说明today是属于该类型的一个变量:enumday{sun,mon,tue,wed,thu,fri,sat};/*枚举类型的定义*/enumdaytoday;/*和枚举变量的定义*/枚举变量的定义也有和结构体共用体类似的三种形式,这里不再一一列举。2024/12/2360说明:(1)花括号中的内容称为枚举表,每个枚举表项是整型常数,系统默认规定其值依次为0,1,2,3,4,5,6。在定义枚举类型时也可对枚举表项进行初始化以改变它们的值。例如:enumday{sun=1,mon,tue=5,wed,thu,fri,sat=11};则sun=1,mon=2,tue=5,wed=6,thu=7,fri=8,sat=11,如果某个枚举元素没有初始化,会自动取前一个枚举元素值加1,第一个枚举元素自动取0。(2)枚举元素都是常量,即枚举常量,而不是变量,因此不能为枚举元素赋值,如sun=5,mon=8是错误的。枚举元素可用于给枚举变量赋值,而枚举变量不能接收一个非枚举常量的赋值。例如:today=sun;(正确)today=3;(错误)(3)可以将一个整数经强制类型转换后赋给枚举变量。例如:enumday{sun,mon,tue,wed,thu,fri,sat}today;today=(enumday)3;相当于today=wed;2024/12/23613.定义枚举类型的好处(1)用标识符表示数值增加了程序的可读性(直观)。例如,if(today==sat)nextday=sun;就比较清晰,if(today==6)nextday=7;就不如前者清晰。(2)可限制了变量的取值范围。在上面的例子中,today只能取sun~sat中的值,不能随便取值。2024/12/2362例6.5顺序输出5种颜色名。#include"stdio.h"main(){

enumcolor{red,yellow,blue,white,black};

enumcolorc;

for(c=red;c<=black;c++)

switch(c)

{

case

red:

printf(″red″);

break;

case

yellow:

printf(″yellow″);

break;

case

blue:

printf(″blue″);

break;

case

white:

printf(″whi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论