ImageVerifierCode 换一换
格式:PPT , 页数:247 ,大小:1.05MB ,
文档编号:7252961      下载积分:22 文币
快捷下载
登录下载
邮箱/手机:
温馨提示:
系统将以此处填写的邮箱或者手机号生成账号和密码,方便再次下载。 如填写123,账号和密码都是123。
支付方式: 支付宝    微信支付   
验证码:   换一换

优惠套餐
 

温馨提示:若手机下载失败,请复制以下地址【https://www.163wenku.com/d-7252961.html】到电脑浏览器->登陆(账号密码均为手机号或邮箱;不要扫码登陆)->重新下载(不再收费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录  
下载须知

1: 试题类文档的标题没说有答案,则无答案;主观题也可能无答案。PPT的音视频可能无法播放。 请谨慎下单,一旦售出,概不退换。
2: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
3: 本文为用户(ziliao2023)主动上传,所有收益归该用户。163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

1,本文(程序设计与C语言(第二版)章-课件8.ppt)为本站会员(ziliao2023)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!

程序设计与C语言(第二版)章-课件8.ppt

1、第8章 结构体、共用体及枚举类型 第第8章结构体、共用体及枚举类型章结构体、共用体及枚举类型8.1 结构体类型结构体类型 8.2 动态数据结构动态数据结构 8.3 共用体共用体 8.4 位段位段 8.5 枚举类型枚举类型 习题习题8 第8章 结构体、共用体及枚举类型 8.1 结结 构构 体体 类类 型型8.1.1 结构体变量的定义及初始化结构体变量的定义及初始化1.结构体类型的定义结构体类型的定义要定义结构体变量,首先要定义结构体类型。结构体类型定义的一般形式是:struct结构名 成员表;;成员表=分量1;分量2;分量=类型标识符分量名第8章 结构体、共用体及枚举类型 其中,符号“=”表示“

2、定义为”,方括号中的内容是可选的。例如语句 struct date int year;int monthint day;第8章 结构体、共用体及枚举类型 就定义了一个表示日期的结构体类型,类型名为struct date。它的三个分量的类型均为整型。对结构体来说,分量的类型可以互不相同,这是它与数组的区别。数组也是构造类型,但它要求各元素具有相同的类型。再如 struct student unsigned num;charname10;intage;loatscore;定义了一个学生的结构体类型,名字为struct student,它有4个分量,类型各不相同。第8章 结构体、共用体及枚举类型 结

3、构体类型可以嵌套定义,即结构体的分量类型是另一个结构体类型。以下两种情况都可以定义嵌套的结构体类型:(1)两个结构体类型的定义是分离的,后者可以把前者作为其分量类型。比如上面已经定义了日期类型,则可以用它来定义学生类型:struct student unsigned num;charname10;intage;floatscore;struct date birthday;第8章 结构体、共用体及枚举类型(2)还可以在一个结构体内部直接嵌套定义:struct student unsigned num;charname10;intage;floatscore;struct int year;in

4、t month;int day;birthday;第8章 结构体、共用体及枚举类型 注意:注意:结构体类型不能递归定义,即分量的类型不能是正在定义的结构体类型。如:struct wrong int i;struct wrong w;;这样的定义是错误的。定义结构体类型时,常犯的错误是忽略了最后的分号。第8章 结构体、共用体及枚举类型 2.结构体变量的定义结构体变量的定义在定义了类型名之后,就可以定义该类型的变量了。定义结构体变量的方法有三种:(1)如结构体类型已定义好,则可以用来定义变量。如:struct date date1,date2;struct student stu1,stu2;注意

5、:注意:在使用结构体类型名时,初学者往往会忽略保留字struct,其实struct date和struct student都是一个统一的整体,二者缺一不可。第8章 结构体、共用体及枚举类型(2)定义结构类型的同时直接定义变量,如 struct date int year;int month;int day;date1,date2;第8章 结构体、共用体及枚举类型(3)定义结构体类型的同时定义变量,但没有结构名。第(2)和(3)种的差别在于:第(2)种方法既定义了类型名又定义了变量,以后需要时还可以继续定义新的变量,而第(3)种就不能再定义新的变量了,因为它没有结构名。第8章 结构体、共用体及枚

