1 / 33

结构体与共用体

结构体与共用体. 结构体与共用体. 结构体 结构体是 一种 构造 数据类型 用途:把 不同类型 的数据组合成一个 整体 ------- 自定义 数据类型 结构体类型定义. 合法标识符 可省 : 无名结构体. struct [ 结构体名 ] { 类型标识符 成员名; 类型标识符 成员名; ……………. } ;. 成员类型可以是 基本型或构造型. struct 是 关键字 , 不能省略. 此处分号 ; 不能少. 结构体变量的定义 常用形式: 先定义结构体类型,再定义结构体 变量 一般形式:.

mitch
Download Presentation

结构体与共用体

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 结构体与共用体

  2. 结构体与共用体 结构体 • 结构体是一种构造数据类型 • 用途:把不同类型的数据组合成一个整体-------自定义数据类型 • 结构体类型定义 合法标识符 可省:无名结构体 struct [结构体名] { 类型标识符 成员名; 类型标识符 成员名; ……………. }; 成员类型可以是 基本型或构造型 struct是关键字, 不能省略 此处分号 ;不能少

  3. 结构体变量的定义 • 常用形式:先定义结构体类型,再定义结构体 变量 • 一般形式: struct结构体名 { 类型标识符 成员名; 类型标识符 成员名; ……………. }; struct结构体名变量名表列; 例 struct point { double x; double y; }; struct point A;

  4. 例 struct point { double x; double y; }; struct triangle { struct point A; struct point B; struct point C; }; • 说明 • 结构体类型与结构体变量概念不同 • 类型:不分配内存; 变量:分配内存 • 类型:不能赋值、存取、运算; 变量:可以 • 结构体可嵌套 • 结构体成员名与程序中变量名可相同,不会混淆 • 结构体类型及变量的作用域与生存期

  5. 低地址 2字节 s1 num name[0] 1字节 例 struct student { int num; char name[20]; int score[3]; }s1={1,”Zhang San”,80,90,100},s2; …….. …….. name[19] 2字节 score[0] score[1] 2字节 score[2] 2字节 高地址 结构体类型定义描述结构 的组织形式,不分配内存 图 7-1 结构体变量s1的存储结构

  6. 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; Stu2 = stu1; ( ) 成员(分量)运算符 优先级: 1 结合性:从左向右 结构体变量的引用 • 引用规则 • 结构体变量不能整体引用,只能引用变量成员 引用方式: 结构体变量名.成员名 • 可以将一个结构体变量赋值给另一个结构体变量 • 结构体嵌套时逐级引用

  7. 例 struct student { int num; char name[20]; int score[3]; }; struct student s1 = {1,“Zhang San”,85,90,100”}; 定义变量时就初始化 struct结构体名 { 类型标识符 成员名; 类型标识符 成员名; ……………. }; struct 结构体名结构体变量={初始数据}; 结构体变量的初始化 • 常用形式:

  8. 例 /*参考程序 7-1.c*/ #include <stdio.h> struct student { int num; char name[20]; int score[3]; }; main() { sturct student s1; int i,average; printf(“Input number:\n”); scanf(“%d”,&s1.num); gets(s1.name); ……} 结构体变量的初始化以及引用 定义变量后,再初始化 要给结构体里的变量依次赋值

  9. 形式二: struct student { int num; char name[20]; char sex; int age; }stu[2]; num num 形式一: struct student { int num; char name[20]; char sex; int age; }; struct student stu[2]; name name 25B stu[0] sex sex 定义结构体时同时定义变量 age age 形式三: struct { int num; char name[20]; char sex; int age; }stu[2]; stu[1] 先定义结构体,再定义变量 定义结构体时同时定义变量 结构体数组 • 结构体数组的定义 三种形式:

  10. 例 /*参考程序 7-2.c*/ #include <stdio.h> #define N 3 struct stu { int num; char name[20]; int score[4]; }; main() { int i,k,max; struct stu s[N]; printf(“Input data:\n”); for(i=0;i<N;i++) { scanf(“%d%s%d%d%d”,&(s[i].num), s[i].name ,&(s[i].score[0]), &(s[i].score[1]),&(s[i].score[2])); 结构体数组应用举例

  11. s[i].score[3]=(s[i].score[0]+s[i].score[1]+s[i].score[2])/3; s[i].score[3]=(s[i].score[0]+s[i].score[1]+s[i].score[2])/3; } printf(“\nAverage:”); for(i=0;i<N;i++) printf(“%d”, s[i].score[3]); max =s[0].score[3]; k =0; for (i=1;i<N;i++) if(s[i].score[3]>max) { k = i; max = s[i].score[3]; } printf (“\n The top student :”); printf (“%d,%s,%d, %d, %d,average:%d\n”,s[k].name, s[k].score[0], s[k].score[1], s[k].score[2], s[k].score[3]);} 结构体数组应用举例

  12. (*结构体指针).成员 结构体指针->成员 结构体变量.成员 指向运算符 -> 优先级: 1 结合方向:从左向右 存放结构体变量在内存的起始地址 结构体和指针 • 指向结构体变量的指针 • 定义形式:struct 结构体名*结构体指针名; 例 struct student *p; • 使用结构体指针变量引用成员形式

  13. #include <stdio.h> #define N 3 struct stu { int num; char name[20]; int score[4]; }; main() { int i,k,max; struct stu s[N],*p; printf(“Input data:\n”); for (p=s;p<s+N;p++) { scanf(“%d%s%d%d%d”,&p->num,p->name,&p->score[0], &p->score[1], &p->score[2]); 参考源程序7-3.c

  14. p->score[3]=(p->score[0]+p->score[1]+p->score[2])/3;} printf(“\nAverage:”); for(p=s;p<s+N;p++) printf(“%d”, p->score[3]); P=s; max =p->score[3]; k =0; for (p=s+1;p<s+N;p++) if(p->score[3]>max) { k = p-s; max = p->score[3]; } p=s+k; printf (“\n The top student :”); printf (“%d,%s,%d, %d, %d,average:%d\n”, p->num,p->name,p->score[0], p->score[1], p->score[2]);}

  15. (main) (main) (main) a :27 a :27 a :27 a :27 a :18 a :27 arg arg arg b: 3 b: 3 b: 3 b: 5 b: 3 b: 3 (main) c :30 c :30 c :30 c :30 c :30 c :90 arg (func) (func) parm parm 例 用结构体变量(变量名)作函数参数 struct data //定义结构体 { int a, b, c; }; main() { void func(struct data); struct data arg; //定义结构体变量,即实参 arg.a = 27; arg.b = 3; arg.c = arg.a+arg.b; printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); printf("Call Func()....\n"); func(arg); //将实参传给函数func,传变量名 printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); } void func(structdataparm) // 通过形参 parm能改变实参 arg吗? { parm.a = 18; parm.b = 5; parm.c = parm.a*parm.b; printf("parm.a=%d parm.b=%d parm.c=%d\n",parm.a,parm.b,parm.c); printf("Return...\n"); } copy

  16. (main) (main) (main) a :27 a :18 a :18 a :27 (func) (func) arg arg arg b: 5 b: 3 b: 3 b: 5 (main) parm parm **** **** c :30 c :90 c :30 c :90 arg 例 用结构体指针变量(变量地址)作函数参数 struct data //定义结构体 { int a, b, c; }; main() { void func(structdata *); struct data arg; //定义结构体变量,即实参 arg.a=27; arg.b=3; arg.c=arg.a+arg.b; printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); printf("Call Func()....\n"); func(&arg); //将实参传给函数func,传变量的地址 printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); } void func(structdata*parm) // 通过形参 parm能改变实参 arg吗? { parm->a=18; parm->b=5; parm->c=parm->a*parm->b; printf("parm->a=%d parm->b=%d parm->c=%d\n",parm->a,parm->b,parm->c); printf("Return...\n"); }

  17. i ch f 共用体 • 构造数据类型,也叫联合体 • 用途:使几个不同类型的变量共占一段内存(相互覆盖) • 共用体类型定义 定义形式: union 共用体名 { 类型标识符 成员名; 类型标识符 成员名; ……………. }; 例 union data { int i; char ch; float f; }; 类型定义不分配内存 最终占用4个字节

  18. i i ch ch f f a b • 共用体变量的定义 形式一: union data { int i; char ch; float f; }a,b; 形式二:(最常用) union data { int i; char ch; float f; }; union data a,b,c,*p,d[3]; 形式三:(无名) union { int i; char ch; float f; }a,b,c; 共用体变量任何时刻 只有一个成员存在 共用体变量定义分配内存, 长度=最长成员所占字节数

  19. 共用体变量名.成员名 共用体指针名->成员名 (*共用体指针名).成员名 • 共用体变量引用 • 引用方式:(同结构体) • 引用规则 • 不能引用共用体变量,只能引用其成员 • 共用体变量中起作用的成员是最后一次存放的成员 • 不能在定义共用体变量时初始化 • 可以用一个共用体变量为另一个变量赋值

  20. 高字节 低字节 01100001 01000001 ch[0] 01000001 ch[1] 01100001 例 将一个整数按字节输出 main() { union int_char { int i; char ch[2]; }x; x.i = 24897; printf("i=%d\n",x.i); printf("ch0=%c,ch1=%c\n", ,x.ch[0],x.ch[1]); } 运行结果: i = 24897 Ch0 = A,ch1 = a

  21. 枚举类型 • 定义:将变量的值一一列举出来,变量的值只限于列举出来的值的范围之内。 • 枚举类型定义 枚举元素 enum weekday {sun, mon, tue, wed, thu, fri, sat}; • 枚举变量定义 workday = mon;week_end = sun; enum weekday workday, week_end; enum{sun, mon, tue, wed, thu, fri, sat}workday, week_end;

  22. 说明:1、在C编译中,对枚举元素按照常量处理 sun = 0; mon = 1; (×) 原因:常量不能再被赋值 2、枚举元素是有值的,按定义时的顺序使它们为 enum weekday {sun, mon, tue, wed, thu, fri, sat}; sun ~ sat依次为:0, 1, 2, 3, 4, 5, 6 enum weekday {sun, mon = 8, tue, wed, thu = 100, fri, sat}; sun ~ sat 依次为:0, 8, 9, 10, 100, 101, 102 3、枚举值可以用来作判断比较。 if( workday == mon )… 4 、一个整数不能直接赋给一个枚举变量。 enum weekday i; i = 100; (×) i = wed; (√) //要用枚举元素来赋值

  23. #include <stdio.h> void main() { enum mon{Jan=1,Feb,Mar,Apr,May} mon1,mon2,mon3; enum mon *pm; pm=&mon3; mon1=Jan; printf(“Input mon2:\”); scanf(“%d”,&mon2); mon3=mon1+2; printf(“mon1=%d,mon2= %d,mon3=%d\n”,mon1,mon2,*pm); } 参考源程序7-6.c

  24. 用typedef定义类型 • 功能:用自定义名字为已有数据类型命名 • 类型定义简单形式: typedef type my_name; 用户定义的类型名 类型定义语句关键字 已有数据类型名 说明: 1.typedef 没有创造新数据类型 2.typedef 是定义类型,不能定义变量 3.typedef 与 define不同 definetypedef 预编译时处理编译时处理 简单字符置换 为已有类型命名

  25. typedef定义类型步骤 • 按定义变量方法先写出定义体 如 int i; • 将变量名换成新类型名 如 int INTEGER; • 最前面加typedef 如 typedef int INTEGER; • 用新类型名定义变量 如 INTEGER i,j; • 类型定义可嵌套 例 typedef struct club { char name[20]; int size; int year; }GROUP; typedef GROUP *PG; PG pclub; GROUP为结构体类型 PG为指向GROUP的指针类型  GROUP *pclub;  struct club *pclub;

  26. 单向链表 存放数据元素的结点包括两个域 用途:数据域(data)和指针域或链域(next) 单向链表表示(^表示NULL) 定义: Struct Ai { int a; struct Ai *next; }

  27. 建立动态链表 创建结点: malloc与calloc函数 • malloc • 函数原型:int *malloc(unsigned int size) • 功能:在内存中动态分配size个连续空间 • 返值:正常,返回空间地址; 出错,为NULL • callcc • 函数原型:int *calloc(unsigned n,unsigned int size) 功能:在内存分配N个连续长度为size的空间 返值:正常,返回空间地址; 出错,为NULL

  28. 节点链接到链表 pend a1 a2 an Head NULL ② ① a1 new NULL 新节点链接到链表末尾

  29. 链表的插入 a1 a2 an Head NULL ② ① an+1 an+1 new new NULL NULL a2 a1 an Head NULL ② ① ① pins 插入节点到头节点之前 插入节点到链表中间

  30. 链表的删除 BEGIN IF (待删除节点为头节点) head=head->next; ELSE 找到目标节点,并让prev指向待删除节点的前导节点; if (prve!=NULL) {pdel=prev->next; prev->next=pdel->next; free(pdel); } else print 没有找到要删除的节点; ENDIF return(head); END

  31. 链表的删除 /*参考源程序7-9*/ #include”Ex7-71.c” #include <stdio.h> Struct Ai *findprev(struct Ai *head,int a)/*从第2个开始查找*/ { struct Ai *prev,*pdel; prev=head; pdel=head->next; while(pdel->a!=a && prev->next!=NULL) { prev=pdel; pdel=pdel->next; } if (pdel->next!=NULL) return(prev); else return(NULL);}

  32. 链表的删除 /*参考源程序7-9*/ Struct Ai *delete(struct Ai *head,int a) {struct Ai *prev,*pdel; if (head->a==a) {head=head->next; printf(“The first node is deleted.\n”);} else {if ((prev=findprev(head,a))!=NULL) {pdel->next=pdel->next; free(p); printf(“Node(which number is %d)is deleted.\n”,a);} else printf(“Node(which number is %d)is not found.\n”,a);} return(head);}

  33. 链表的删除 /*参考源程序7-9*/ main() { struct Ai *head,*new,*p; int n=0; int a; head=create(); printf(“Input data for the node to be deleted:\n”); scanf(“%d”,&a); head=delete(head,a); printf(“Atfer the node is deleted:\n); output(head); }

More Related