Presentation is loading. Please wait.

Presentation is loading. Please wait.

白 雪 飞 中国科学技术大学电子科学与技术系 Dept. of Elec. Sci. & Tech., USTC Fall, 2007 第 8 章 结 构 体.

Similar presentations


Presentation on theme: "白 雪 飞 中国科学技术大学电子科学与技术系 Dept. of Elec. Sci. & Tech., USTC Fall, 2007 第 8 章 结 构 体."— Presentation transcript:

1 白 雪 飞 baixf@ustc.edu.cn 中国科学技术大学电子科学与技术系 Dept. of Elec. Sci. & Tech., USTC Fall, 2007 第 8 章 结 构 体

2 C 语言程序设计 - 第 8 章 结构体 2 目 录 结构体 结构体数组 指向结构体的指针 定义类型别名 动态存储分配函数 结构体的应用 — 链表

3 C 语言程序设计 - 第 8 章 结构体 3 结构体 (Structure) 结构体概述 结构体类型的声明 结构体变量的定义 结构体变量的初始化 结构体变量的引用

4 C 语言程序设计 - 第 8 章 结构体 4 结构体概述 结构体 将不同类型的数据组合成一个整体 用来表示简单类型无法描述的复杂对象 可以用结构体来定义用户自己的数据结构 举例 描述学生信息 numnamesexagescoreaddr 12039Bill GatesM4076.5New York

5 C 语言程序设计 - 第 8 章 结构体 5 结构体类型的声明 一般形式 struct [ 结构体名 ] { 成员表列 }; “ 成员表列 ” 形式 类型 成员名 ;......

6 C 语言程序设计 - 第 8 章 结构体 6 结构体类型声明的说明 (1) 声明了一种类型,而不是定义变量 结构体名可以没有,但是这样就无法再 次使用该结构体类型了 成员表列中是成员 (Member) 的定义 成员的定义形式与变量定义相同 成员类型可以是另一结构体类型,但不 可直接或间接递归嵌套 成员表列不可为空,至少要有一个成员

7 C 语言程序设计 - 第 8 章 结构体 7 结构体类型声明的说明 (2) 注意 {} 不表示复合语句,其后有分号 同一结构体的成员不能重名 不同结构体的成员可以重名 结构体成员和其他变量可以重名 结构体类型名称是 struct 结构体名, 注意 struct 关键字不能省略 结构体类型也要 “ 先声明,后使用 ”

8 C 语言程序设计 - 第 8 章 结构体 8 结构体类型声明的说明 (3) 即使两个结构体声明中的成员类型、名 称、顺序都完全一致,它们也是不同的 类型 如果结构体类型声明在函数内部,则该 函数之外无法引用此结构体类型 一般把结构体类型声明放到文件最前面 也可以把结构体类型声明放在头文件里

9 C 语言程序设计 - 第 8 章 结构体 9 结构体类型的声明举例 struct student { unsigned num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ unsigned age; /* 年龄 */ float score; /* 分数 */ char addr[50]; /* 地址 */ };

10 C 语言程序设计 - 第 8 章 结构体 10 结构体变量的定义 (1) 先声明结构体类型再定义变量 struct student { unsigned num; char name[20]; char sex; unsigned age; float score; char addr[50]; }; struct student stu1, stu2;

11 C 语言程序设计 - 第 8 章 结构体 11 结构体变量的定义 (2) 在声明结构体类型的同时定义变量 struct student { unsigned num; char name[20]; char sex; unsigned age; float score; char addr[50]; } stu1, stu2;

12 C 语言程序设计 - 第 8 章 结构体 12 结构体变量的定义 (3) 直接定义无名结构类型变量 struct { unsigned num; char name[20]; char sex; unsigned age; float score; char addr[50]; } stu1, stu2;

13 C 语言程序设计 - 第 8 章 结构体 13 结构体声明和变量定义举例 struct date { int year, month, day; }; struct student{ unsigned num; char name[20]; char sex; struct date birthday; float score; } stu1, stu2;

14 C 语言程序设计 - 第 8 章 结构体 14 结构体变量的初始化 按照成员的顺序和类型对成员初始化 struct date date1 = {1984, 10, 20}; struct student stu = { 1001, /*unsigned num*/ "Tom", /*char name[20]*/ 'M', /*char sex*/ {1983, 9, 20},/*struct date birthday*/ 93.5 /*float score*/ };