6、举类型 3.结构体变量赋初值结构体变量赋初值结构体变量可以在定义时赋初值,如语句struct student stu1,stu2=63001,zhang,18,642.5;就对结构体变量stu2进行了初始化,实际上是用右边的值对stu2各分量进行初始化,因此提供的初值必须和相应分量的类型一致。两个相同类型的结构体变量之间可以进行赋值操作。如:stu1=stu2;则使stu1的各分量具有了和stu2各分量一样的值。第8章 结构体、共用体及枚举类型 4.结构体指针变量的定义结构体指针变量的定义除了定义结构体变量之外,还可定义结构体指针变量。如:struct student stu1,*p;定义了结

7、构体类型指针p。像其他类型的指针一样,结构体指针只有和某个结构体变量发生了联系,即得到了结构体变量的首地址之后才能被使用。如:p=&stu1;就把stu1的首地址,即第一个分量的地址赋给了p,p于是指向这个结构体变量,如下图所示。这之后对stu1和对*p的操作效果都是一样的。stu1pnumnameage score第8章 结构体、共用体及枚举类型 5.结构体变量的内存分配结构体变量的内存分配结构体变量由各分量组成。各分量分配内存的次序和规则与普通变量有所不同。如:struct student char name7;int age;char sex;float score;stu,*p=&st

8、u;则其内存分配情况如图8-1所示。第8章 结构体、共用体及枚举类型 图8-1 结构体变量各分量的内存分配情况第8章 结构体、共用体及枚举类型 从图8-1中可以看出:(1)结构体变量中各分量内存分配的情况是:按照各分量出现的先后次序,先出现的分量在上面,地址小;后出现的分量在下面,地址大。(2)数组分量中,下标小的元素在上面,地址小;下标大的元素在下面,地址大。(3)各分量之间的关系依系统的不同而有所不同。对Turbo C来说,各分量之间没有空洞,即不要求各分量按整字边界存放,它们之间是紧凑的。因此,当用sizeof运算符求结构体变量的大小时,其值等于各分量实际字节数之和,此处有:sizeof

9、(stu)=14。第8章 结构体、共用体及枚举类型 而对Visual C+而言,要求各分量按整字边界存放,这样在各分量之间就有可能存在空洞,因此在用sizeof运算符求结构体变量的大小时,必须将这些空洞计算进来,此处有:sizeof(stu)=20。由此可知,在求结构体变量的大小时,必须首先明确是在什么系统中进行的。第8章 结构体、共用体及枚举类型 8.1.2 结构体数组及结构体分量的引用结构体数组及结构体分量的引用1.结构体数组结构体数组一个结构体变量可以处理一个对象,如果有多个对象,则需要多个结构体变量,这时应该用结构体数组来处理多个同类型的对象。例如,定义一个产品类型的数组prod:st

10、ruct product unsigned long no;charname15;intnum;floatprice;prod3;定义结构体变量的其他两种方法也可以用来定义结构体数组。第8章 结构体、共用体及枚举类型 对结构体数组可以初始化,例如 struct product prod3=112346,football,56,284.5,112347,basketball,108,256,112348,valleyball,35,96.4;其逻辑结构如图8-2所示。第8章 结构体、共用体及枚举类型 图 8-2 结构体数组的逻辑结构 第8章 结构体、共用体及枚举类型 这个结构像是二维数组,但它不

