C语言结构体与共用体_第1页
C语言结构体与共用体_第2页
C语言结构体与共用体_第3页
C语言结构体与共用体_第4页
C语言结构体与共用体_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

会计学1C语言结构体与共用体9.1.2定义结构体类型变量的方法

1.说明结构体类型的同时定义结构体数据structstudent{charname[12];charsex;structdatebirthday;floatsc[4];}std,pers[3],*pstd;2.直接定义结构体类型的数据在说明一个无名结构体类型的同时,直接进行定义。结构体名可省略,写成:struct{charname[12];charsex;structdatebirthday;floatsc[4];}std,pers[3],*pstd;第1页/共36页3.先说明结构体类型,再定义结构体数据structstudent{charname[12];charsex;structdatebirthday;floatsc[4];};structstudentstd,pers[3],*pstd;第2页/共36页9.1.3结构体类型数据的初始化1.结构体变量初始化所赋初值顺序放在一对花括号中,例如:structstudentstd={“LiMing”,’M‘,1962,5,10,88,76};注意:a按成员在结构体中的顺序一一对应赋值。

b不允许跳跃式赋初值。

c未赋初值的数值型和字符型数据,系统自动赋初值0。第3页/共36页2.结构体数组初始化由于数组的每一个元素都是一个结构体,因此通常将其成员的值依次放在一对花括号中,以便区分各个元素。例如:structbookcard{charnum[5];floatmoney;}bk[3]={{“No1”,35.5},{“No2”,25.0},{“No3”,66.7}};/*bk[0]bk[1]bk[2]*/3.结构体指针初始化结构体类型数据的指针与其它类型数据的指针初始化相同例如:structstustd,pers[3],*psd1=&std,*psd2=pers,(*p)[3]=&pers;第4页/共36页9.1.4结构体类型数据的引用1.结构体成员的引用若已定义了一个结构体变量和该类型的指针变量,并且该指针已指向同类型的变量,则可以用以下三种形式来引用结构体变量中的成员。结构体变量名也可以是已定义的结构体数组的数组元素。 (1)结构体变量名.成员名(2)指针变量名->成员名(3)(*指针变量名).成员名其中点号(.)称为成员运算符;箭头(->)称为结构指向运算符,减号(-)和大于号(>)之间不得有空格;第三种形式中,一对圆括号不可少。这些运算符与圆括号、下标运算符的优先级相同,优先级最高。第5页/共36页structstudent{charname[12];charsex; floatsc[4];}std,pers[5],*pstd;pstd=&std;引用成员形式如下: pstd->name (*pstd).name 第6页/共36页2.结构体变量的赋值a.成员的赋值:std.sex=’M’;pstd->sex=’M’;

(*pstd).sex=‘M’

b.整体赋值:即同类型的结构体变量可以相互赋值。pers[0]=std;(*pstd)=pers[0];第7页/共36页3.结构体数据的输入输出例9.1结构体数据输入输出。

#include“stdio.h”main(){struct{inti;charch1;charch2;}tr; scanf(“%d%c%c”,&tr.i,&tr.ch1,&tr.ch2); printf(“i=%d,ch1=%d,ch2=%d\n”,tr.i,tr.ch1,tr.ch2);}不能将一个结构体变量作为一个整体进行输入和输出,只能对结构体变量中的成员分别进行输入和输出.第8页/共36页9.1.5函数之间结构体数据的传递1.传递结构体成员与简单变量相同例9.2#include“stdio.h”structST{charstr[20];inti};voidf1(char*s){printf(“%s\n”,s);}voidf2(intn){printf(“%d\n”,n);}main(){structSTt={“Clanguage”,85};f1(t.str);f2(t.i);}程序运行结果为:Clanguage85第9页/共36页2.传递结构体变量形参结构体变量=实参结构体变量例9.3#include“stdio.h”structST{charstr[20],inti;}voidf(struct

STx){printf(“%s%d\n”,x.str,x..i);}main(){structSTt={“Clanguage”,85};f(t);}程序运行结果为:Clanguage85第10页/共36页3.传递结构体地址形参结构体指针变量=实参结构体指针例9.4#include“stdio.h”structST{charstr[20];inti;};voidf(structST*x){printf(“%s\n%d\n”,x->str,x->i);}main() {structSTt={“Clanguage”,85},*p;p=&t;f(p);}程序运行结果为:Clanguage85第11页/共36页4.结构体类型的函数例9.5找出成绩最高的学生记录,学生记录由学号和成绩组成。#include“stdio.h”#defineN5structstu{charnum[5]; floats;};structstufun(struct