15 C 语言程序设计 - 第 8 章 结构体 15 结构体变量中成员的引用 一般形式 结构体变量名. 成员名 成员运算符. 具有最高的优先级,自左向右结合 说明 结构体成员和同类型的变量用法相同 若成员类型又是一个结构体,则可以使用若 干个成员运算符,访问最低一级的成员

16 C 语言程序设计 - 第 8 章 结构体 16 结构体变量中成员的引用举例 struct student stu;... scanf("%f", &stu.score); stu.num = 12345; stu.birthday.month = 11; stu.score = sqrt(stu.score) * 10; strcpy(stu.name, "Mike"); printf("No.%d:", stu.num);

17 C 语言程序设计 - 第 8 章 结构体 17 结构体变量整体引用 结构体类型变量之间可以直接相互赋值 实质上是两个结构体变量相应的存储空间中 的所有数据直接拷贝 包括复杂类型在内的所有结构体成员都被直 接赋值,如字符串、结构体类型等 函数的实参和形参可以是结构体类型, 并且遵循实参到形参的单向值传递规则 为了提高程序的效率,函数的参数多使 用结构体类型指针

18 C 语言程序设计 - 第 8 章 结构体 18 结构体变量整体引用举例 struct student stu1, stu2={1002, "Kate", 'F', {1981, 11, 4}, 89.0}; void print(struct student s) { printf("%d,%4s,%c,%d.%02d.%02d,%4.1f\n", s.num, s.name, s.sex, s.birthday.year, s.birthday.month, s.birthday.day, s.score); } int main () { stu1 = stu2; /* 直接赋值 */ print(stu1); /* 1002,Kate,F,1981.11.04,89.0 */ }

19 C 语言程序设计 - 第 8 章 结构体 19 结构体数组 结构体数组的用法与基本类型数组类似 定义、初始化、引用等 结构体数组可用于表示二维表格 举例 struct student s[10]; for (i=0; i<10; i++) scanf("%d,%s,%c,%d,%f", &s[i].num, s[i].name, &s[i].sex, &s[i].age, &s[i].score);

20 C 语言程序设计 - 第 8 章 结构体 20 结构体数组初始化及应用举例 struct student stu[] = { {1001,"Tom",'M',{1980,1,2},85.5}, {1002,"Kate",'F',{1981,11,4},89.0}, {1003,"Mike",'M',{1980,3,5},95.5}}; for (i=0; i<3; i++) printf("%d,%4s,%c,%d.%02d.%02d,%4.1f\n", stu[i].num, stu[i].name, stu[i].sex, stu[i].birthday.year, stu[i].birthday.month, stu[i].birthday.day, stu[i].score);

21 C 语言程序设计 - 第 8 章 结构体 21 结构体数组与二维表 numnamesex birthday score yearmonthday s[0]1001TomM19801285.5 s[1]1002KateF198111489.0 s[2]1003MikeM19803595.5 s[3]1004JohnM198181373.0 s[4]1005LilyF19813681.0 struct student s[5]; 结构体

22 C 语言程序设计 - 第 8 章 结构体 22 指向结构体的指针 指向结构体的指针 定义、使用与其他基本类型指针类似 可以使用指向运算符 ( -> ) 引用指针所指向的 结构体的成员 指向运算符 -> 结构体指针 -> 成员名 具有最高的优先级,自左向右结合 若 struct student stu, *p=&stu; 则 stu.num 、 (*p).num 、 p->num 等效

23 C 语言程序设计 - 第 8 章 结构体 23 指向结构体数组的指针 指向结构体数组的指针 与指向其他基本类型数组的指针用法类似 注意相关运算符的结合方向和优先级 举例 struct student stu[10], p=stu; ++p->num; /* 同 ++(p->num); */ p++->num; /* 同 (p++)->num; */ (++p)->num; (p++)->num;

24 C 语言程序设计 - 第 8 章 结构体 24 结构体指针作函数参数举例 void input(struct student *p) { scanf("%d %s %c %d.%d.%d %f", &p->num, p->name, &p->sex, &p->birthday.year, &p->birthday.month, &p->birthday.day, &p->score); } int main () { struct student stu[20]; int i; for (i=0; i<20; i++) input(stu+i); }

