自引用主要是用来构成链表.结构体可含有指向本结构体的指针成员.
自引用:当一个结构体中有一个或是多个成员是指针,它们的基类型就是本结构体类型时,通常这种结构体称为"引用自身的结构体".
struct link
{
char ch;
struct link* p;
};
链表:把同一类型的结构体变量连在一起;
结点:链表中的结构体变量;
静态链表:由系统在内存中开辟一块固定大小的,互不连续的存储单元,在程序执行过程中,结点不能人为的添加,也不能人为的消失.
补充:数组的内存单元是连续的.如果有指向首地址的指针p,那么p++就会指向下一个单元,这个操作是有意义的.但是对于链表来说,指向链表结点的指针如果自增操作,那么对链表来说,是没有意义的,它的存储单元不是连续的,访问下一结点,要用到结构体的自引用.p=p->next;
1>静态链表的构建:
///静态链表//
struct node
{
int data;
struct node *next;
};
void nodelink()
{
struct node a,b,c,d,*h,*p;
a.data=10;b.data=20;c.data=30;d.data=40;
a.next=&b;b.next=&c;c.next=&d;d.next='/0';
h=&a;
p=h;
while(p)
{
printf("%d/n",p->data);
p=p->next;
}
}
在静态链表中,每一个结点都是有名字的,可以能过名字来访问它们.并且链表的长度固定.
动态链表:链表中的每个存储单元都由动态存储分配函数获得.
a>各次动态分配的存储单元并不连续;
b>各数据之间存在接续关系;
c.>每个结点都由数据域和指针域组成.指针域:存放下一结点元素的地址.
d>每个结点元素没有自己的名字,只能通过指针维系各个结点之间的接序关系.
e>一旦链表中某一个元素断开,后续的元素也与链表断开.
动态链表包括:头指针,头结点(可无,没有数据域),结点,尾结点.
构建动态单向链表:读取数据域中要存入的数据;生成新结点:申请结点空间,malloc();将数据存放到结点的数据域中;将新结点插入到链表中.
//动态链表
struct list
{
int data;
struct list * next;
};
struct list* creatlist()
{
int c;
scanf("%d",&c);
struct list *h,*r,*s;
h = (struct list *)malloc(sizeof(struct list));
h->data=0;
r=h;
while(-1!=c)
{
s=(struct list*)malloc(sizeof(struct list));
s->data=c;r->next=s;r=s;s->next='/0';//将数据存入到数据域,将结点指针下移到当前结点.
scanf("%d",&c);
}
return h;
}