stua[]){structstum=a[0]; inti; for(i=1;i<N;i++) if(m.s<a[i].s) m=a[i]; returnm;}第12页/共36页main(){structstua[N]={{“A01”,89},{“A05”,56},{“A25”,68},{“A08”,96},{“A09”,95}},b; b=fun(a); printf(“%s,%f\n”,b.num,b.s);}程序运行结果为:A08,96.000000第13页/共36页5.结构体指针类型函数例9.6找出成绩最高的学生记录的地址。#include“stdio.h”#defineN5structstu{ charnum[5]; floats;};structstu*fun(structstua[]){ structstu*m=&a[0]; inti; for(i=1;i<N;i++) if(m->s<a[i].s) m=&a[i]; returnm;}第14页/共36页main(){structstua[N]={{“A01”,89},{“A05”,56},{“A25”,68},{“A08”,96},{“A09”,95}},*b; b=fun(a); printf(“%s,%f\n”,b->num,b->s);}程序运行结果为:A08,96.000000第15页/共36页9.1.6动态存储分配与链表1.动态存储分配的概念:需要时分配,不需要时释放。2.用于动态存储分配的函数:使用时包含文件stdlib.h

(1)malloc()函数原型:void*malloc(unsignedintsize)

功能:在内存开辟size个字节存储区,返回一个指向存储区首地址的基类型为void的地址。若没有足够的内存单元供分配,函数返回空值(NULL)。注意:

i.由于malloc函数的返回值为void*,故在调用该函数时,必须利用强制类型转换运算符将其转换成所需的类型。

int*pi;pi=(int*)malloc(2);

第16页/共36页ii.若不能确定数据类型所占字节数,可以使用sizeof运算符求得。

int*pi;pi=(int*)malloc(sizeof(int));(2)calloc()函数原型:void*calloc(unsignedintnum,unsignedintsize)功能:分配num个大小为size字节的连续存储空间。成功,返回存储空间首地址;不成功,返回空值(NULL)。

int*pa;

pa=(int*)calloc(10,sizeof(int));(3)free函数原型:voidfree(void*ptr)

功能:将指针变量ptr指向的存储空间释放。注意:i.free函数只能释放由malloc函数和calloc函数开辟的存储空间。

ii.形参ptr是欲释放空间的首地址,不必指定空间大小。该函数无返回值。

free(pa);

第17页/共36页3.链表链表概念:同一类型的结构体变量连接到一起,构成一个链,各个结构体变量即为链表中的结点。(1)静态链表所有结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为”静态链表”.例如:structlink{charch;structlink*p;}a;在这里,p是一个可以指向structlink类型变量的指针;因此,a.p=&a是合法的表达式,由此构成的存储结构如图所示:第18页/共36页

例9.7一个简单的链表

structnode{intdata;structnode*next;};main(){a.cha.pstructnodea,b,c,*h,*p;a.data=10;b.data=20;c.data=30; h=&a; a.next=&b; b.next=&c;c.next=’\0’; p=h;/*移动p,使之依次指向a、b、c,输出它们data域中的值*/while(p) {printf(“%d”,p->data);p=p->next;/*p顺序后移*/}printf(“\n”);

habc}

第19页/共36页动态链表head