25 C 语言程序设计 - 第 8 章 结构体 25 定义类型别名 一般形式 typedef 举例 typedef float REAL; typedef struct { int month; int day; int year; } DATE;

26 C 语言程序设计 - 第 8 章 结构体 26 动态存储分配函数 动态分配存储 根据需要开辟或释放存储单元 相关函数 malloc 函数 calloc 函数 free 函数 说明 应包含 malloc.h 或 stdlib.h

27 C 语言程序设计 - 第 8 章 结构体 27 malloc 函数 函数原型 typedef unsigned size_t; void *malloc(size_t size); 参数 size: 分配存储空间的字节数 返回值 若成功,返回指向分配区域起始地址的指针 若失败,返回 NULL

28 C 语言程序设计 - 第 8 章 结构体 28 calloc 函数 函数原型 void *calloc(size_t n, size_t size); 参数 n : 分配内存的项目数 size: 分配内存的每个项目的字节数 返回值 若成功,返回指向分配区域起始地址的指针 若失败,返回 NULL

29 C 语言程序设计 - 第 8 章 结构体 29 free 函数 函数原型 void free(void *ptr); 参数 ptr: 要释放的内存区地址 说明 释放 ptr 指向的内存区 释放后的内存区能够分配给其他变量使用

30 C 语言程序设计 - 第 8 章 结构体 30 结构体的应用 — 链表 (Link List) a1a1 a1a1 a2a2 a2a2 a3a3 a3a3... anan anan ^ ^ head struct node data next aiai aiai struct node { int data; struct node *next; }; struct node *head; struct node { int data; struct node *next; }; struct node *head;

31 C 语言程序设计 - 第 8 章 结构体 31 链表的操作 链表的建立 从链尾到链头:新结点插入到链头 从链头到链尾:新结点插入到链尾 链表的遍历 删除结点 根据一定的条件,删除一个或多个结点 插入结点 根据一定的条件,把新结点插入到指定位置

32 C 语言程序设计 - 第 8 章 结构体 32 建立链表 ( 从链尾到链头 ) head a i-1... ④ head = p; ② p = malloc(sizeof (struct node));  p->data = a[i]; ② p = malloc(sizeof (struct node));  p->data = a[i]; ① for(i=0; i<n; i++) p p aiai aiai ③ p->next = head;

33 C 语言程序设计 - 第 8 章 结构体 33 建立链表 ( 从链头到链尾 ) a i-1 ^ ^... ④ p->next = q; ② q = malloc(sizeof (struct node));  q->data = a[i]; ② q = malloc(sizeof (struct node));  q->data = a[i]; ① for(i=0; i<n; i++) aiai aiai ^ ^ q q ③ q->next = NULL; p p ⑤ p = q;

34 C 语言程序设计 - 第 8 章 结构体 34 遍历链表... a i-1 aiai aiai a i+1... ③ p = p->next; p p ① while(p) ② printf("%d", p->data);

35 C 语言程序设计 - 第 8 章 结构体 35 删除结点... a i-1 aiai aiai a i+1... ③ p->next = q->next; ④ free(q); ② q = p->next; p p q q ① if(p->next 满足删除条件 )

36 C 语言程序设计 - 第 8 章 结构体 36 插入结点... aiai aiai a i+1... ④ p->next = q; ② q = malloc(sizeof (struct node));  q->data = x; ② q = malloc(sizeof (struct node));  q->data = x; p p ① if(p 满足插入条件 ) q q x x ③ q->next = p->next;

37 C 语言程序设计 - 第 8 章 结构体 37 链表操作中需要注意的几个问题 注意考虑几个特殊情况下的操作 链表为空表 (head==NULL) 链表只有一个结点 对链表的第一个结点进行操作 对链表的最后一个结点进行操作 最后一个结点的 next 指针应为 NULL 可以定义一个结构体类型用于表示结点 的数据部分,以便于对数据的操作

38 C 语言程序设计 - 第 8 章 结构体 38 结束 The End


Download ppt "白 雪 飞 中国科学技术大学电子科学与技术系 Dept. of Elec. Sci. & Tech., USTC Fall, 2007 第 8 章 结 构 体."

Similar presentations


Ads by Google