您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 冶金工业 > 第7讲-结构体与指针
1复习:(1)结构体变量的定义与引用(2)结构体数组新内容:(1)指向结构体变量的指针(2)指向结构体数组的指针(3)结构体指针作为函数参数(4)用指针处理链表第7讲结构体与指针2复习:结构体变量的定义与引用注意不要忘了分号成员列表结构体类型定义形式:struct结构体类型名{数据类型成员名1;数据类型成员名2;::数据类型成员名n;};关键字用户定义的标识符32.定义结构体类型同时定义变量structstudent{charname[10];intage;ints1,s2;}st1,st2;1.先定义结构体类型,再定义变量structstudent{charname[10];intage;ints1,s2;};structstudentst1,st2;复习:结构体变量的定义与引用结构体变量的定义结构体类型定义结构体变量定义结构体变量占用的字节数可用sizeof运算符算出printf(“%d\n”,sizeof(structstudent));printf(“%d\n”,sizeof(st1));4复习:结构体变量的定义与引用例:structdate{intyear;intmonth;intday;};structstud{charname[10];structdatebirthday;ints1,s2;};结构体类型可以嵌套定义或:structstud{charname[10];structdate{intyear;intmonth;intday;}birthday;ints1,s2;};5复习:结构体变量的定义与引用应用typedef定义结构体类型structstudent{charname[10];intage;ints1,s2;};structstudentst1,st2;typedefstructstudent{charname[10];intage;ints1,s2;}SD;SDst1,st2;优点:书写简单,使程序具有更好的移植性6复习:结构体变量的定义与引用引用结构体变量中的成员(点记法)格式:结构体变量名.成员名structstudent{charname[10];intage;ints1,s2;}st1,st2;strcpy(st1.name,“Mary”);st1.age=21;scanf(“%d%d”,&st1.s1,&st1.s2);相同类型的结构体变量可以进行整体赋值只能对结构体变量的成员进行输入和输出st2=st1;711.6.1指向结构体数据的指针定义指向结构体变量的指针typedefstructstudent{charname[20];intage;ints1,s2;}SD;SDx,stu,*p;p=&stu;成员的引用格式(1)结构体变量名.成员名stu.name例:scanf(“%s”,x.name);scanf(“%d”,&x.age);x.s1=89;x.s2=78;gets(stu.name);(*p).age=21;scanf(“%d”,&p-s1);p-s2=90;(2)(*指针变量名).成员名(*p).age(3)指针变量名-成员名p-s18赋值语句p=&student;指针变量p指向结构体变量student引用结构体中的成员变量:(*p).成员名或p-成员名相当于student.成员名pstudent9说明:和成员运算符一样,“-”为指向运算符,是运算优先级最高的运算符。由于成员运算符“.”的运算优先级高于运算符“*”,因此(*p).成员名中()不能少。*p.成员名p=&student.score;不能用指向某个结构体变量的指针指向该结构体变量的某个成员。10对结构体数组及其元素可以用指针来指向例如:structstruct_name{charname[10];intnum;floatscore;};/*定义结构体类型标识符*/structstruct_namestd[30],*p;11.6.1指向结构体数组的指针11900390赵明879002王建899001李红结构体数组stdstd[0]std[1]std[2]p赋值语句p=std;/*p指向一个结构体数组std*//*指针变量p存放的是数组std的首地址*/引用:p-name;p-num;p-score;12赵明909003879002王建899001李红结构体数组stdstd[0]std[1]std[2]思考:赋值语句p=std+1;和p++;分别代表指针p指向哪里?p-name;p-num;p-score;代表的信息发生了什么变化?pp13注意:以下赋值语句都是错误的:p=&std[1].score;(不能指向数组元素的成员变量)p=&std;(数组名本身就代表该数组的首地址,因此不能使用地址运算符&)14结构体变量作为函数参数1.函数实参和形参都用结构体变量,参数之间为值传递实参结构体变量各成员的值依次传给形参结构体变量2.返回结构体类型值的函数定义格式:结构体类型名函数名(形参表){函数体;}例:structstudentfunct(intx,floaty){函数体;}注意:结构体类型是已经定义好的11.6.3结构体指针作为函数参数15#includestdio.h#defineN5structstud{charname[10];ints[3];intsum,ave;};structstudcount(structstudx){intj;x.sum=0;for(j=0;j3;j++)x.sum=x.sum+x.s[j];x.ave=x.sum/3;return(x);}例:求学生成绩的总分和平均分(结构体变量作参数)//定义学生的结构体类型//计算学生三门课的总分//返回学生的全部信息//结构体变量作参数返回结构体类型的值16voidmain(){structstuda[N];intj;for(j=0;jN;j++)scanf(“%s%d%d%d”,a[j].name,&a[j].s[0],&a[j].s[1],&a[j].s[2]);for(j=0;jN;j++)a[j]=count(a[j]);for(j=0;jN;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}//函数调用,将a[j]的值传给count函数的参数x,并将返回值赋给a[j]//输入N个学生的信息//定义结构体数组a,存放N个学生的信息17structstudcount(structstud*p){intj;p-sum=0;for(j=0;j3;j++)p-sum=p-sum+p-s[j];p-ave=p-sum/3;return(p);}例:求学生成绩的总分和平均分(指向结构体的指针作参数)#includestdio.h#defineN5structstud{charname[10];ints[3];intsum,ave;};//指向结构体的指针作参数返回结构体类型的值18voidmain(){structstuda[N];intj;for(j=0;jN;j++)scanf(“%s%d%d%d”,a[j].name,&a[j].s[0],&a[j].s[1],&a[j].s[2]);for(j=0;jN;j++)a[j]=count(&a[j]);for(j=0;jN;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}19voidmain(){structstuda[N],*q;intj;q=a;for(j=0;jN;j++)scanf(“%s%d%d%d”,q-name,&a[j].s[0],&a[j].s[1],&a[j].s[2]);for(j=0;qa+N;q++)a[j]=count(q);for(j=0;jN;j++)printf(“%10s%4d%4d%4d%6d%4d\n”,a[j].name,a[j].s[0],a[j].s[1],a[j].s[2],a[j].sum,a[j].ave);}20课后作业题定义一个结构体用于存储年、月、日数据,并定义函数用于求两个日期之间的天数。2111.7用指针处理链表链表:是可以动态地进行存储分配的一种数据结构它是由一组动态数据链接而成的序列结点:链表中的每一个动态数据称为一个结点表头结点表尾结点NULL为空地址表示链表到此结束2010142815709514281861570282NULL3中间结点22一.、基本概念1.动态存储分配:根据需要临时分配内存单元用以存放数据,当数据不用时可以随时释放内存单元2.链表:是可以动态地进行存储分配的一种数据结构它是由一组动态数据链接而成的序列3.结点:链表中的每一个动态数据称为一个结点4.结点类型:是一个包含指针项的结构体类型一般由两部分组成:(1)数据成员:存放数据(2)指针成员:存放下一个结点的地址23structsd{intnum;intscore;structsd*next;};数据成员指针成员链表的基本概念2010142815709514281861570282NULL324链表的基本概念2010head2010142815709514281861570282NULL3链表的每个结点存放在内存中的不同位置,只有找到第1个结点,才能通过第1个结点的指针成员找到第2个结点…因此我们将第1个结点的地址存放在头指针中头指针链表的长度是不固定的,可以随时添加结点,如果将一个结点添加到链表的尾部,则新结点成为表尾结点,它的指针成员必须赋为NULL,而原来的表尾结点则成为中间结点75NULL43692369225静态简单链表#includestdio.htypedefstructstud{intnum,score;structstud*next;}SD;head2010142815702010abc19514282861570382NULLp201014281570NULLvoidmain(){SDa,b,c,*head,*p;head=&a;a.num=1;a.score=95;a.next=&b;b.num=2;b.score=86;b.next=&c;c.num=3;c.score=82;c.next=NULL;p=head;while(p!=NULL){printf(“%3d%4d\n”,p-num,p-score);p=p-next;}}26动态链表的建立建立链表的方法表尾添加法:新结点作为表尾结点表首添加法:新结点作为表头结点95NULL1201086NULL21428201082NULL3157095NULL1201086NULL2142882NULL31570head201014281570head2010142827处理动态链表所需的函数(需用头文件stdlib.h)1.malloc函数原型:void*malloc(unsignedintsize)作用:在内存中开辟一个长度为size的连续存储空间,并将此存储空间的起始地址带回注意:(1)函数返回值是指针,但该指针是指向void类型的,因此在使用时希望这个指针指向其他类型需要用强制类型转换(2)如果内存缺少足够大的空间进行分配,则malloc函数返回值为“空指针”(即NULL)例:structsd*p;p=(structsd*)malloc(sizeof(structsd));强制类型转换结构体类型占用的字节长度282.free函数原型:voidfree(void*ptr)作用:将指针变量ptr指向的存储空间释放注意:(1)ptr的值不是任意的地址,必须是程序中执行malloc
本文标题:第7讲-结构体与指针
链接地址:https://www.777doc.com/doc-6109360 .html