结构体、共用体、用户自定义_第1页
结构体、共用体、用户自定义_第2页
结构体、共用体、用户自定义_第3页
结构体、共用体、用户自定义_第4页
结构体、共用体、用户自定义_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

1、结构体、共用体、用户自定义类型int、char、float、double等都是系统预定义的标准数据类型。程序员用这些类型声明符声明需要的变量,系统就会为它们分配相应的存储空间,按特定的存储方式进行存储,并在有关运算符作用于这些数据时进行合法性检查。除此之外,C语言还允许程序员在一定的框架范围内定制需要的数据类型。声明了类型之后,程序员就可以使用它们来定义需要的变量,如同使用系统提供的int、char、float、double等一样。C语言允许程序员定制的数据类型是在下面的5种类型框架内进行。这5种框架分别是: 结构体(struct):也称集合数据类型,用于将不同类型的数据组织在一个名字下 共用

2、体(union):允许一个存储空间中存储不同类型的变量。 typedef:用于为已经存在的类型定义新名字。一、 用typedef定义类型 Typedef 类型名 标识符1、 简单的名字替换typedef int INTEGER; 意思是将int型定义为INTEGER,这二者等价,在程序中就可以用INTEGER作为类型名来定义变量了。INTEGER a,b;/*相当于int a,b;*/ 定义a,b为INTEGER类型,也即int类型。下面是一个解释例: 首先按通常定义变量的方法定出定义的主体char *p; 将变量名换成新类型名:char *CHAR;在量后面加上关键字typedef;type

3、def char *CHARP 可以用新类型名定义变量了:CHARP p;二、结构体类型1、定义结构变量的一般格式为: struct 结构名 类型变量名; 类型变量名; . 结构变量; 结构名是结构的标识符不是变量名 例如: struct date int y,month,day;说明: 结构体类型名不仅可以是简单数据类型,也可以是构造类型,当然也可以是基种结构体类型。当结构体说中又包含结构体时,称其为结构体的嵌套。如下:struct studentchar name12;char sex;struct date birthday;float sc4;若没的事先说明这一类型,以上结构类型说明可

4、改定为如下形式: struct studentchar name12;char sex;struct date int y,month,day;birthday;float sc4;建立通信录定制一种数据类型struct Addr:truct Addr char name30; /* 姓名 */ char street40;/* 街道 */ char city20;/* 城市 */ char provn20;/* 省名 */ unsigned int zip; /* 邮编 */2、 结构体类的变量、数组和指针变量和定义可以用以下四种方法定义结构体类型的变量、数组和指针变量。紧跟在结构体类型说明

5、之后说进行定义。struct student char name12; char sex;struct date birthday;float sc4;std,pers3,*pstd;在说明一个无名结构体类型的同时,直接进行定义;如: struct char name12; char sex;struct date birthday;float sc4;struct std,pers3,*pstd;先说明结构体类型,再单独进行变量定义。 struct student char name12; char sex;struct date birthday;float sc4;struct stud

6、ent std,pers3,*pstd; 使用typedef说明一个结构体类型名,再用新类型来定义变量。 3、 定义结构体类型变量及对变量的初始化 定制一个结构体类型后,得到一个结构体类型名。有了这个类型名,就可以像int、char、float和double一样,用来定义一些结构体类型的变量。定义了变量,系统就会为变量分配存储空间。 1. 定义结构体变量可以采用不同的方法定义一个结构体类型的变量。(1)在定义了一个结构体类型之后,把变量定义为该类型。如有以下声明:struct Student stdnt1, stdnt2, stdnt3; 定义了stdnt1、stdnt2,和stdnt3三个s

