能帮我讲解一下链表的原理吗,高手帮忙

如题。假设三个学生,他们的学号和分数(实际上是谭浩强的例子)。#include<stdio.h>#include<stdlib.h>#defineNULL0#define... 如题。
假设三个学生,他们的学号和分数(实际上是谭浩强的例子)。
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
#define LEN sizeof(struct student)

//创建一个链表
struct student
{
long num;
float score;
struct student *next;
};
int n;
struct student *creat(void)
{
struct student *head;
struct student *p1,*p2;
n=0;
p1=p2=(struct student *)malloc(LEN);
scanf("%ld,%lf",&p1->num,&p1->score);
head=NULL;
while(p1->num!=0)
{
n=n+1;
if(n==1)head=p1;
else p2->next=p1;
p2=p1;
p1=(struct student *)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
}
p2->next=NULL;
return(head);
}
这个例子我很多地方不明白。
1:struct student *creat(void),这段有什么用?不要行不行?后面的void,是表示没有参数,还是说没有返回值?为什么有时候void表示函数没有参数,有时候表示没有返回值,怎么区分?
2: if(n==1)head=p1;,这一句意思是说n如果等于1,则head=p1,是把p1这个指针变量的地址给head,还是把p1所指的结构体地址给head?
3:else p2->next=p1,意思是说如果n不等于1,则 p2->next=p1,这什么意思,这时输入的是第二数据了,难道是把第二数据next指向第一个结构体所在地址?这不反了吗?是不是因为底下的那一句p1=p2,又把他们位置换过来了?
4: p1=(struct student *)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score);
}
p2->next=NULL;
为什么又搞一个p1=(struct student *)malloc(LEN),之前不是已经为p1分配了空间了吗?scanf为什么也要重复?
在下是一个超级菜鸟,不懂到应该如何去提问题,还请高手不吝赐教,小弟感激不尽。
展开
 我来答
FrankGaocy
2010-12-10 · TA获得超过779个赞
知道小有建树答主
回答量:160
采纳率:0%
帮助的人:135万
展开全部

第一个问题:

struct student *creat(void)

{

……

}

这是一个函数体,就比如 int my_function(char a, char b){……}一样;

其中 struct student * 就相当于上面比如中的 int , 是函数的返回类型,只不过这个类型有点复杂,准确的说是:student结构(自定义)的一个指针类型。

creat 是函数名(相当于比如中的 my_funcation)。

void 是指没有参数(不需要参数)。

总结:

函数是C语言组成的基本单位(是C语言的细胞)。每一个程序都是有若干函数组合在一起,按照一定得逻辑顺序合作完成预定目标的。

所以一定要认识清楚函数是如何构成的:(函数的组成如下)

函数的返回值类型 函数名( 参数列表 )

{

函数体

}

第二个问题:

 if(n==1) head=p1;

当n等于1时,将p1的值赋给head。(因为head和p1都是指针类型,所以该赋值的作用是:

让指针head指向p1所指向的地址。)

第三个问题和第四个问题:

显然,这2个问题都是由于你还没有认清什么是结构体链表。下面我试图给你解释下结构体链表的构成方式:

首先,你要知道程序(或说计算机)是如何来保存一个变量的。

我们把计算机的内存比作一个大宾馆,这个宾馆中有若干房间,房间可以用来住人(存放数据),每个房间都是有房间编号的(内存地址)。

下面我们举例,在程序中定义一个变量并给它赋值为100:“int a = 100; ”

对于这条语句计算机在内存中开辟一个空间(地址为01),并将100这个数写入到这个空间。

这就相当于有个旅客(100)住进了大宾馆的某个房间(房间编号为01)。

在C语言中任何一个变量都是这样处理的。下面我们来看看【结构体】是怎样构成的:

struct student

{

   long num;

   float score;

   struct student *next;

};

以这个结构体为例,用该结构体定义一个变量struct student a;

则在内存中开辟一个空间来存放a的内容,

(而a不是一个人来宾馆住店,a是个小团体,成员有num,score,next,所以宾馆给a开了个套房!)

下面我们图示说明如何用【结构体】来构成一张【链表】:

如果图中的链表你看懂了,那么这个程序应该就没什么大问题了,当然还有最后一点,关于

【为什么又搞一个p1=(struct student *)malloc(LEN),之前不是已经为p1分配了空间了吗?】

正是因为有一个【新的结构体类型数据】要加入这张【链表】,所以要给新数据分配新空间(也就是在大宾馆中,又来个个小团体,所以再开一个套房!当然scanf要给这个小团体的成员进行登记。)

百度网友aa6c03b
2010-12-10 · TA获得超过610个赞
知道小有建树答主
回答量:328
采纳率:0%
帮助的人:294万
展开全部
1:struct student *creat(void) ,这个函数实际上就是实现了链表的创建,struct student,是链表中存 储的数据结构。所以不能不要,而且非常重要。

2.void 如果用在参数时 就像你这个程序,struct student *creat(void),在这里函数create(),不接受任何参数的话最好写成create(void);所以上面的程序是比较规范的写法,而返回值的类型,是函数名前面的那个 类型,struct student *,create()这个函数返回的是一个struct student类型的指针。如果是 void create(void); 不接收任何参数,也不返回任何值。 void create(int x); 接收 int 型参数,不返回任何值。

