第十一章结构类型及其它构造类型

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第十一章结构类型及其它构造类型在实际生活中,有着大量由不同性质的数据构成的实体,如日期就是由年、月、日组成的,通信录就是由姓名、地址、电话、邮政编码等组成的,对于象日期或通信录这样的实体,用数组是难于描述的。因此,在C语言中提供了一种新的称为结构的构造型数据类型。结构是一组相关的不同类型的数据的集合。结构类型为处理复杂的数据提供了便利的手段。本章详细讨论结构的定义、说明和使用,结构与数组和指针等基本问题,并介绍联合的基本概念,以及怎样用typedef定义新的类型。上一页下一页11.1结构类型11.1.1结构类型的概念与定义结构与数组类似,都是由若干分量组成的。数组是由相同类型的数组元素组成,但结构的分量可以是不同类型的,结构中的分量称为结构的成员。访问数组中的分量(元素)是通过数组的下标,而访问结构中的成员是通过成员的名字。在程序中使用结构之前,首先要对结构的组成进行描述,称为结构的定义。结构的定义说明了该结构的组成成员,以及每个成员的数据类型。结构定义的一般形式如下:struct结构类型名称{数据类型成员名1;数据类型成员名2;……数据类型成员名n;};其中:struct为关键字,是结构的标识符;结构类型名称是所定义的结构的类型标识,由用户自己定义;{}中包围的是组成该结构的成员项;每个成员的数据类型既可以是简单的数据类型,也可以是复杂的数据类型。整个定义作为一个完整的语句用分号结束。结构类型名称是可以省略的,此时定义的结构称为无名结构。虽然结构定义时并不要求其内部成员之间有任何内在的联系,但一般来说,结构中所有的成员在逻辑上都是彼此紧密相关的,将毫无任何逻辑关系的一组成员放入同一结构中没有任何实际意义。为了描述日期可以定义如下结构:structdate{intyear;/*年:整型作为结构中的成员*/intmonth;/*月*/intday;/*日*/};在这个结构定义中,结构类型名称为date,可以称这个结构类型为date。在date结构中,有三个成员year,month和day,三个成员均为整型。为了处理通信录,可以定义如下结构:structaddress{charname[30];/*姓名。字符数组作为结构中的成员*/charstreet[40];/*街道名称*/charcity[20];/*城市*/charstate[2];/*省市代码*/unsignedlongzip;/*邮政编码。无符号长整型作为结构中的成员*/};结构的定义明确了结构的组成形式,定义了一种C语言中原来没有、而用户实际需要的新的数据类型。与其他的数据类型不同,在程序编译的时候结构的定义并不会使系统为该结构分配内存空间,只有在说明结构变量时才分配内存空间。在程序中,结构的定义可以在一个函数的内部,也可以在所有函数的外部,在函数内部定义的结构,仅在该函数内部有效,而定义在外部的结构,在所有函数中都可以使用。上一页下一页11.2结构数组结构与数组的关系有两重:其一是在结构中使用数组类型作为结构的一个成员;其二是用结构类型作为数组元素的基类型构成数组。前者在前面的例题中已多次见到;后者是本节要讨论的内容。结构数组是一个数组,其数组中的每一个基本元素都是结构类型。说明结构数组的方法是:先定义一个结构,然后用结构类型说明一个数组变量。例如:为记录100个人的基本情况。可以说明一个有100个元素的数组。每个元素的基类型为一个结构,在说明数组时可以写成:structpersonman[100];man就是有100个元素的结构数组,数组的每个元素为person型结构。要访问结构数组中的具体结构,必须遵守数组使用的规定,按数组名及其下标进行访问,要访问结构数组中某个具体结构下的成员,又要遵守有关访问结构成员的规定,使用.访问运算符和成员名。访问结构数组成员的一般格式是:结构数组名[下标].成员名同一般的数组一样,结构数组中每个元素的起始下标从0开始,数组名称表示该结构数组的存储首地址。结构数组存放在一连续的内存区域中,它所占内存数目为结构类型的大小乘以数组元素的个数。结构数组man在内存中的存储如图11-3所示:例如,我们要将数组man中的3号元素赋值为:Fangjin,'M',1963,9,13,就可以使用下列语句:strcpy(man[3].name,Fangjin);man[3].sex='M';man[3].birthday.year=1963;man[3].birthday.month=9;man[3].birthday.day=13;/*为结构数组中一个元素的各个成员赋值*/为了将Fangjin改为Fangjun,修改其中的字母'i',可以使用下列语句,为结构数组中一个元素的数组成员中的一个字符赋值。man[3].name[5]='u';利用有3个元素的结构数组,可以很方便地改写例11-3.C,请读者自己编写。例11-4:分析运行结果。structs{intx;int*y;/*y:结构中的成员是指向整型的指针*/};intdata[5]={10,20,30,40,50};/*data:整型数组*/structsarray[5]={100,&data[0],200,&data[1],300,&data[2],400,&data[3],500,&data[4]};/*array:结构数组,初始化*/#includestdio.hmain(){inti=0;/*说明变量i并赋初值*/structss_var;/*s_ver:一般的结构变量*/s_var=array[0];/*将结构数组的array[0]整体赋给s_var*/printf(%d\n,s_var.x);/*按照结构变量的方式引用结构的成员*/printf(%d\n,*s_var.y);printf(Forarray:\n);/*以下是按结构数组元素方式引用结构成员*/printf(%d\n,array[i].x);printf(%d\n,*array[i].y);printf(%d\n,++array[i].x);printf(%d\n,++*array[i].y);printf(%d\n,array[++i].x);printf(%d\n,*++array[i].y);printf(%d\n,(*array[i].y)++);printf(%d\n,*(array[i].y++));printf(%d\n,*array[i].y++);printf(%d\n,*array[i].y);}程序中说明了一个结构数组array,结构数组array的每个元素有两个成员,其一为整型x,其二为指向整型的指针y。结构数组array的初始化后的状态如图11-4所示。程序各个printf语句中对数组操作的含义如下:s_var.x/*取s_var的成员x的值,输出100*/*s_var.y/*取s_var的成员指针y所指的内容,输出10*/array[i].x/*取array[i]的x的值,输出100*/*array[i].y/*取array[i]的指针y所指的内容,输出10*/++array[i].x/*取array[i]的x的值,x加1后输出101*/++*array[i].y/*取array[i]的指针y所指的内容,y的内容加1后输出11*/array[++i].x/*i先加1后取array[i]的x的值,输出200*/*++array[i].y/*将array[i]的指针y先加1后再取y所指的内容,输出30*/(*array[i].y)++/*取array[i]的指针y的内容,输出30后,y的内容再加1*/*(array[i].y++)/*取array[i]的指针y的内容,输出31后,指针y再加1*/*array[i].y++/*同上,由于运算的结合性隐含了括号,输出40*/*array[i].y/*输出50*/程序运行结束时,结构数组array的状态如图11-5所示。例11-5:简单的密码加密程序。其加密过程是先定义一张字母加密对照表。将需要加密的一行文字输入加密程序,程序根据加密表中的对应关系,可以很简单地将输入的文字加密输出,对于表中未出现的字符则不加密。可以定义一个结构来表示加密表。结构table中的成员input存入输入的字符,成员output保存加密后对应的字符。#includestdio.hstructtable/*定义结构table*/{charinput;/*成员input存输入的字符*/charoutput;/*成员output存输出的字符};structtabletranslate[]=/*说明外部的结构数组translate并初始化*/{'a','d','b','w','c','k','d',';','e','i','i','a','k','b',';','c','w','e'};/*建立加密对照表*/main(){charch;intstr_long,i;str_long=sizeof(translate)/sizeof(structtable);/*计算数组元素个数*/while((ch=getchar())!='\n'){for(i=0;translate[i].input!=ch&&istr_long;i++);if(istr_long)putchar(translate[i].output);/*对表中的字符加密输出*/elseputchar(ch);/*对其它字符原样输出*/}}语句structtabletranslate[]={...}有三个作用,一是说明了一个外部的结构数组translate;二是表示数组的大小由后面给出的初始化数据决定,三是对结构数组进行初始化。在程序中给出了数组初始化数据,所以结构数组translate有9个元素。程序中语句str_long=sizeof(translate)/sizeof(structtable);是用sizeof运算计算结构数组translate中元素的数目。sizeof(translate)求出数组translate所占用的字节总数,sizeof(structtable)求出数组中每个元素所占用的字节总数。运行程序时,从键盘逐个读取输入的字符存入变量ch中,将ch的值与结构translate中的input比较,如果是要加密的字符,则输入加密后的字符output,否则ch原样输出。例11-6:有N个小孩围成一圈并依次编号,教师指定从第M个小孩开始报数,当报到第S个小孩时,即令其出列,然后再从下一个孩子起从1开始继续报数,数到第s个小孩又令其出列,这样直到所有的孩子都依次出列。求小孩出列的顺序。这就是约瑟夫问题。由于问题中的小孩围成一个圈,因而启发我们用一个环形链来表示。我们用结构数组构成一个环形链。结构名为child。数组名为link。nextp的含义是排在当前这个孩子后面的下一个孩子的序号。由nextp可构成一个环型链,no是孩子的序号。这样就可以从第M个小孩开始沿着nextp连成的闭合链不断计数S次,输出对应的no表示让他出列。#includestdio.hstructchild/*定义结构child*/{intnextp;/*排在后面下一个位置上的孩子的序号*/intno;/*孩子的序号*/}link[100];/*说明结构数组link*/main(){inti,n,s,y,k,m,count=0;/*count为输出计数器*/printf(\nTellmehowmanychildrenarethere?);scanf(%3d,&n);printf(\nFromwhichtocount?);scanf(%3d,&m);printf(\nHowmanyshallIcount?);scanf(%3d,&s);for(i=1;i=n;i++)/*根据孩子总数n建立一个环*/{if(i==n)link[i].nextp=1;/*若是最后一个,则他的下一个是第一个人*/elselink[i].nextp

1 / 22
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功