7、truct Student类型的结构体变量。注意不能写成:struct Student ,stdnt1, stdnt2, stdnt3;/* 错误逗号 */也不能写成Student stdnt1, stdnt2, stdnt3; /* 缺少关键字struct 结构体变量的初始化在定义了结构体变量之后,stdnt1, stdnt2, stdnt3等就具有struct Student结构体类型的特征 ,也有了变量的特征。但是,这些变量不是简单变量,它们的值也不是一个简单的整数、实数或字符等,而是由许多个基本数据组成的复合的值。例如,stdnt1、stdnt2和stdnt3的值可以有如图7.1所示的

8、值 那么,如何对结构体变量进行初始化呢?与简单变量的初始化类似,结构体变量的初始化应当在变量定义时进行,并且要把初始值依次写在一对花括号内,用赋值运算符赋值给对应的变量。如struct Student unsigned int num; char name20; char sex; int age; float score; char addr30; stdnt1=50201,”ZhangXi”,M,18,90.5,”Shanghai”, stdnt2=50202,”WhangLi”,F,19,88.3,”Beijing”; 也可以用以下形式Struct Student stdnt3=5020

9、3,”LiHong”,M,17,79.9,”Shanxi”;/* ex070101 */struct Student unsigned int num; char name20; char sex; unsigned char age; float score;#include int main(void)struct Student student1=50201,“WangLi”,M,18,89.5;struct Student student2;student2=student1;/* 结构体变量间赋值 */printf (“student1: %u,%s,%c,%u,%5.2fn”, s

10、tudent1.num,,student1.sex,student1.age,student1.score);printf (“student2: %u,%s,%c,%u,%5.2fn”, student2.num,,student2.sex,student2.age,student2.score);return 0; 在执行“student2=student1;”这个赋值语句时,将student1变量中各个成员逐个依次赋给student2中相应各个成员。显然,这两个结构体变量的类型应当相同才行。 注意:不允许用赋值语句将一组常量直接赋给一个

11、结构体变量。如下面语句不合法:student1=50203,“WangLong“,19,F,89.5;4、 引用结构体变量中的数据结构体变量名.成员名指针变量名- 成员名(*指针变量名).成员名使用指向结构体变量的指针引用结构体变量的成员/* ex070801 */#include #include struct StudTypechar name16;long num;int age;char sex;float score; ;int main(void)struct StudType student,*p;/* 使用结构体变量引用成员 */ strcpy (,Wa

12、ng Li); student.num=50101; student.age=18; student.sex=m; student.score=89.5;/* 使用指向结构体变量的指针引用成员 */ p=& student; printf (nname:%snnumber:%1dnage:%dnsex:%cnscore:%6.2fn, (*p).name,(*p).num,(*p).age,(*p).sex,(*p).score); return 0;5、 相同类型结构体变量之间的数据传递例:Struct Char name10;Int num;per1,per2=“YANGGM”,46;赋值

13、:per1=per26、 函数之间结构体变量的数据传递 向函数传递结构体变量中单个成员的数据 向函数传递整个结构体变量中的数据 传递结构体变量的地址#include typedef structchar s10;int t;ST;getdata(ST*p)scanf(%s%d,p-s,&p-t);main()ST a;getdata(&a);printf(%s,%dn,a.s,a.t); 向函数传递结构体名#include typedef structint num;double mark;REC;void sub1(REC x)x.num=23;x.mark=81.5;void sub2(R

14、EC y)y0.num=12;y0.mark=77.5;main()REC a=16,90.0,b=16,90.0;sub1(a);printf(A)%d,%5.1lfn,a.num,a.mark);sub2(b);printf(B)%d,%5.1lfn,b0.num,b0.mark); 函数的返回值是结构体类型#include typedef structint a;char b;ST;ST fun(ST x)x.a=99;x.b=S;return x;void main()ST y;y.a=0; y.b=A;printf(y.a=%dy.b=%cn,y.a,y.b);y=fun(y);pr