11、是真正的数组,它没有行地址和列地址之说,因此对它用指针进行操作时也就没有所谓行指针和列指针的问题,只有一种指向结构体的指针。例如,若定义结构体指针变量p:struct product*p;则经过赋值运算“p=prod;”之后,就使p指向了prod数组的第1个元素prod0。p+后指向prod,即沿垂直方向向下走一步,指向下一个结构体,而不能说指向下一行。并且它也只能沿着垂直方向前进,而不能沿水平方向前进。至于水平方向的引用则涉及到对结构体分量引用的问题。第8章 结构体、共用体及枚举类型 2.对结构体分量的引用对结构体分量的引用对结构体分量的引用有三种方法:用点运算符引用;用指向运算符引用;对数

12、组元素的分量用下标加点或指向运算符引用。下面分别加以说明。(1)用点运算符引用结构体变量的分量的方法,有两种引用形式:结构体变量名.分量名(*结构体指针).分量名即在结构体变量和其分量名之间加一个点运算符。例如:struct product prod,*p=∏则prod.num=35;/*等价于(*p).num=35;*/strcpy(prod.name,football);就是对结构体变量prod的分量进行赋值的运算。这时prod.num(或(*p).num)、prod.name作为一个独立的变量使用,可以直接进行输入/输出操作。第8章 结构体、共用体及枚举类型【例例 8-1】对结

13、构体分量的引用。include struct product unsigned long no;charname15;int num;floatprice;第8章 结构体、共用体及枚举类型 main()struct product prod;prod.no=117364;prod.num=46;prod.price=287.5scanf(%s,prod.name);printf(%lu,%s,%d,%fn,prod.no,prod.name,prod.num,prod.price);return 0;第8章 结构体、共用体及枚举类型 运行输出:football 117364,football,

14、46,287.5注意:注意:因为name分量是字符数组,所以不能用赋值语句直接赋值,只能用字符串处理函数strcpy或用scanf函数的控制符“%s”控制输入。第8章 结构体、共用体及枚举类型(2)用指向运算符引用结构体指针所指对象的分量的方法,是用结构体指针处理结构体的常用形式,其引用形式为:结构体指针变量-分量名指向运算符由两个字符“-”和“”组成,它是一个整体,中间没有空格。例如:p-no=117368;strcpy(p-name,basketball);第8章 结构体、共用体及枚举类型【例例 8-2】用指针重做例8-1。include struct product unsigned l

15、ong no;charname15;intnum;floatprice;第8章 结构体、共用体及枚举类型 main()struct product prod,*p;p=∏scanf(%lu%s%d%f,&p-no,p-name,&p-num,&p-price);printf(%lu,%s,%d,%fn,p-no,p-name,p-num,p-price);return 0;运行输出:117364 valleyball 75 197.6 117364 valleyball 75 197.6输入时应注意,数字和后面的字符串之间可以不留空格,编译器会自动识别数字的终结,但字符串和后面的数字

16、之间必须有空格,否则编译器会把数字也当作字符看待。第8章 结构体、共用体及枚举类型(3)用下标加点运算符引用结构体数组元素的分量的方法,其引用形式为:数组名下标.分量名注意:注意:下标和数组名紧密相连,不可分离,不能把下标放在分量名后面。例如:struct product prod;则prod2.price=78.5;是正确的引用,而prod.price则是错误的写法。第8章 结构体、共用体及枚举类型【例例 8-3】建立和输出有3个元素的产品结构体数组,并输出价格最高的产品的所有信息。include struct product unsigned long no;charname15;intn

17、um;floatprice;struct int year,month,day;outdate;prod;第8章 结构体、共用体及枚举类型 main()int i,j;float max=0;struct product*p=prod;puts(Input prod3:n);for(i=0;i=2;i+)scanf(%lu%s%d%f%d%d%d,&prodi.nu,prodi.name,&prodi.num,&prodi.price,&prodi.outdate.year,&prodi.outdate.month,&prodi.outdate.day);printf(The prod arr

18、ay is:n);第8章 结构体、共用体及枚举类型 for(i=0;ino,p-name,p-num,p-price,p-outdate.year,p-outdate.month,p-outdate.day);p+;printf(n);第8章 结构体、共用体及枚举类型 for(i=0;imax)max=prodi.price;j=i;printf(Element having highest price:n);printf(%lu,%s,%d,%.2f,%d,%d,%dn,prodj.no,prodj.name,prodj.num,prodj.price,prodi.outdate.year,

19、prodj.outdate.month,prodj,outdate.day);return 0;第8章 结构体、共用体及枚举类型 运行输出:Input prod3:11111 aaaaa 89 99.2 2001 11 9 22222 bbbbb 76 100.4 2002 1 8 33333 ccccc 96 187 2002 8 4 The prod3 array is:11111 aaaaa 89 99.20 2001/11/9 22222 bbbbb 76 100.40 2002/1/8 33333 ccccc 96 187.00 2002/8/4 Element having hig

