C言语教程第七章:布局与连系(7)


[例7.14]把以上设立设置配备摆设链表,删除结点,拔出结点的函数构造在一路,再建一个输出一切结点的函数,然后用main函数挪用它们。
#define NULL 0
#define TYPE struct stu
#define LEN sizeof(struct stu)
struct stu
{
int num;
int age;
struct stu *next;
};
TYPE * creat(int n)
{
struct stu *head,*pf,*pb;
int i;
for(i=0;i<n;i )
{
pb=(TYPE *)malloc(LEN);
printf("input Number and Age\n");
scanf("%d%d",&pb->num,&pb->age);
if(i==0)
pf=head=pb;
else pf->next=pb;
pb->next=NULL;
pf=pb;
}
return(head);
}
TYPE * delete(TYPE * head,int num)
{
TYPE *pf,*pb;
if(head==NULL)
{ printf("\nempty list!\n");
goto end;}
pb=head;
while (pb->num!=num && pb->next!=NULL)
{pf=pb;pb=pb->next;}
if(pb->num==num)
{ if(pb==head) head=pb->next;
else pf->next=pb->next;
printf("The node is deleted\n"); }
else
free(pb);
printf("The node not been found!\n");
end:
return head;
}
TYPE * insert(TYPE * head,TYPE * pi)
{
TYPE *pb ,*pf;
pb=head;
if(head==NULL)
{ head=pi;
pi->next=NULL; }
else
{
while((pi->num>pb->num)&&(pb->next!=NULL))
{ pf=pb;
pb=pb->next; }
if(pi->num<=pb->num)
{ if(head==pb) head=pi;
else pf->next=pi;
pi->next=pb; }
else
{ pb->next=pi;
pi->next=NULL; }
}
return head;
}
void print(TYPE * head)
{
printf("Number\t\tAge\n");
while(head!=NULL)
{
printf("%d\t\t%d\n",head->num,head->age);
head=head->next;
}
}
main()
{
TYPE * head,*pnum;
int n,num;
printf("input number of node: ");
scanf("%d",&n);
head=creat(n);
print(head);
printf("Input the deleted number: ");
scanf("%d",&num);
head=delete(head,num);
print(head);
printf("Input the inserted number and age: ");
pnum=(TYPE *)malloc(LEN);
scanf("%d%d",&pnum->num,&pnum->age);
head=insert(head,pnum);
print(head);
}
  本例中,print函数用于输出链表中各个结点数据域值。函数的形参head的初值指向链表第一个结点。在while语句中,输出结点值后,head值被变革,指向下一结点。若保存头指针head, 则应另设一个指针变量,把head值赋予它,再用它来替代head。在main函数中,n为设立设置配备摆设结点的数目, num为待删结点的数据域值;head为指向链表的头指针,pnum为指向待插结点的指针。 main函数中各行的意义是:
第六行输出所建链表的结点数;
第七行调creat函数设立设置配备摆设链表并把头指针前往给head;
第八行调print函数输出链表;
第十行输出待删结点的学号;
第十一行调delete函数删除一个结点;
第十二行调print函数输出链表;
第十四行调malloc函数分配一个结点的内存空间, 并把其地址赋予pnum;
第十五行输出待拔出结点的数据域值;
第十六行调insert函数拔出pnum所指的结点;
第十七行再次调print函数输出链表。

  从运转结果看,首先设立设置配备摆设起3个结点的链表,并输出其值;再删103号结点,只剩下105,108号结点;又输出106号结点数据, 拔出后链表中的结点为105,106,108。连系“连系”也是一种布局典范的数据布局。 在一个“连系”内可以定义多种差此外数据典范, 一个被声明为该“连系”典范的变量中,准许装入该“连系”所定义的任何一种数据。 这在前面的各种数据典范中都是办不到的。比方, 定义为整型的变量只能装入整型数据,定义为实型的变量只能赋予实型数据。

  在理论问题中有良多这样的例子。 比方在学校的教员和高足中填写以下表格: 姓 名 年 龄 职 业 单位 “职业”一项可分为“教员”和“高足”两类。 对“单位”一项高足应填入班级编号,教员应填入某系某教研室。 班级可用整型量示意,教研室只能用字符典范。 要求把这两种典范差此外数据都填入“单位”这个变量中, 就必需把“单位”定义为包含整型和字符型数组这两种典范的“连系”。

  “连系”与“布局”有一些类似之处。但两者有实质上的差别。在布局中各成员有各自的内存空间, 一个布局变量的总长度是各成员长度之和。而在“连系”中,各成员共享一段内存空间, 一个连系变量的长度等于各成员中最长的长度。应该声明的是, 这里所谓的共享不是指把多个成员同古装入一个连系变量内, 而是指该连系变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。如前面介绍的“单位”变量, 如定义为一个可装入“班级”或“教研室”的连系后,就准许赋予整型值(班级)或字符串(教研室)。要么赋予整型值,要么赋予字符串,不能把两者同时赋予它。连系典范的定义和连系变量的声明一个连系典范必需经过定义之后, 才华把变量声明为该连系典范。



版权声明: 原创作品,准许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。不然将穷究功令责任。

原文地址:https://www.cnblogs.com/zgqjymx/p/1975579.html