文档介绍:结构体与联合体:高级概念
吴清锋
2007年秋
提纲
指向结构体类型数据的指针
用指针处理链表
链表概述
简单链表(静态链表)
处理动态链表所需的函数
动态链表的处理
用typedef定义类型
运算符小结
结束
指向结构体类型数据的指针(1)
概述
结构体变量的指针就是该变量所占据的内存段的起始地址。
可以定义一个指针变量来指向一个结构体变量。
指针变量可以用来指向结构体数组中的元素。
定义结构体指针变量的一般形式是(回顾下之前如何定义?)
struct 结构体类型* 结构体指针名务必注意每一部分的含义
通过结构体指针变量访问相应结构体成员
(* 结构体指针名).分量
指向运算符->
优先级、
结构体指针名->分量
总结下三种访问成员的三种形式。尤其是,使用*和->的对象都是指针变量,但是书写上一定要注意差异!
例子()
指向结构体类型数据的指针(2)
用结构体类型数据的指针来访问结构体数组。
,一定要注意p++的含义!
p是一个指向结构体类型的指针变量,因此赋值的时候要门当户对!否则就要进行强制类型的转换!
函数参数问题—传递结构体入函数(注意门当户对!)
将结构体变量的各个分量分别对应一个参数传递;
将结构体变量整体作为实参进行传递;
比较
(p++)->num P291
(++p)->num P291
++(p->num)
++p->num P290
p->num++ P290
返回
链表概述(1)
用数组存储一批数据时,必须事先定义固定的长度。当事先并不很确定时,就只能定义长度为足够大。这样很浪费空间。
数组之所以要事先定义固定的长度,目的是先分配好空间以为保证各元素之间的连续性。
如果长度不固定必然要求空间是动态分配的。这就带来一个问题:各个元素之间不一定能分配到相邻空间。如此,每个元素中都必须有一个指针能指向下一个元素。
链表是一种常见而又重要的数据结构,是动态地进行存储分配的一种结构。
简单链表的模型P294
链表的特点:链表中元素可以不连续存放
在链表结构中随机访问元素比较麻烦。
头指针
头结点
尾结点
尾结点的标志是其“后向指针”的值为NULL
,值为0。
链表概述(2)
结构体变量用来表示链表结构最合适。Why?
可定义一个自引用的结构体以表示链表结点
例:struct student{ long num; float score; struct student * next;}; 一定要深刻理解其含义,这是一个基本操作!
注意,下面是错的: 为什么呢?会造成无穷尽现象! struct student{ long num; float score; struct student next;};
注意:上面只是定义了一个结构体类型,还没有实际分配空间,也就没有所谓的链表!
返回
处理动态链表所需的函数(1)
学习的时候,注意:
函数的功能,输入和输出情况!
这里是定义函数,而不是定义指向函数的指针!
malloc
#include <>
void * malloc (size_t size);
calloc
#include <>
void * alloc (size_t nelem, size_t elsize);
free
#include <>
void free (void * block);
处理动态链表所需的函数(2)
void *是ANSI中引进的,用来表示通用指针
malloc时的强制类型转换(P277)main(){ char * name; name=(char *)malloc(10); strcpy(name, "Zhang San"); printf("%s", name); free(name);}
返回
链表的相关操作(1)
静态链表(简单链表)
程序的实现的几个关键步骤:
借助变量,构造空间和值
建立变量间关系
通过指针变量来访问链表中的每个节点
例子:
=NULL的作用
p=p->next;的含义,就是实现了“接力”!
链表的相关操作(2)
动态链表
注意:
都是基本操作!应该熟记!
初学时一定要思考每一语句的顺序和存在的意义!
一定要考虑多个节点的处理!
可能有的问题只需要用p1而有的用p2,需要思考必要性
动态链表的操作
动态链表的建立和输出
对链表中节点的删除和插入
注意:上面的各个操作只有提供了若干子函数,需要构造一个主函