20、hest price:33333 ccccc 96 187.00 2002/8/4第8章 结构体、共用体及枚举类型 本例中prod是一个嵌套的结构体类型数组,其中出厂日期分量outdate是一个结构体类型。在对嵌套的结构体分量进行引用时,必须连续使用点运算符,以达到分量的最底层,这时才可以对各分量进行输入/输出操作。比如第i个元素的出厂年份的表示为:prodi.outdate.year,这个序列是个整体,相当于一个整型变量,可以对它进行读/写。第8章 结构体、共用体及枚举类型(4)用指向运算符也可以引用结构体数组元素的分量,因为对结构体数组可以用指针进行处理。例如有定义:struct prod

21、uct prod3,*p;令p=prod,则p指向数组prod的第1个元素,p+指向下一个元素,每个元素又是结构体,仍要用“-”运算符求其分量,如图8-3所示。用指针来引用结构体分量时,要注意“-”运算符的优先级最高,它把前后两部分连成一个不可分割的整体,因此,p-num+等价于(p-num)+,即先取出p所指结构体的num分量的当前值,然后对它加1;+p-num等价于+(p-num),即对num分量加1;(+p)-num是先把p移向数组的下一个元素,再求该元素的num分量;(p+)-num 是先把p所指结构的num分量取出,再把p向下移一个元素。为了加深对结构体指针和结构体数组的理解,我们可

22、以分析下面的程序。第8章 结构体、共用体及枚举类型 图 8-3 结构体数组的指针处理 第8章 结构体、共用体及枚举类型【例例 8-4】分析下面程序的输出结果。include struct sinl char*s;int i;struct sinl*slp;第8章 结构体、共用体及枚举类型 main()static struct sinl a=abcd,1,a+1,efgh,2,a+2,ijkl,3,a;struct sinl*p=a;int i;printf(a0.s=%st p-s=%sta2.slp-s=%snn,a0.s,p-s,a2.slp-s);第8章 结构体、共用体及枚举类型 fo

23、r(i=0;is)=%sta(+p)-i.s=%st a-(p-slp-i).s=%sn,+(p-s),a(+p)-i.s,a-(p-slp-i).s);return 0;第8章 结构体、共用体及枚举类型 运行输出:a.s=abcd p-s=abcd a2.slp-s=abcd -a0.i=0+a0.s3=e -a1.i=1+a.s3=i +(p-s)=fgia(+p)-i.s=abce a-(p-slp-i).s=abce程序中定义了一个结构体数组a并初始化。从初始化的数据看有三个结构体。图8-4画出了这三个结构体中指针的指向。第8章 结构体、共用体及枚举类型 图8-4 结构体中指针的指向第

24、8章 结构体、共用体及枚举类型 在定义的结构体中,分量slp是指向自身结构的指针,这种结构称为自引用结构。slp又称为“链接”,它能够把一个struct sinl结构体与另一个同样的结构体链接在一起。因为slp是指针,所以这不是递归定义。结构体中有一个分量的名字为i,而在主函数中,i又被定义成一个新的整型变量,两者是否会冲突?答案是不会,因为它们所处的地方不同,作用也不同。由图8-3可知,a的s分量是指向字符串的指针;p-s为p所指对象的s分量,即a0的s分量,是一个指针;a2.slp-s为a的slp分量所指对象的s分量,也即a 的s分量。这三种表示是等价的,因而输出也相同,为“abcd”。第