15、intf(y.a=%dy.b=%cn,y.a,y.b); 函数的返回值可以是指向结构体变量的指针类型#include typedef structint a;char b;ST;ST *fun(ST x)ST *px;x.a=100;x.b=C;px=&x;return px;void main()ST y,*p;y.a=999;y.b=X;printf(y.a=%dy.b=%cn,y.a,y.b);p=fun(y);printf(*p).a=%d(*p).b=%cn,(*p).a,p-b);输入3个学生的信息并将它们输出/* ex070701 */#include #include #def

16、ine StuNUM 3struct StudType char name16; longnum; int age; charsex; float score; int main(void) struct StudType stuStuNUM; int i; char ch; char numstr16;/* 输入数据 */for (i=0;iStuNUM;i+) printf (nenter all data of stu%d:n,i); gets (); gets (numstr);stui.num=atol (numstr); gets (numstr);stui.ag

17、e=atoi(numstr); stui.sex=getchar(); ch=getchar(); gets (numstr);stui.score=atof(numstr);/* 输出数据 */ printf (n record name t t numtagetsextscoren); for (i=0;iStuNUM;i+) printf (%dt%-16s%-8d%dt%-ct%6.2fn,i,, stui.num,stui.age,stui.sex,stui.score); return 0;/* ex070702 */#include #include #defi

18、ne StuNUM 3struct StudType Char name16; longnum;int age;charsex;float score; ;int main(void) struct StudType stuStuNUM,*p; int i; char numstr16; /* 输入数据 */ for (i=0,p=stu;pname); gets (numstr);p-num=atol (numstr); gets (numstr);p-age=atoi (numstr); p-sex=getchar( );getchar( ); gets (numstr);p-score=

19、atof (numstr); /* 输出数据 */ printf (n record name t t numtagetsextscoren); for (i=0,p=stu;pname,p-num,p-age,p-sex,p-score); return 0;三、利用结构体变量构成的链表 1、结构体中含的可以指向本结构体的指针成员当一个结构体中的一个或多个成员的基类型就是本结构体类型时,通常把这种结构体称为可以“引用自身的结构体”。例: Struct link Char ch; Struct link *p;a;链表(link)是指将若干个数据(每一个数据组称为一个“节点”)按一定的原则连接

20、起来的数据结构。图7.7为一个简单链表的示意图。Wang Li5020189.5124502412449601244960Li Ling502039812449921245024Zhang Fun5020290.512450561244992Chen Bo5020580.5NULL1245056headWang Li5020189.5124499212449601244960Li Ling502039812449921245024Zhang Fun5020290.512450561244992Chen Bo5020580.5NULL1245056head1、 一个简单的链表 定义3个节点和一个

21、头指针 */ struct StudNode stud1,stud2,stud3,*head;/* 为3个节点中的数据部分赋值 */ stud1.num=89101;stud1.score=89.5; stud2.num=89102;stud2.score=90.5; stud3.num=89103;stud3.score=94.5;/* 为各指针赋值,形成链接关系 */ head=&stud1; /* 使头指针指向第一个节点*/stud1.next=&stud2; /* 使第1个节点指向第2个节点*/stud2.next=& stud3; /* 使第2个节点指向第3个节点*/stud3.ne

22、xt=NULL; /* 使使第3个节点指向空,形成链位尾*/2、 动态链表的建立方法 与数组相比,链表具有插入和删除方便的特点。但是,按照上面的方法建立的链表并没有能够充分体现出链表的优势。因为使用链表,就是希望能够方便地进行节点的插入和删除。而采用上述的方法对链表进行操作时,实际上需要生成所有的节点,程序的作用是把它链接在链表中。如果将某一节点从链表中删除,它所占用的存储空间仍然保留在内存中,在于程序运行的始终。而且节点总数若变化了,必须修改程序。使用起来不太方便。这种链表称为静态链表。采用动态链表可以克服这些不足。 所谓动态链表,就是在程序运行过程中能从无到由有地建立链表,如果要把一个节点