头指针头结点动态链表指的是在程序执行过程中从无到有的建立起一个链表,即一个一个的开辟结点和输入各结点数据,并建立起前后相链的关系。每个链表都用一个“头指针”变量来指向链表的开始,如图中的head;也就是说,在head中存放了链表第一个结点的地址。在这个链表中,设置了一个“头结点”,这个结点的数据域中不存放数据(也可以不设头结点)。链表最后一个结点的指针域不需存放地址时,就置成‘\0’(NULL)值,标志着链表的结束。上述链表的每个结点只有一个指针域,每个指针域存放着下一个结点的地址,因此,这种链表只能从当前结点找到后续结点,故称为“单向链表”。构成如图所示的单向链表,每个结点应该由两个成员组成:一个是整型的成员,一个是指向自身结构的指针类型成员。结点类型定义如下:structslist{intdata;structslist*next;};87^第20页/共36页I.建立带有头结点的单向链表建立单向链表的主要操作步骤如下:①读取数据; ②生成新结点;③将数据存入结点的成员变量中;④将新结点插入到链表中。重复上述操作直至输入结束。例9.8编写函数creat_slist,建立带有头结点的单向链表。结点数据域中的数值从键盘输入,以-1作为输入结束标志。链表的头结点的地址由函数值返回。h:头结点r:尾结点s:新结点第21页/共36页structslist*creat_slist(){intc;structslist*h,*s,*r;h=(structslist*)malloc(sizeof(structslist));/*生成头结点*/ r=h; scanf(“%d”,&c); /*读入数据*/ while(c!=-1) /*未读到数据结束标志时进入循环*/ {s=(structslist*)malloc(sizeof(structslist));/*生成一个新结点*/ s->data=c; /*读入的数据存入新结点的data域*/ r->next=s; /*新结点连到表尾*/ r=s; /*r指向当前表尾*/ scanf(“%d”,&c); /*读入数据*

} r->next=’\0’; /*置链表结束标志*/ returnh; /*返回表头指针*/}第22页/共36页II.顺序访问链表中各结点的数据域例9.9编写函数print_slist,顺序输出单向链表各结点数据域中的内容。voidprint_slist(structslist*head){structslist*p;p=head->next; /*p指向头结点后的第一个结点*/if(p==’\0’)printf(“Linklistisnull!\n”);/*链表为空(只有头结点)*/ else {printf(“head”); do { printf(“%d”,p->data);/*输出当前结点数据域中的值*/ p=p->next; /*p指向下一个结点*/}while(p!=’\0’); /*未到链表尾,继续循环*/printf(“end\n”);}}第23页/共36页III.在单向链表中插入结点在单链表中插入结点,首先要确定插入的位置。

qps例:编写函数:insert_snode,它的功能是:在值为x的结点前,插入值为y的结点,若值为x的结点不存在,则插在表尾。在进行插入操作的过程中,可能遇到三种情况:1)链表非空,值为x的结点存在,新结点应插在该结点之前。2)链表非空,但值为x的结点不存在,按要求新结点应插在表尾。3)链表为空表,这种情况相当于值为x的结点不存在,新结点应插在表尾,即插在头结点之后,作为表的第一个结点。908第24页/共36页函数insert_snode将对这三种情况进行处理。structslist*insert_snode(structslist*head,intx,inty){structslist*s,*p,*q; s=(structslist*)malloc(sizeof(structslist)); /*生成新结点*/ s->data=y; /*新结点中存入y值*/ q=head;p=head->next; /*工作指针初始化,p指向第一个结点*/ while((p!=’\0’)&&(p->data!=x)) /*表非空且未到表尾,查找x的位置*/ { q=p;p=p->next;} /*q指向p的前趋结点*/ s->next=p;q->next=s;/*x存在,插在x之前,x不存在,p的值为NULL,插在表尾*/returnhead;}第25页/共36页IV.删除单向链表中的结点为了删除单向链表中的某个结点,首先要找到待删除结点的前趋结点;然后将此前趋结点的指针域去指向待删结点的后续结点;最后释放被删结点所占存储空间即可。如图所示:

qp987第26页/共36页structslist*del_snode(structslist*head,intx){structslist*p,*q;if(head==’\0’){printf(“listnull!”);}/*链表不存在*/p=head;while((p->next!=’\0’)&&(p->data!=x)){ q=p;p=p->next;} /*q指向p的前趋结点*/if(p->data==x){if(p==head)head=p->next;/*p为头结点,使head指向p的下一个结点*/elseq->next=p->next;}/*q指向p的下一个结点*/printf(“delete:%ld”,x);}elseprintf(“%ldnotbeenfound!”,x);returnhead;}第27页/共36页9.2共用体共用体的类型说明和变量的定义方式和结构体的类型说明和变量定义的方式完全相同。不同的是:结构体变量中的成员各自占有自己的存储空间,而共用体变量中的所有成员占有同一个存储空间。第28页/共36页9.2.1共用体类型说明

共用体类型说明的一般形式为:

union

共用体名

{类型名1共用体成员名1;类型名2共用体成员名2;……类型名n共用体成员名n;};

例如:unionexam{ inta; floatb; charc;};第29页/共36页9.2.2共用体变量的定义

同结构体(三种方法)第30页/共36页9.2.3共用体变量的引用1.可以引用其成员

unionexam{ inta; floatb; charc;}x,y,a[5],*px;x.a=25;x.b=38.5;x.c=’A’;y.a=x.a;y.b=x.b;y.c=x.a;px=&x;px=a;2.可以将一个共用体变量的值整体赋值于另一个共用体变量例:y=x;a[0]=x;第31页/共36页9.2.4注意事项

1.共用体类型数据的多个成员共用一个内存段,但每一瞬时只有一个成员起作用。2.共用体变量中起作用的是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。3.共用体变量的地址和它的成员的地址都是同一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论