25、8章 结构体、共用体及枚举类型 因为-ai.i等价于-(ai.i),即以ai的i分量的值减1作为输出结果,所以-a0.i=0,-a1.i=1,于是a0.i=0,ai.i=1。因为+ai.s3=+(ai.s3),s是指向字符串中第一个字符的指针,s+3为指向该串第3+1个字符的指针,又因为s3=*(s+3),即s3为该串第3+1个字符,所以+ai.s3表示ai的s分量指向的字符串中的第3+1个字符加1(即其后继字符),所以+a0.s3=e,+a1.s3=i,于是a0.s指向“abce”,a1.s指向“efgi”。在下面的输出中,以Turbo C对函数参数由右向左进行求值的顺序,先计算并输出a-(

26、p-slp-i).s,然后是a(+p)-i.s,最后是+(p-s),且左边的求值受右边求值的影响。第8章 结构体、共用体及枚举类型 求a-(p-slp-i).s:这时p指向a0,p-slp-i,即a1.i,它的值已变为1,再对它进行自减运算得a1.i=0,于是a0.s指向“abce”。求a(+p)-i.s:因p指向a0,则+p使p指向a1,而a1的i分量的值已变为0,则a(+p)-i.s仍是求a0.s所指字符串,即“abce”。求+(p-s):因此时p已指向a1,p-s即为a1的s分量,它指向字符串“efgi”的第1个字符e,则+(p-s)指向“efgi”的第2个字符f,故输出为“fgi”。注

27、意:注意:在循环语句中,ai.i中的两个i代表不同的对象,方括号中的i是循环控制变量,代表数组元素的下标,而小数点后面的i则是结构体的分量名。第8章 结构体、共用体及枚举类型 3.二维结构体数组二维结构体数组二维结构体数组和其他类型的二维数组一样,由行和列组成,只不过它的每个元素是一个结构体,每个结构体又有自己的分量,因此,在对二维结构体数组赋初值和进行存取的过程中,必须考虑到行、列及分量等特点。设有定义 struct cid char ch;int i;double x;a33;则结构体类型cid有三个分量,二维数组a有3行,每行有3列,共有9个元素,即有9个结构体。它的组织形式如图8-5所

28、示。第8章 结构体、共用体及枚举类型 图8-5 二维结构体数组第8章 结构体、共用体及枚举类型 在对二维数组赋初值时,为了清晰起见,应适当地使用括号,以便于把每行、每个元素都清楚地表示出来。例如:struct cid a33=a,1,1.1,b,2,2.2,c,3,3.3,d,4,4.4,e,5,5.5,f,6,6.6,g,7,7.7,h,8,8.8,i,9,9.9,在赋初值时应注意,每行之间、每列之间及结构体的分量之间都不能留有空洞,或简单地讲,不能连续地出现两个逗号,即在两个逗号之间必须有具体内容。但在每对括号内部,后面的部分可以省略,该处的变量自动具有初值:字符型数据的初值为空字符,数值