23、插入到链表中,就临时为其分配空间。如果把一个节点从链表中删除,就释放其所占的空间。为了能动态地开辟和释放内存单元,要用到C标准库函数库中内存动态分配函数。 与数组相比,链表具有插入和删除方便的特点。但是,按照上面的方法建立的链表并没有能够充分体现出链表的优势。因为使用链表,就是希望能够方便地进行节点的插入和删除。而采用上述的方法对链表进行操作时,实际上需要生成所有的节点,程序的作用是把它链接在链表中。如果将某一节点从链表中删除,它所占用的存储空间仍然保留在内存中,在于程序运行的始终。而且节点总数若变化了,必须修改程序。使用起来不太方便。这种链表称为静态链表。采用动态链表可以克服这些不足。 与数

24、组相比,链表具有插入和删除方便的特点。但是,按照上面的方法建立的链表并没有能够充分体现出链表的优势。因为使用链表,就是希望能够方便地进行节点的插入和删除。而采用上述的方法对链表进行操作时,实际上需要生成所有的节点,程序的作用是把它链接在链表中。如果将某一节点从链表中删除,它所占用的存储空间仍然保留在内存中,在于程序运行的始终。而且节点总数若变化了,必须修改程序。使用起来不太方便。这种链表称为静态链表。采用动态链表可以克服这些不足。3、 单向链表每个结点都有两部分组成:一个是整型的成员,一个是指向自身结构的指针类型成员(1) 建立带头结点单向链表步骤如下: 读取数据 生成新结点 将数据存入结点的

25、成员变量中。 将新结点插入到链表中。 输出全部数据的函数ListAll(2) 输出全部数据的函数ListAll一个链表输出函数。void DispLink(struct StudNode *head)struct StudNode *thisP=head;int i=0;doprintf (nrecord number %dn,+i);printf (name:%sn,thisP-name);printf (num:%ldn,thisP-num);printf (score:%6.2fn,thisP-score);thisP=thisP-next;/* 一个节点数据输出完,thisPp指向下一

26、节点*/ while (thisP !=NULL); /*打印完最后一个节点不再打印*/一个链表节点的删除函数。struct StudNode *DelNode(struct StudNode *head,long StuNum)struct StudNode *p1,*p2; /* 定义临时指针*/* 考虑是空链表的情形 */if(head=NULL)printf(“nNo Linked Table”);return (head);/* 考虑是非空链表的情形 */p1=head; /* 从链表头开始找 */while(StuNum!=p1-num & next!=NULL) /* 没有找到并

27、不到表尾 */p2=p1; /* 临时保留p1中的地址*/p1=p1-next; /* p1指向下一节点*/if(StuNum=p1-num) /* 若是找到而退出循环结构*/if(p1=head) /* 如果是第1个节点*/head=p1-next; /* 将头指针指向第2个节点 */else /* 若是当前节点 */p2-next=p1-next; /* 将前一节点指向下一节点 */free(p1); /* 撤销所分配的存储空间 */printf(“delete the node”); /* 输出已删除信息*/else /* 不是因找到而退出循环*/printf(“nNot found t

28、he Node”); /* 显示找不到信息*/return head; /* 函数返回*/程序1:学生的记录由学号和成绩组成。N名学生的数据已放入主函数中的结构体数组s中,请编写函数fun,其功能是:把高于等于平均分的学生数据放在b所指的数组中,高于等于平均分的学生人数通过形参n传回,平均分通过函数值返回。#include #define N 12typedef struct char num10; double s; STREC;double fun( STREC *a, STREC *b, int *n ) int i; double av=0.0; *n=0; for(i=0;iN;i+

