已阅读5页,还剩41页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第十一章 结构体,结构体 结构体与函数 本章小结 作业,考虑这样一类数据:一个数据项由多个子数据项组成,而且每个子数据项的类型可能不一样。 在人事档案管理中,每个人的自然情况表可能包含: 名字(字符串型) 年龄(整型) 出生时间(三个整型) 性别(枚举)等等。 研究人造卫星,每个人造卫星的信息可能包括: 名字(字符型) 发射时间(三个整数) 重量(实型) 直径(实型) 轨道半径(实型) 赤道夹角(实型)等等。,数组可描述由同类型子数据项组成的数据。 结构体可描述由不同类型子数据项组成的数据,结构体,结构体类型 结构体类型是分量的集合 分量也称成员、成分、域,例11-1 一个人的自然情况表 卫星数据类型,enum sext male , female ; struct date int year ,month ,day ; ; struct preson char name10 ; int age ; enum sext sex ; struct date birthdate ; ;,struct mansatellite char name10 ; struct date lounchdate ; float weight, diameter, orbitrad, angle ; ;,date是一个结构体类型,包含三个成分 成分year为int类型 成分month为int类型 成分day为int类型,preson是一个结构体类型,包含四个成分 成分name为数组类型 成分age为int类型 成分sex为枚举类型 成分birthdate仍为一个结构体类型,mansatellite是一个结构体类型,包含六个成分,结构体类型引用 在struct后跟以结构体标签,称为“结构体类型引用”。在例11-1的结构体类型定义的意义下: struct date struct preson struct mansatellite 都是结构体类型引用,使用它们将分别标记相应结构体定义。,结构体类型说明符: 结构体类型定义和结构体类型引用统称“结构体类型说明符” 使用结构体类型说明符可以 定义结构体类型的类型名 声明结构体类型变量,结构体类型名,使用 typedef 可以定义结构体 类型名 typedef 结构体类型说明符 标识符 例子 typedef struct int y,m,d datetype; struct date int y,m,d ; typedef struct date datetype;,例11-2 定义结构体类型名,typedef struct date int year,month,day ; datetype ; typedef char tstring1010; typedef struct tstring10 name ; int age ; enum sext sex ; struct date birthdate ; presontype ; typedef struct mansatellite mansatellitetype,datetype birthdate;,结构体变量,结构体类型变量声明可以采取如下三种形式之一 使用结构体类型引用 直接使用结构体类型定义 使用typedef定义的结构体类型名,例11-3 结构体变量声明,struct preson zhang ; struct date int year,month,day ; dateofbirth; struct char author10 ; datetype publish_date ; int page_number ; programming ; mansatellitetype first_east ;,变量zhang用结构体类型引用声明 是struct preson类型,具有如图结构,例11-3 结构体变量声明,struct preson zhang ; struct date int year,month,day ; dateofbirth; struct char author10 ; datetype publish_date ; int page_number ; programming ; mansatellitetype first_east ;,变量programming使用不带结构体标签的结构体类型定义声明,包含3个成分,分别为字符数组类型的author、datetype类型的publish_date、int类型的page_number,结构如图所示;,例11-3 结构体变量声明,struct preson zhang ; struct date int year,month,day ; dateofbirth; struct char author10 ; datetype publish_date ; int page_number ; programming ; mansatellitetype first_east ;,变量first_east使用typedef定义的类型标识符mansatellitetype声明,具有如图结构,类型定义不分配存储空间,只说明一个数据类型的框架结构。 变量声明时才给变量分配存储空间,并且使得被声明的变量具有相应类型的结构。 到目前为止声明的四个变量zhang、dateofbirth、programming、first_east具有实体,被分配存储空间。 类型标识符datetype、 mansatellitetype只是定义了一个数据类型的框架,不占用存储空间,只给相应类型起一个名字。,指向结构体变量的指针,C可以定义指向任何类型的指针类型,并声明相应指针类型的变量,结构体类型当然不例外。,struct preson *pointer_preson ; struct date int year,month,day ; *dateofpointer ; struct char author10 ; datetype publish_date ; int page_number ; *p ; mansatellitetype *p_east,例11-4 指向结构体类型变量的指针变量,变量pointer_preson为指向标签为preson的结构体类型变量的指针变量。 pointer_preson可以指向相应结构体类型的变量。比如 pointer_preson = ,变量p为指向无标签结构体类型变量的指针变量。 P 可以指向相应结构体类型的变量。比如 p = ,变量p_east为指向结构体类型mansatellitetype变量的指针变量。 p_east 可以指向相应结构体类型的变量。比如 p_east = ,结构体变量的成分,访问结构体变量的一个成分,使用成员选择表达式 成员选择表达式 直接成员选择 间接成员选择 直接成员选择 后缀表达式 . 标识符 间接成员选择 后缀表达式 - 标识符,直接成员选择 直接成员选择表达式针对一般的结构体变量。 形式是: r . w r 是后缀表达式,最终计算出一个结构体变量; w是 r 所属结构体类型中的一个成员名字 下述成员选择表达式是合法的: programming_pascal.author,间接成员选择 间接成员选择表达式针对指向结构体变量的指针变量 形式是 p-w p 是后缀表达式,最终计算出一个指向结构体变量的指针变量; w 是p所指向结构体变量所属类型中的一个成员名字 下述成员选择表达式是合法的: pointer_preson - name p_east - weight p_east - lounchdate,也可首先对指针变量进行求地址运算 然后使用直接成员选择 比如上述三个选择表达式还可以写成如下形式。由于优先级的原因,这里的括号是必须的 (*pointer_preson).name (*p_east).weight (*p_east).lounchdate,由于成员选择表达式本身也是一个变量访问,它是相应成分类型的一个变量,它与成分类型的其它变量一样 凡是可以使用那些变量的地方都可以使用成员选择表达式。 对于嵌套结构体,可以认为“成员选择表达式”仍然是一个“后缀表达式”,所以可以继续应用“成员选择表达式”的规则访问里层的成分。 zhang.birthdate.month p_east - lounchdate.year,例11-5 设计表示复数的结构体类型, 给出复数加法和乘法函数,解: /* 复数类型 */ typedef struct complex float real_part,imaginary_part ; complex_type,/* 复数加法 */ complex_type complex_add(complex_type x, complex_type y) complex_type add; add.real_part=x.real_part+y.real_part; add.imaginary_part=x.imaginary_part+y.imaginary_part; return add; ,/* 复数乘法 */ complex_type complex_mul ( complex_type x, complex_type y ) complex_type product ; product.real_part = x.real_part * y.real_part + x.imaginary_part * y.imaginaty_part ; product.imaginary_part = x.real_part * y.imaginary_part + x.imaginaty_part * y.real_part ; return product ; ,【例11-6】,已知图书检索卡的结构如图所示,建立该卡片的数据结构,并编出根据书号检索相应书名、作者名、语种、摘要的函数。,解: 显然应该用结构体类型来描述该卡片。设每个结构体变量为一张卡片, 全部卡片存放在文件 card.dat 中。函数先读入书号;对欲检索的书号采用顺序检索方式检索; 检索到后输出书名、作者名、语种、摘要;最后输出提示信息“search end!”。,假设主程序中有下述一系列声明 FILE * cardpointer ; /* 文件指针 */ struct bookno / 书号结构体 char catalogue ; char order8 ; ; struct date / 日期结构体 int year,month,day ; ; struct bookcard / 检索卡结构体 char name32,author16,languge16 ; struct date publishingdate ; struct bookno no ; char abstract256; ;,并且在主函数中已经用 cardpointer=fopen(“card.dat“,“r“ ); 打开了文件card.dat ,则 检索函数 searchbook 输出检索结果的函数out_anser 如下:,/* 输出检索结果函数 */ void out_anser(struct bookcard card ) int i , j , k ; printf( “NAME:%sn”, ); printf( “AUTHOR:%sn”, card.author); printf( “LANGUGE:%sn”, card.languge ); printf(“Publish date:%d-%d-%d“ ,card.publishdate.year ,card.publishdate.month ,card.publishdate.day); printf( “ABSTRACT:n” ) ; for ( i=0; i3; i+ ) printf( “ ” ) ; for ( k=1; k=64; k+ ) printf( “%c”,card.abstract64*i+j) ; printf(“n”); ,/* 检索函数 */ void searchbook( void ) char catalogue0 ; char order08 ; struct bookcard card; /* 输入欲检索的类别, 书号 */ printf ( pleace input catalogue , order : ) ; scanf( “%c” , ,结构体与函数,结构体与函数的关系 返回结构体值的函数 函数的结构体参数 在C中允许函数类型为结构体类型,即函数可以返回一个结构体值; 还允许结构体作为函数的参数,用参数的方式向函数传递结构体类型的值。,返回结构体值的函数,函数的计算结果可能是一个结构体值。在C中,有两种途径能够把该结构体值通过函数调用带回调用函数的主程序。 使用指针 函数的结果类型是指向结构体类型变量的指针类型 直接使用结构体类型 函数的结果类型是结构体类型,直接把一个结构体值带回调用函数的主程序,第一种方式就是返回指针的函数,只不过相应指针是指向结构体类型变量的指针。与其它类型返回指针的函数没有任何区别,本书在第八章8.2节已经介绍过,此处不再赘述。 本章的例11-5已经使用了第二种方式,下边再举例介绍这种方式。,例11-9,一个人事档案管理系统中,职工登记卡包含姓名、性别、出生时间等信息。为该人事档案管理系统编写输入一个职工卡片的函数,供主管理系统使用。,解:职工登记卡的类型定义如下。 typedef enum male , female sextype ; typedef struct int year,month,day ; datetype; typedef struct cardperson char name8 ; /* 姓名 */ datetype birthdate ; /* 出生时间 */ sextype sex; /* 性别 */ typecardperson ;,typecardperson readcard(void) typecardperson card; / 说明一个卡片类型变量 int sex_tag; printf( “pleace input name:“); / 以下开始输入 scanf(“%s“,); / 姓名 printf( “please input birthdate:year、month、day“); scanf(“%d %d %d”, / 带着一张卡片card值返回 ,在主程序中,将使用函数readcard带回的card值。比如主程序中具有功能:输入所有职工卡片、填加一张职工卡片等,这些功能的实现都将调用该函数。如果用数组保存所有卡片并且设不超过100个职工,并有声明: #define n 100 int v,flag; typecardperson card_arrn;,可以设计实现输入功能的程序片段如下: v=0; flag=1; while (flag) card_arrv = read_card(); v+; printf( “please choose 0_end 1_continue :“); scanf(“%d“, ”调用函数read_card 函数带回的值是结构体值,直接送入数组成分变量card_arrv中,结构体作函数参数,在函数之间,通过参数传送结构体值也有两种方法 用指向结构体变量的指针作函数参数 直接用结构体变量作函数参数 第一种方式就是指针作函数参数,只不过相应指针是指向结构体类型变量的指针。与指向其它类型变量的指针没
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年方便面行业网红品牌崛起路径与启示
- 2026年山东省化学中考预测试卷
- 2026年指导病人进行血培养标本采集流程
- 2026年儿科病房物体表面 ATP 监测应用
- 游泳馆设备维护保养合同协议
- 线上投资理财资金结算合同
- 电脑维修质量监控协议
- 风险管理框架2026年金融风险管理合同
- 线上数据标注兼职敏感性评估协议
- 2026年便携式气象站安装与使用
- 2026广东东莞市城市管理和综合执法局招聘编外聘用人员6人备考题库及答案详解(真题汇编)
- 2026甘肃甘南州临潭县卫生健康系统紧缺卫生专业技术人员招聘30人考试备考题库及答案解析
- 2026年7月浙江高中学业水平合格考生物试卷试题(含答案详解)
- 2026年真空镀膜机电源行业分析报告及未来发展趋势报告
- 煤矿尽职调查报告
- (正式版)T∕CPCPA 0017-2026 托育机构婴幼儿回应性照护服务规范
- (2026版)视网膜中央动脉阻塞神经介入专家共识课件
- 2025年四川省广元市八年级地理生物会考考试真题及答案
- 2026年证券从业资格证题库检测试卷及完整答案详解(考点梳理)
- 边坡工程验收记录表模板
- 2026湖北三峡旅游集团股份有限公司招聘笔试参考试题及答案解析
评论
0/150
提交评论