《第10章结构、联合与枚举类型.ppt》由会员分享,可在线阅读,更多相关《第10章结构、联合与枚举类型.ppt(83页珍藏版)》请在三一办公上搜索。
1、结构、联合与枚举类型,第十章,第一节 结构类型第二节 结构数组第三节 结构指针第四节 在函数之间传递结构第五节 联合类型第六节 枚举类型第七节 用typedef定义类型第八节 链表基础第九节 举例,问题的引出 用学号、姓名、性别、年龄、住址等属性来描述一个学生。int num;char name20;char sex;int age;char addr30;问题一:在程序中这些变量没有的内在联系。问题二:如果有很多的学生,就可能造成混乱。,一、结构类型的概念,第一节 结构类型,这些数据存放在内存的某个区域。将此区域统一来使用,形成了结构体的概念。结构是逻辑上相互联系的一组分量的集合。结构中的分
2、量可以有不同的类型数据,结构中的分量称为结构的成员。,第一节 结构类型,比较简单数据类型时的变量说明语句:int i;,struct 结构体名 数据类型 成员名;数据类型 成员名;数据类型 成员名;;,二、结构类型的定义,struct为关键字结构体名是用户定义的类型标识。中包围的是组成该结构的成员。,成员的数据类型既可以是简单的数据类型(int、char、float、double.),也可以是复杂的数据类型(数组类型和结构类型)。,第一节 结构类型,结构定义实例为了描述日期可以定义如下结构:struct date int year;/*年 结构成员的*/int month;/*月 数据类型是*
3、/int day;/*日 整型*/;为了处理通信录,可以定义如下结构:struct address char name30;/*姓名。字符数组*/char street40;/*街道名称*/char city20;/*城市*/char state2;/*省市代码*/unsigned long zip;/*邮政编码。*/;,第一节 结构类型,在定义了某种类型的结构体后,就可以使用该类型的结构变量。用类型说明语句说明结构变量 struct 结构体名 结构变量名;系统为所说明的结构变量按照结构定义时说明的组成(成员分量),分配存储数据的实际内存单元。例:将变量today说明为date型的结构变量:s
4、truct date today;说明多个address型的结构变量:struct address wang,li,zhang;结构变量同样有存储类型,存储特性与一般变量完全相同。,三、结构变量的说明,第一节 结构类型,结构变量占用内存情况 结构变量的各个成员分量在内存中占用连续存储区域,所占内存大小为结构中每个成员的占用内存的长度之和。结构变量today和wang占用在内存的情况如图所示。,第一节 结构类型,关于结构类型的说明类型与变量是不同的概念。在定义结构变量时一般先定义一个结构类型,然后 定义变量为该类型。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是
5、不分配空间的,只对变量分配空间。对结构中的成员,可以单独使用,它的作用与地位相当于普通变量。成员也可以是结构变量。成员名可以与程序中的变量名相同时,二者不代表同一对象。,第一节 结构类型,在定义结构时说明结构变量例如:struct student int num;char name20;char sex;int age;char addr30;student1,student2;直接说明结构变量例如:struct char name20;char addr30;zhang;,第一节 结构类型,结构成员是另一个结构例如:struct dateint month;int day;int year;
6、struct studentint num;char name20;char sex;int age;struct date birthday;char addr30;student1,student2;,birthday,birthday,birthday,birthday,第一节 结构类型,访问结构中的成员是通过成员的名字,称为“按名引用”。在程序中使用结构中成员的方法为:结构变量名.成员名称例:将“92.10.01”送入today,对其各个成员分别赋值:today.year=92;today.month=10;today.day=1;指明结构成员的符号“.”是运算符,含义是访问结构中的成
7、员。“.”操作的优先级在语言中是最高的。其结合性为从左到右。,四、引用结构变量的成员,第一节 结构类型,例:用结构描述一个人的基本情况,可以定义如下结构:struct person/*定义person结构类型*/char name30;char sex;struct date birthday;/*结构的嵌套定义*/man;,第一节 结构类型,输入zhang先生的情况,可用如下语句:strcpy(man.name,“zhang”);/*注意:不能写成man.name=zhang;*/man.sex=M;/*为结构中的字符成员赋值*/man.birthday.year=1960;man.birt
8、hday.month=3;man.birthday.day=28;/*为嵌套定义的结构中的成员赋值*/,第一节 结构类型,如果要将“zhang”改为“zhong”,只要将结构变量man中的数组成员name下标为2的元素a改为o即可。可以使用下列语句:man.name2=o;/*为结构变量中的数组成员的一个元素赋值*/,第一节 结构类型,五、对结构变量的整体操作,要对结构进行整体操作有很多限制,语言中能够对结构进行整体操作的运算不多,只有赋值“”和取地址“”操作。例如:有 struct date sunday,today;如果today被赋值后,可用语句 sunday=today;为sunday
9、赋值。,第一节 结构类型,结构类型的引用说明不能将一个结构变量作为一个整体直接访问。例如已定义student1为结构变量并且已有值。不能这样引用:printf(“%s,%c,%d,%d,%dn”,student1);如果成员本身又是一个结构类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取等运算。例如,对上面定义的结构变量student1,可以这样访问各个成员:student1.namestudent1.sexstudent1.birthday.monthstudent1.birthday.daystudent1.birthday.year,第一节
10、结构类型,对成员变量可以象普通变量一样进行各种运算。student2.birthday.year=student1.birthday.year;sum=student1.birthday.month+12;student1.age+;+student1.age;,第一节 结构类型,可以引用成员的地址,也可以引用结构变量的地址。如:scanf(“%d”,第一节 结构类型,例:输入今天的日期,然后输出该日期。#include main()struct date/*在函数中定义结构类型date*/int year,month,day;struct date today;/*说明结构变量today*/
11、printf(Enter today date(YYYY/MM/DD):);scanf(%d/%d/%d,例C10_103,第一节 结构类型,对结构变量进行初始化在说明变量的同时,可以对每个成员置初值,称为结构变量的初始化,其一般形式为:定义结构时说明变量 struct 结构体名 结构变量=初始化数据;类型说明语句struct 结构体名 结构变量=初始化数据;说明:中的初始化数据用逗号分隔。注意数据的个数、数据类型、顺序要一一对应。,六、结构变量的初始化,第一节 结构类型,例:用结构描述个人基本情况,打印个人档案。struct date/*在所有函数的外部定义结构date*/int year,
12、month,day;struct person/*在所有函数的外部定义结构person*/char name14,sex;struct date birthday;struct person xu=Xu lihui,M,1962,10,4;main()struct person fang=Fang jin,M,1963,9,13;struct person yuan=Yuan zhiping,M,1963,10,5;/*说明结构变量fang、yuan,并初始化结构变量*/,第一节 结构类型,printf(name sex birthdayn);printf(-n);printf(%-14s%-
13、4c%4d.%2d.%2dn,xu.name,xu.sex,xu.birthday.year,xu.birthday.month,xu.birthday.day);printf(%-14s%-4c%4d.%2d.%2dn,fang.name,fang.sex,fang.birthday.year,fang.birthday.month,fang.birthday.day);printf(%-14s%-4c%4d.%2d.%2dn,yuan.name,yuan.sex,yuan.birthday.year,yuan.birthday.month,yuan.birthday.day);,例C10_
14、104,第一节 结构类型,结构体数组说明语句的格式,对结构体数组的认识是一个数组。数组中的每一个元素的数据类型是结构类型。例:为记录100个人的基本情况。可以说明一个有100个元素的数组。数组元素的基类型为结构。struct person man100;man就是有100个元素的结构数组,数组的每个元素为 person 型。,标识符数组长度,struct 结构体名,第二节 结构数组,访问结构数组元素成员 必须遵守数组使用和访问结构成员的规定。访问数组元素 按下标进行访问。访问数组元素的成员,使用“.”运算符和成员名。例如:要将数组man中的 3号元素赋值为:Fangjin,M,1963,9,1
15、3,就可以使用下列语句:strcpy(man3.name,Fangjin”);man3.sex=M;man3.birthday.year=1963;man3.birthday.month=9;man3.birthday.day=13;,第二节 结构数组,将“Fangjin”改为“Fangjun”,修改其中的字母i:man3.name5=u;/*为数组中元素的数组成员中的一个字符赋值*/注意结构数组遵循数组的性质数组元素的起始下标从0开始,数组名表示该结构数组的存储首地址。结构数组存放在连续的内存区域中,所占内存大小为结构类型的大小乘以数组元素的数量。sizeof(struct person),
16、struct person man100长度=37*100=3700 字节,?,第二节 结构数组,例:简单的密码加密程序。加密过程是先定义一张字母加密对照表。将需要加密的文字输入加密程序,程序根据加密表中的对应关系,将输入的文字加密输出。对加密表中未出现的字符则不加密。输入 输出 输入 输出 输入 输出 输入 输出 输入 输出 a d b w c k d;e i i a k b;c w estruct table/*定义结构table*/char input;/*成员input存输入的字符*/char output;/*成员output存输出的字符*/;/*外部结构数组translate并初始
17、化*/struct table translate=a,d,b,w,c,k,d,;,e,i,i,a,k,b,;,c,w,e;/*建立加密对照表*/,第二节 结构数组,“struct table translate=.”有三个作用:说明了一个外部的结构数组translate,表示数组的大小由后面给出的初始化数据决定,对结构数组进行初始化。在程序中给出了数组初始化数据,所以结构数组translate有9个元素。,第二节 结构数组,struct table char input,output;struct table translate=a,d,b,w,c,k,d,;,e,i,i,a,k,b,;,c
18、,w,e;main()char ch;int str_long,i;str_long=sizeof(translate)/sizeof(struct table);/*计算元素个数*/while(ch=getchar()!=n)for(i=0;translatei.input!=ch/*原样输出*/,例C10_201,第二节 结构数组,例:分析程序运行结果struct s int x;int*y;/*y:是指向整型的指针*/int data5=10,20,30,40,50;/*data:整型数组*/struct s array5=100,/*array:结构数组,初始化*/结构数组array的
19、每个元素有两个成员,初始化后的状态如下。,第二节 结构数组,main()int i=0;/*说明变量i并赋初值*/struct s s_var;/*s_ver:一般的结构变量*/s_var=array0;/*将结构数组array0整体赋给s_var*/printf(%dn,s_var.x);printf(%dn,*s_var.y);printf(For array:n);printf(%dn,arrayi.x);printf(%dn,*arrayi.y);printf(%dn,+arrayi.x);printf(%dn,+*arrayi.y);printf(%dn,array+i.x);pri
20、ntf(%dn,*+arrayi.y);printf(%dn,(*arrayi.y)+);printf(%dn,*(arrayi.y+);printf(%dn,*arrayi.y+);printf(%dn,*arrayi.y);,第二节 结构数组,(i=0):s_var=array0;,100,10,100,s_var.x 取s_var的成员x的值*s_var.y 取s_var的成员指针y所指的内容,arrayi.x 取arrayi的x的值*arrayi.y 取arrayi的指针y所指的内容,10,10,100 10,100 10,第二节 结构数组,+arrayi.x 取arrayi的x的值,
21、x加1后输出+*arrayi.y 取arrayi的指针y所指的内容,y的内容加1后输出,100,101,10,11,1,200,30,array+i.x i先加1后取arrayi的x的值,输出*+arrayi.y 将arrayi的指针y先加1后再取y所 指的内容,输出,101 11,200 30,第二节 结构数组,(*arrayi.y)+取arrayi的指针y的内容,输 出,y的内容再加1*(arrayi.y+)取arrayi的指针y的内容,输 出,指针y再加1,30,31,40,50,*arrayi.y+同*(arrayi.y+),由于运 算的结合性隐含了括号,输出*arrayi.y 输出,
22、例C10_202,30 31,40 50,第二节 结构数组,类似于指向基本数据类型的指针的概念,将结构体变量的地址赋给另一个变量,这就是指向结构体的指针(简称为结构指针)。结构指针说明的一般形式struct 结构体名*标识符;例如:struct date*pdate,today;执行语句:pdate=结果:,一、结构指针的概念,第三节 结构指针,通过结构指针访问成员采用运算符“-”进行操作。结构指针-成员名“-”运算符有最高的优先级,结合性从左至右。通过结构指针pdate访问成员year的操作就可以写成:pdate-year=1963;等价于:today.year=1963;(*pdate).
23、year=1963;辨疑:pdate-year*pdate-year,二、通过结构指针访问结构体的成员,例C10_301,第三节 结构指针,例:用结构指针改写加密程序struct tablechar input,output;struct table transl=a,d,b,w,c,k,d,;,e,i,i,a,k,b,;,c,w,e,;main()char ch;struct table*p,*pend;/*p和pend为向结构指针*/pend=,第三节 结构指针,例.C:请分析程序的运算结果struct sint x,*y;/*y:结构中的成员是指向整型的指针*/*p;/*p:指向结构的指
24、针*/int data5=10,20,30,40,50,;/*data:整型数组*/struct s array5=100,/*array:结构数组*/,第三节 结构指针,main()p=array;/*指针p指向结构数组的首地址*/printf(%dn,p-x);printf(%dn,(*p).x);printf(%dn,*p-y);printf(%dn,*(*p).y);printf(%dn,+p-x);printf(%dn,(+p)-x);printf(%dn,p-x+);printf(%dn,p-x);printf(%dn,+(*p-y);printf(%dn,+*p-y);print
25、f(%dn,*+p-y);printf(%dn,p-x);printf(%dn,*(+p)-y);printf(%dn,p-x);printf(%dn,*p-y+);printf(%dn,p-x);printf(%dn,*(p-y)+);printf(%dn,p-x);printf(%dn,*p+-y);printf(%dn,p-x);,第三节 结构指针,结构数组array的初始化后的状态如图所示。p-x 取结构指针p指向的结构的成员x的值,输出(*p).x 取结构指针p的内容的成员x的值,输出*p-y 取结构指针p的指针成员y的内容,输出*(*p).y 取指针p的内容的指针成员y的内容,输出
26、+p-x p所指向的x加1,x先加1后再输出,p不加1,100,10,101,100,100,10,10,101,第三节 结构指针,(+p)-x p先加1后再取x的值,x不加1,输出 p-x+先取x的值,输出,然后x再加1,p-x 输出+(*p-y)p所指的y的内容先加1,输出,p不加1,y也不加1+*p-y 同上,由运算的结合性隐含了括号,输出,200,201,20,21,22,200,200,201,21,22,第三节 结构指针,*+p-y p所指的y先加1后再取y的内容,输出,p不加1,y的内容不加1 p-x 输出*(+p)-y p先加1后再取所指y的内容,输出 30 p-x 输出*p-
27、y+取p所指的y的内容输出,然后p所指的y加1 p-x 输出,30,201,300,30,201,30,300,30,300,第三节 结构指针,*(p-y)+取p所指的y的内容,输出,然后p所指的y再加1p-x 输出*p+-y 取p所指的y的内容,输出,然后p再加1p-x 输出,40,300,50,400,300,40,50,400,例C10_303,第三节 结构指针,指针运算与+运算规律小结由运算符的优先级和结合性决定+操作的对象;由+的前缀/后缀形式,决定操作的时机。+p-x p-x+*p-y*+p-y*(+p)-y*p-y+;*(p-y)+*p+-y,第三节 结构指针,结构与函数的关系:
28、向结构中传递函数的成员;在函数之间传递整个结构;向函数传递结构的地址(指针)。向函数中传递结构的成员在函数中传递结构成员的方法与传递简单变量的方法相同:在函数之间传递成员的值;在函数之间传递成员的地址。,一、结构、结构指针作为函数的参数,第四节 在函数之间传递结构,实例printf(“%d”,man.birthday.year);传递成员的值 scanf(“%d”,传递结构成员的地址,第四节 在函数之间传递结构,在函数之间传递整个结构将结构作为整体,在函数之间传递:将结构变量作为形参;函数的返回值为一个结构类型。,第四节 在函数之间传递结构,例:利用结构变量求解两个复数之积。、(3+4i)(5
29、+6i)、(10+20i)(30+40i)struct complxint real;/*real为复数的实部*/int im;/*im为复数的虚部*/;struct complx cmult(za,zb)/*函数返回值为结构类型*/struct complx za,zb;/*形式参数为结构类型*/struct complx w;w.real=za.real*zb.real-za.im*zb.im;w.im=za.real*zb.im+za.im*zb.real;return(w);/*返回计算结果,返回值的类型为结构*/,例C10_401,第四节 在函数之间传递结构,向函数传递结构的地址向函
30、数中传递结构的地址要将函数的形参定义为指向结构的指针,在调用时要用结构的地址作为实参。例:输入10本书的名称和单价,按照单价排序。程序中使用插入排序算法。,第四节 在函数之间传递结构,插入排序的基本思想是:在数组中,有 N 个已经从小到大已经排好序的元素,要加入1个新的元素时,可以从数组的第 1 个元素开始,依次与新元素进行比较。当数组中首次出现第 i 个元素的值大于新元素时,则新元素就应当插在原来数组中的第i-1个元素与第 i 个元素之间。此时可以将数组中第 i 个元素之后(包括第 i 个元素)的所有元素向后移动 1 个位置,将新元素插入,使它成为第 i 个元素。这样就可以得到已经排好序的
31、N+1 个元素。,第四节 在函数之间传递结构,2,2,2,3,5,9,7,6,11,插入排序法示例,第四节 在函数之间传递结构,#define NUM 10struct book/*定义结构book*/char name20;/*书名*/float price;/*单价*/;main()struct book term,booksNUM;int count;/*数组books的元素计数器*/for(count=0;countNUM;)printf(“Enter Name and Price.book%d=,count+1);scanf(“%s%f”,term.name,/*传递数组中1个元素的
32、地址*/,第四节 在函数之间传递结构,sortbook(term,pbook,count)struct book term;/*形参:结构变量term*/struct book*pbook;/*指向结构数组首元素的指针pbook*/int count;/*数组中已存入count个有序元素*/int i;struct book*q,*pend=pbook;for(i=0;iprice term.price)break;for(q=pend-1;q=pbook;q-)*(q+1)=*q;*pbook=term;/*在pbook处插入新元素term*/,第四节 在函数之间传递结构,printbook
33、(pbook)struct book*pbook;printf(%-20s%6.2fn,pbook-name,pbook-price);,例C10_402,第四节 在函数之间传递结构,定义结构变量stu:struct student int num;float score;char sex;stu;,sizeof(stu)是 7。,第五节 联合类型,什么是联合类型,union,定义联合变量stu:student int num;float score;char sex;stu;,联合变量stu占用内存情况,union,union,union,联合变量占用空间的大小等于成员分量中最长的成员占用内
34、存的长度。,第五节 联合类型,union long i;int k;char c;mix;mix.i=0 x12345678;printf(“%xn”,mix.i);printf(“%xn”,mix.k);printf(“%xn”,mix.c);,低,高,ffe3 ffe2 ffe1 ffe0,第五节 联合类型,mix.c=A;,printf(“%ldn”,mix.i);printf(“%dn”,mix.k);printf(“%cn”,mix.c);,30541984122081A,例C10_501,第五节 联合类型,枚举类型是有限取值的数据类型。,第六节 枚举类型,什么是枚举类型,定义枚举类
35、型的格式 enum 枚举类型名 可能的取值表;例:enum weekday sun,mou,tue,wed,thu,fri,sat;说明枚举类型变量的格式 enum 枚举类型名 变量标识符;例:enum weekday a,b,c;,枚举类型的使用规则:1.枚举元素由系统定义表示序号的数值,从0 开始,顺序定义为0,1,2。例如:enum weekday sun,mou,tue,wed,thu,fri,sat;sun值为0,mon值为1,tue值为2,,sat值为6。2.枚举值是常量,不是变量,不能对枚举值赋值。例如,sun=5;mon=2;都是错误的。3.枚举元素的取值可以由用户定义。例如:
36、enum mon a,three=3,b,c,d;则元素的取值是0、3、4、5、6。,第六节 枚举类型,例C10_601,用户自定义类型标准类型(如int、char、float等):系统已经定义好的类型,用户可以直接使用,无须再进行定义。用户自定义类型:用户根据自己的实际要求,自己定义的新的数据类型。除结构和联合等类型之外,还可以用类型说明语句typedef定义新的类型标识符来代替已有的类型。typedef语句的一般形式typedef 已定义的类型 新的类型实例 typedef int INTEGER;typedef float REAL;等价:int i,j;INTEGER i,j;floa
37、t pai;REAL pai;,第七节用typedef定义类型,用链表处理不定长数组。什么是链表?结构定义:struct student int num;float score;struct student*next;链表的分类 单向链表、双向链表等。,一、链表概述,第八节 链表基础,动态存储分配函数 原型:void*malloc(int size)头文件:stdlib.h。功能:分配size个字节的存储区。返回值:分配成功,所分配区域的首返回地址。分配失败,返回 0。例如:struct student*ps;ps=(struct student*)malloc(sizeof(struct s
38、tudent);,第八节 链表基础,释放内存函数 原型:void free(void*p)头文件:stdlib.h。功能:释放p所指向的内存空间。返回值:无。例如:前面说明结构指针ps,为其分配了内存,释放内存,则写:free(ps);,第八节 链表基础,创建链表的过程:按照结构的大小分配一块内存区域。将该区域的首地址赋给一个头指针。继续分配一块内存区域。将该区域的首地址分配给前一个结点的结点指针变量。继续上述过程,直到链表的尾。,二、创建链表,第八节 链表基础,ps,f1aa,ps=(struct student*)malloc(sizeof(struct student),scanf(“%
39、ld,%f”,p1=(struct student*)malloc(sizeof(struct student),p1,ffe4,ffe4,ff4d,例C10_701,第八节 链表基础,建立链表函数(注:返回值是头指针)说明结构变量 head、p1、p2;head为空;输入第一个结点的数值数据;循环(条件:数据数据有效)为新结点分配内存,结点地址存于p1;为数值域赋值;如果是第一结点,将地址存于头指针;否则,保存在链表尾结点的指针域;给尾结点指针赋值;输入新的结点数据;;返回 head;,例C10_701a,第八节 链表基础,从头结点开始,到尾结点结束。尾结点的特征:其指针域为空。输出(结点指
40、针)循环(条件:指针不为空)输出数值域;前进一个结点;,三、输出一个链表,例C10_701b,第八节 链表基础,删除一个结点,既让上一个结点指向下一个结点。,三、在链表中删除一个结点,f1aa,头指针,(ps-1)-next=ps-next,ff4d,例C10_701b,第八节 链表基础,插入一个结点 既插入处前一个结点,指向新结点,新结点指向一个结点。,四、在链表中插入一个结点,f1aa,头指针,ff4d,ffdd,ps-next=head-next;,ps=(struct student*)malloc(sizeof(struct studet);,head-next=ps-next;,例
41、C10_701b,第八节 链表基础,双向链表:结点包含有两个指针域,分别保存其前继结点的地址和后续结点的地址。环型链表:链表的尾结点的指针指向链表的第一个结点。头结点:带有头结点的链表,其第一结点不保存数据,它所指向的结点为保存有效数据的第一个结点。,五、双向链表、环型链表、头结点,第八节 链表基础,例1:在第9章对整型数组从小到大排序输出时,使用指针数组指出整数的大小。例如:整数:5、3、4、7、3、5、6 指针数组 pa 的下标表示整数从小到大的顺序。,现在对整数进行编号,整数:5、3、4、7、3、5、6编号:3、1、2、5、1、3、4 使用结构数组求解这个问题,如右图所示。,第九节 举例
42、,struct bianhao int*pa;int b;struct bianhao pb7;,for(i=0;in;i+)scanf(“%d”,第九节 举例,struct bianhao int*pa;int b;struct bianhao pb7;for(i=0;in;i+)scanf(“%d”,for(i=0;i*pbj+1.pa)temp=pbj.pa;pbj.pa=pbj+1.pa;pbj+1.pa=temp;,第九节 举例,求整数的编号:pb0.b=1;for(i=1;in;i+)if(*pbi.pa=*pbi-1.pa)pbi.b=pbi-1.b;else pbi.b=pbi
43、-1.b+1;,例C10_901,第九节 举例,例2:编写一个模拟人工洗牌程序 使用结构card来描述一张牌,用随机函数来模拟人工洗牌的过程,最后将洗好的52张牌顺序分别发给四个人。struct card int pips;/*从1到13。1:A,11:J,12:Q,13:K*/char suit;/*牌的花色 C:梅花 D:方块 H:红心 S:黑桃*/;,第九节 举例,struct card deck=1,C,2,C,3,C,4,C,5,C,6,C,7,C,8,C,9,C,10,C,11,C,12,C,13,C,1,D,2,D,3,D,4,D,5,D,6,D,7,D,8,D,9,D,10,D
44、,11,D,12,D,13,D,1,H,2,H,3,H,4,H,5,H,6,H,7,H,8,H,9,H,10,H,11,H,12,H,13,H,1,S,2,S,3,S,4,S,5,S,6,S,7,S,8,S,9,S,10,S,11,S,12,S,13,S;/*初始化一副牌*/,第九节 举例,shuffle(deck)/*模拟人工洗牌的过程*/struct card deck;/*形式参数传递整个数组*/int i,j;randomize();/*调用函数对随机函数初始化*/for(i=0;i52;i+)j=rand()%52;/*从52张牌中随机选*/*择1张与第i张交换*/swapcard(
45、/*以元素地址为实参*/,第九节 举例,swapcard(p,q)/*交换两张牌*/struct card*p,*q;/*形参为指向结构的指针*/struct card temp;temp=*p;*p=*q;*q=temp;/*交换两个结*/*构变量的值*/main()int i;shuffle(deck);/*以结构数组名为实参调用函数*/for(i=0;i52;i+)if(i%13=0)printf(nNo.%d:,i/13+1);else printf(%c%2d,decki.suit,decki.pips);,例C10_902,第九节 举例,例3:约瑟夫问题 N个小孩围成一圈,从第M个
46、小孩开始循环报数(从1开始报),每报到R时这个人出列,然后接着从下一个人开始报数,同样报到S的人出列,直到全部人出列。求最后一个出列的小孩。求这个问题,先建立一个环型的单向链表,报数的过程就是从链表中删除结点的过程。通过此例掌握链表的操作。结构定义:struct boy int no;struct boy*next;,第九节 举例,for(i=1;i=n;i+),建立环性型链表:struct boy*setlinklist(int n)struct boy*head=NULL,*t,*q;int i;,t=(struct boy*)malloc(sizeof(struct boy);,t-no
47、=i;,1,if(head=NULL)head=t;else q-next=t;,q=t;,t-next=head;return(head);,第九节 举例,findlast(struct boy*head,int m,int r)int i;struct boy*t=head,*q=head;,1,2,3,t,for(i=1;inext;while(t!=t-next)for(i=1;inext;q-next=t-next;t=q-next;return(t-no);,第九节 举例,main()int i,n,m,r;struct boy*head;printf(Input n,m,r:);scanf(%d,%d,%d,例C10_903,第九节 举例,