3. if(n==1)head=p1;用你的话说是把p1所指的结构体地址给head,也可以说,p1和head 都指向一块内存,那块就是 p1=(struct student *)malloc(LEN) 这里malloc出来的内存。

4.这里的逻辑,你可能不是很清楚,通俗的讲吧,p1 代表一个学生的数据,p2 也代表一个学生的数据, p2 其实起到了一个传递的作用,就是 第一步.p1和p2指向一个数据 , 第二步,p1去接收新值, 第三步 p1 把这个数据放到p2 后面(p2->next),第四步,p2后移一个,也就是指向了新加进来的数据p1,也就是指向了当前这个链表的最后一个数据,返回第二步,这样循环执行。

5.它要新开辟一个空间来存储新的数据,通俗的说我们为你开辟的内存进行编号,你之前开辟的空间假设为1,1这里面的数据是同学A的信息,链表的第一个数据,实际上就是你开辟的空间1,如果你想要再加入另外同学B的信息,那么你就要开辟出来空间2来存B的信息。即 (空间1) -> (空间2) 。我们假设你没有新开辟空间接收新数据的话,那么B的信息,将会存到空间1里面,也就说会覆盖掉,A的信息,而你链表里面存在的这两个数据,实际上都是空间1,数据都为你最新的数据,即B同学的数据。就编程了(空间1)->(空间1).

6.scanf 重复,因为你要一直接收数据呀,你看,当你进入到while循环里的时候,如果数据处理完不用scanf新的数据的话,你就只能接收一次数据了呀。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
有颗小虎牙啊E2
推荐于2016-12-01 · TA获得超过158个赞
知道答主
回答量:29
采纳率:0%
帮助的人:0
展开全部
首先回答您的问题。
1.struct student *creat(void)是一个函数,作用是建立一个关于学生档案的链表,返回头结点head地址。后面的void表示该函数不需要任何参数,返回值是头结点地址,我刚刚已经说过了。当void在函数后的括号中,表示没有参数,如果在开头,比如说void student *creat(),则表示没有返回值。具体要根据程序要求确定。
2.head=p1,指的是将p1所指的结构体地址给head,然后head也指向p1所指的那结构体。
3.请注意,该函数中p2指向的结点是p1指向结点的前一个。请按程序运行的顺序看下去,总体逻辑是p1先建立一个结点,然后head也指向它。同时p2指向它,可以保留结点的地址,接着p1建立新的结点,p2->next指向p1指向的新结点,才建立了链表。
4.这就是p1建立一个新的结点,这是下一个学生的数据,所以要重新输入。之前p1指向的地址是上一个学生的数据,由p2指向它。

下面的我给程序的注释,请看一下。
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
#define LEN sizeof(struct student)

//创建一个链表
struct student
{
long num;
float score;
struct student *next;
};
int n;
struct student *creat(void)
{
struct student *head;
struct student *p1,*p2;
n=0; //表示现在还没有任何结点
p1=p2=(struct student *)malloc(LEN);//建立两个新的结点
scanf("%ld,%lf",&p1->num,&p1->score);//输入p1所指向结点的数据
head=NULL;//头结点head目前为空
while(p1->num!=0)//表示输入完所有数据之后,再输入p1所指向的结点num值为0,退出函数,并返回头结点。
{
n=n+1;//结点数加1
if(n==1)head=p1; //此时p1所指向的结点为头结点,让head也指向它。
else p2->next=p1;//p2指向的结点为p1指向结点的前一个,故将p1指向结点的地址赋给p2->next
p2=p1;//p2指向p1原来指向的结点,保留这个结点地址,这样,p1就可以指向新的地址、
p1=(struct student *)malloc(LEN);//p1指向新的地址
scanf("%ld,%f",&p1->num,&p1->score);//输入p1数据。
}
p2->next=NULL;//循环结束,说明所有结点已经输入完毕,故p2->next指向空地址。
return(head);
}

希望我解释明白了,还有不明白的地方,可以给我留言。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
qizhi0119
2010-12-10 · TA获得超过357个赞
知道小有建树答主
回答量:510
采纳率:0%
帮助的人:273万
展开全部
是想学习还是应付考试?
如果想学习的话,估计你前面的章节的基础知识掌握的不够好,
建议再重看一下,谭的书我自己看的时候感觉比较基础,挺适合初学的.
如果应付考试,我就不发表意见了..
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
hydonlee
2010-12-10 · TA获得超过590个赞
知道小有建树答主
回答量:859
采纳率:0%
帮助的人:481万
展开全部
你知道的太多了。你要知道的再少一些,就不会有这么多问题了。

1.请深刻理解函数的概念及使用方法。
2.再学习下指针与指针操作。(谭老的书上有)
3.这个要理解链表的结构,建议先从书上找到图,自己画一下。。。
4.画程序流程图,要理解循环结构的使用。

不要找哥,哥也菜过。。。基础打好,以上自然通。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(4)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式