29、型数据的初值为零。第8章 结构体、共用体及枚举类型 要引用二维数组中元素的分量,必须在数组名的后面带两个下标,后跟点运算符加分量名。比如要引用上述定义中的字符f,则其表示为a12.ch,对其中元素2.2的引用是a01.x。若数组名只带一个下标,如a1,则它表示第2行第1个元素的地址,此时对f的引用应表示成(*(a1+2).ch。注意:点运算符的优先级高于间接引用运算符*,所以必须把*(a1+2)用括号括起来。第8章 结构体、共用体及枚举类型【例例8-5】设有I个班,每班有J名学生,每个学生有N个成绩,请输入学生的姓名和4科成绩,并计算每个学生的平均分,所有学生全部成绩的平均分、最高分和最低分。

30、编程思路:编程思路:一个学生的信息用一个结构体描述,所有班、所有学生可用二维数组加以组织,因此这是一个二维结构体数组,可用上面叙述的方法加以处理。第8章 结构体、共用体及枚举类型 程序如下:include define I 2define J 3define N 4struct student char name10;float scoreN;float ave;aIJ;第8章 结构体、共用体及枚举类型 main()int i,j,n;float max,min,average,sum,sumi;max=average=sum=0;min=100;for(i=0;iI;i+)for(j=0;j

31、J;j+)sumi=0;printf(Input a name:);scanf(%s,&aij.name);printf(Input%d scores:,N):第8章 结构体、共用体及枚举类型 for(n=0;nmax)max=aij.scoren;if(aij.scorenmin)min=aij.scoren;sum+=aij.scoren;sumi+=aij.scoren;aij.ave=sumi/N;第8章 结构体、共用体及枚举类型 for(i=0;iI;i+)printf(nnclass%d:n,i+1);printf(Name score1 score2 score3 score4

32、averagen);for(j=0;jJ;j+)printf(%-5s ,(*(ai+j).name);第8章 结构体、共用体及枚举类型 for(n=0;nN;n+)printf(%.1f ,(*(ai+j).scoren);printf(%.1fn,(*(ai+j).ave);average=sum/(I*J*N);printf(nmax=%.1fnmin=%.1fntotal average=%.1fnn,max,min,average);return 0;第8章 结构体、共用体及枚举类型 运行输出:Input a name:zhaoInput 4 scores:88 89 87 68In

33、put a name:qianInput 4 scores:78 89 97 86Input a name:sunInput 4 scores:89 97 86 59Input a name:liInput 4 scores:89 97 96 68Input a name:zhouInput 4 scores:87 76 69 89Input a name:wuInput 4 scores:85 83 96 91第8章 结构体、共用体及枚举类型 class 1:Name score1 score2 score3 score4 averagezhao88.089.087.068.083.0qia

34、n78.089.097.086.087.5sun89.097.086.059.082.8class 2:Name score1 score2 score3 score4 averageli89.097.096.068.087.5zhou87.076.069.089.080.3wu85.083.096.091.088.8max=97.0min=59.0total average=85.0第8章 结构体、共用体及枚举类型 8.1.3 结构体变量和结构体指针作参数结构体变量和结构体指针作参数结构体变量和结构体指针都可以作为函数的参数及函数的返回值。若形参和实参均为结构体变量,则参数传递的是结构体的拷

35、贝,属于函数的传值调用。但这样做既费时间又费空间。如果把形参定义成指针类型,就可以解决这两方面的问题。这时实参传递的是结构体变量的地址,函数中对形参的处理就是对实参的直接处理。下面的例子说明了这种情况。第8章 结构体、共用体及枚举类型【例例 8-6】求两个复数的和与积。编程思路:编程思路:复数相加的公式为:(a+bi)+(c+di)=(a+c)+(b+d)i即两个复数相加结果仍为一复数,结果的实部为两个复数的实部之和,结果的虚部为两个复数的虚部之和。复数相乘的公式为:(a+bi)*(c+di)=(ac-bd)+(bc+ad)i复数可以设计成一个结构体类型。复数相加与相乘用两个函数表示。复数结构

36、体类型在各个函数中都要使用,因此把它放到所有函数之外,作为全局类型定义。第8章 结构体、共用体及枚举类型 include struct complex float re,im;struct complex*cadd(struct complex*,struct complex*,struct complex*);struct complex cmul(struct complex,struct complex);main()struct complex a,b,c,d,*pa=&a,*pb=&b;*pc=&c;printf(Input a.re=?,a.im=?n);scanf(%f%f,&a

37、.re,&a.im);printf(Input b.re=?,b.im=?n);scanf(%f%f,&b.re,&b.im);pc=cadd(pa,&b,&c);d=cmul(a,b);printf(sum of 2 complex number:n);第8章 结构体、共用体及枚举类型 printf(c.re=%.1f,c.im=%.1fn,c.re,(*pc).im);printf(nn multiple of 2 complex number:n);printf(d.re=%.1f,d.im=%.1fn,d.re,d.im);return 0;struct complex*cadd(st

38、ruct complex*x,struct complex*y,struct complex*t)(*t).re=(*x).re+(*y).re;(*t).im=(*x).im+(*y).im;return t;第8章 结构体、共用体及枚举类型 struct complex cmul(struct complex x,struct complex y)struct complex c;c.re=x.re*y.re-x.im*y.im;c.im=x.im*y.re+x.re*y.im;return c;第8章 结构体、共用体及枚举类型 运行输出:Input a.re=?a.im=?2 3 Inp

39、ut b.re=?b.im=?3 4 sum of 2 complex number:c.re=5.0,c.im=7.0 multiple of 2 complex number:d.re=-6.0,d.im=17.0第8章 结构体、共用体及枚举类型 对于cmul函数,两个参数都是结构体类型,实参也是两个结构体变量,返回值也是结构体类型。函数cadd有3个参数,全是结构体指针,实参有结构体指针,也有结构体变量的地址,它们都是等价形式。函数以一个形参t作为返回值,调用时把结构体变量c的地址赋给形参t,则在函数中对t的处理也就是对实参c的处理。函数返回的t也被指向c的指针pc所接收。第8章 结构体

40、、共用体及枚举类型 讨论:讨论:根据cadd函数的处理情况,能否去掉形参t,而把它作为函数体内定义的指针变量呢?这是不允许的,因为作为临时指针变量,在它和具体的结构体建立联系之前,它的指向是随机的,对它指向的内存空间的赋值有可能引起破坏性的后果。但是可以对cadd函数作如下变形:void cadd(struct complex*x,struct complex*y,struct complex*t)(*t).re=(*x).re+(*y).re;(*t).im=(*x).im+(*y).im;即函数中可以不要返回语句,因为对形参t的处理也是对实参的处理,所以这里可以用函数语句的形式对函数cad

41、d进行调用。cadd(pa,pb,pc);第8章 结构体、共用体及枚举类型 思考:思考:cadd函数能作如下定义吗?struct complex*cadd(struct complex*x,struct complex*y)struct complex t,*p=&t;t.re=(*x).re+(*y).re;t.im=(*x).im+(*y).im;return p;注意:注意:函数中定义的变量都是内部变量或临时变量,它们只在函数内部起作用,一旦到了函数外部就失去了作用,临时为它开辟的内存也被收回。第8章 结构体、共用体及枚举类型【例例8-7】日期倒计时。计算今天距北京2008年奥运会开幕还

42、剩多少天。编程思路:编程思路:日期由年、月、日组成,可用结构体表示。倒计时的计算由三部分组成:当年所余天数+下一年距开幕前一年的天数+开幕当年的天数。(1)当年所余天数=当月所余天数+下个月至年底的天数。当月所余天数=当月总天数-当天号数;下月至年底天数=各个月份的天数累加。(2)下一年距开幕前一年的天数=各年天数累加。累加时闰年为366天,非闰年为365天。第8章 结构体、共用体及枚举类型(3)开幕当年的天数=开幕那月前数月的天数+开幕那天的号数。设北京奥运会开幕时间为2008年8月8日,可用宏定义表示具体数值,若改为其他日期,只需修改宏值即可。对当前日期的输入,可以用一个函数实现,函数的参

43、数为一个指向结构体的指针,函数调用时的实参为主调函数中定义的指针,在使用以前它已指向了一个结构体变量。所以函数中对形参指针的操作,也就是对结构体变量的操作。第8章 结构体、共用体及枚举类型 程序如下:include include define YEAR 2008define MON 8define DAY 8int days212=31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31;struct date int da_year;int da_mon;int da_day;第8章 结构体、共用体及枚举

44、类型 main()int i,l,sum=0;int leap(int);void getdate(struct date*);struct date today;struct date*p1=&today;getdate(p1);printf(today:%d.%d.%dn,p1-da_year,p1-da_mon,p1-da_day);第8章 结构体、共用体及枚举类型 for(i=p1-da_year+1;i=YEAR-1;i+)if(leap(i)sum+=366;else sum+=365;l=leap(YEAR);for(i=0;ida_mon-1-p1-da_day;第8章 结构体

45、、共用体及枚举类型 for(i=p1-da_mon;ida_year)i;printf(nTo Beijing Olympic,i1 rest%d days!nn,sum);return 0;int leap(int m)if(m%4=0&m%100!=0|m%400=0)return 1;elsereturn 0;第8章 结构体、共用体及枚举类型 void getdate(struct date*p)printf(Input current year:n);scanf(%d,&p-da_year);printf(Input current month:n);scanf(%d,&p-da_mo

46、n);printf(Input current day:n);scanf(%d,&p-da_day);第8章 结构体、共用体及枚举类型 运行输出:Input current year:2006 Input current month:7 Input current day:20 today:2006.7.20To Beijing Olympic,il rest 750 days!第8章 结构体、共用体及枚举类型 8.1.4 类型名定义类型名定义typedef在上面的例子中,我们定义了一个复数类型struct complex,这是个不能分开的整体,利用这个类型名可以定义变量、函数的返回值等。但这

47、个类型名很长,稍不留心就会出错。如果程序中有很多的复数类型的变量和函数需要定义,书写起来更是不胜其烦。能不能简单一些呢?答案是肯定的。C语言提供了一种机制,利用保留字typedef就可以用一个简单的名字来代替像struct complex这样的长序列。例如:typedef struct complex COMPLEX;则COMPLEX即是和struct complex等价的类型名,可以用它定义变量:COMPLEX a,b,c,*pa;这样用起来就方便多了。第8章 结构体、共用体及枚举类型 用typedef说明类型名的一般形式如下:typedef 原类型名新类型名新类型名一般用大写表示,以便与原

48、名在性质上区别开来,即它不是新创造的类型,而是原类型的代名词或化身,它代表了原类型。原类型名可以是构造类型,也可以是标准类型,如:typedef float REAL;就为标准类型float起了个新名REAL。以后在程序中,原名和别名可以同时使用。如有语句REAL f1,f2;就定义了两个浮点型的变量f1和f2。第8章 结构体、共用体及枚举类型 说明新类型的方法十分简单,可按下列步骤进行:(1)先定义原类型的变量。(2)把变量名大写,以示它为新类型名。(3)在前面加上typedef保留字。例如:struct student stu;struct student STU;typedef stru

49、ct student STU;于是STU即成为struct student的新名字,可用来定义变量了,如STU stud1,stud2;第8章 结构体、共用体及枚举类型 注意:注意:在用新类型名定义变量时,新类型说明中的附加部分不能写上,如typedef int ARRAY10;则新类型名为ARRAY,它代表有10个整型元素的数组,可以用它来这样定义数组:ARRAY a,b;而不能写成:ARRAY10 a,b;第8章 结构体、共用体及枚举类型 说明:说明:用typedef说明新类型名的目的是为了简化书写,便于阅读,这对简化结构体类型名尤为有用,应该学会使用。但不要把简单的问题复杂化,比如要定义

50、有10个整型元素的数组,完全可以写成:int a10,b10,c10;这样的定义相当直观明了,大可不必先去定义个ARRAY,再用ARRAY来定义有10个元素的数组,那样做既麻烦又违背了简化程序的初衷。用typedef定义的新类型名不一定要大写,小写也可以,大写是为了突出新类型名。第8章 结构体、共用体及枚举类型 8.2 动态数据结构动态数据结构到目前为止我们所使用的数据结构如数组等,其大小是一开始就定义好的,在程序中不能改动,这对内存的合理使用及某些操作非常不便。而动态数据结构是一开始并不指定大小,可以随需要不断增加,不用时随时取消的结构,如链表、堆栈、队列、树等,这些动态结构在信息科学中非常

侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|