29、) av=av+ai.s; av=av/N; for(i=0;iN;i+) if(av=ai.s) b*n=ai;*n=*n+1; return av;main() STREC sN=GA05,85,GA03,76,GA02,69,GA04,85,GA01,91,GA07,72,GA08,64,GA06,87,GA09,60,GA11,79,GA12,73,GA10,90; STREC hN, t; int i,j,n; double ave; ave=fun( s,h,&n ); printf(The %d student data which is higher than %7.3f:n,

30、n,ave); for(i=0;in; i+) printf(%s %4.1fn,hi.num,hi.s); printf(n); for(i=0;in-1;i+) for(j=i+1;jn;j+) if(hi.shj.s) t=hi ;hi=hj; hj=t; 程序2:学生的记录由学号和成绩组成,N名学生的数据已放入主函数中的结构体数组s中,请编写函数fun,其功能是:按分数降序排列学生的记录,高分在前,低分在后。#include #define N 16typedef struct char num10; int s; STREC;void fun( STREC a )int i,j; S

31、TREC t; for(i=1;iN;i+) for(j=0;jN-1;j+) if(aj.saj+1.s) t=aj;aj=aj+1;aj+1=t;main() STREC sN=GA005,85,GA003,76,GA002,69,GA004,85,GA001,91,GA007,72,GA008,64,GA006,87,GA015,85,GA013,91,GA012,64,GA014,91,GA011,66,GA017,64,GA018,64,GA016,72; int i; fun( s ); printf(The data after sorted :n); for(i=0;iN; i

32、+) if( (i)%4=0 )printf(n); printf(%s %4d ,si.num,si.s); printf(n); 程序3:学生的记录由学号成绩组成,N名学生的数据已放入主函数中的结构体数组s中,请编写函数fun,其功能是:函数返回该学号的学生数据,指定的学号在主函数中输入。若没找到指定学号,在结构体变量中给学号置空串,给成绩置1,作为函数值返回。(用于字符串比较的函数是strcmp)。#include #include #define N 16typedef struct char num10; int s; STREC;STREC fun( STREC *a, char

33、*b )int i; STREC str=0,-1; for(i=0;iN;i+) if(strcmp(ai.num,b)=0) str=ai; return str; main() STREC sN=GA005,85,GA003,76,GA002,69,GA004,85,GA001,91,GA007,72,GA008,64,GA006,87,GA015,85,GA013,91,GA012,64,GA014,91,GA011,77,GA017,64,GA018,64,GA016,72; STREC h; char m10; int i; printf(The original data:n);

34、 for(i=0; iN; i+) if(i%4=0) printf(n); printf(%s %3d ,si.num,si.s); printf(nnEnter the number: );gets(m); h=fun( s,m ); printf(The data : ); printf(n%s %4dn,h.num,h.s); printf(n); h=fun(s,GA013); 程序4:学生的记录由学号和成绩组成,N名学生的数据已放入主函数中的结构体数组s中,请编写函数fun,其功能是:把分数最高的学生数据放在b所指的数组中。注意:分数最高的学生可能不止一个,函数返回分数最高的学生的

35、人数。#include #define N 16typedef struct char num10; int s; STREC;int fun( STREC *a, STREC *b )int i,j=0,max=a0.s; for(i=0;iN;i+) if(maxai.s) max=ai.s; for(i=0;iN;i+) if(max=ai.s) bj+=ai; return j;main() STREC sN=GA05,85,GA03,76,GA02,69,GA04,85,GA01,91,GA07,72,GA08,64,GA06,87,GA015,85,GA013,91,GA012,6

36、4,GA014,91,GA011,77,GA017,64,GA018,64,GA016,72; STREC hN; int i,n; n=fun( s,h ); printf(The %d highest score :n,n); for(i=0;in; i+) printf(%s %4dn,hi.num,hi.s); printf(n); 程序5:某学生的记录由学号、8门课程成绩和平均分组成,学号和8门课程的成绩已在主函数中给出,请编写函数fun,其功能是:求出该学生的平均分,并放入记录的ave成员中。例如,学生的成绩是:85.5,76,69.5,85,91,72,64.5,87.5,则他的平均分应为78.875。#include #define N 8typedef st

温馨提示

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

评论

0/150

提交评论