求助,c语言结构体和链表的问题
这个程序,第一次循环执行完成后,head,p1,p2是指向同一个节点的,在执行第二次循环时,循环体内(*p2).next=p1,p1把地址给了p2的next。我理解的head和p2是两个不同的结构体变量,p2的next被p1改变,head的next值应该不变呐。
但是我执行printf("%d\n%d\n",(*p2).next,(*head).next);把他们地址打印出来发现是一样的,这是为什么啊?
按照链表的定义,这里head的next值是必须要变才能跟后面链接上的,但是我的理解head的next应该是不变的啊,大佬们我的理解哪里出了问题。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define LEN sizeof(struct student)
struct student *creat();
void print(struct student *head);
struct student
{
int num;//存放学生编号;
float score;//存放学生分数;
struct student *next;
}*stu,*p1,*p2;
int n;//记录输入次数
int main(void)
{
struct student *stu;
stu=creat();
print(stu);
printf("\n\n");
system("pause");
}
struct student *creat()
{
struct student *head;
struct student *p1,*p2;
p1=p2=(struct student *)malloc(LEN);
printf("Please enter the num:");
scanf("%d",&(*p1).num);
printf("Please enter the score:");
scanf("%f",&(*p1).score);
head=NULL;//初始化头节点
n=0;
while(0!=(*p1).num)
{
n++;
if(1==n)
{
head=p1;
}
else
{
(*p2).next=p1;
if(n==2)
{
printf("%d\n%d\n",(*p2).next,(*head).next);
}
}
p2=p1;
p1=(struct student *)malloc(LEN);//再次给p1分配长度,开辟新节点
printf("Please enter the num:");
scanf("%d",&(*p1).num);
printf("Please enter the score:");
scanf("%f",&(*p1).score);
}
(*p2).next=NULL;
return head;
}
void print(struct student *head)
{
struct student *p;
printf("\nThere are %d record!\n\n",n);
p=head;
if(NULL!=head)
{
do
{
printf("学号为%d的成绩是:%f\n",(*p).num,(*p).score);
p=(*p).next;
}while(p);
}
} 本帖最后由 jackz007 于 2021-1-19 17:51 编辑
为你重写了链表创建函数,并加上了详细注释
struct student * creat()
{
struct student * head , * p1 , * p2 ;
int num ;
for(p1 = p2 = head = NULL ;;) {
printf("Please enter the num : ") ;
scanf("%d" , & num) ;
if(num > 0) { // 只有在确定 num 为正整数时才分配内存,创建节点
if((p1 = (struct student *) malloc(sizeof(struct student)))) {// 判定内存分配是否成功
p1 -> num = num ; // 到了这里,说明内存分配很成功,结构成员赋值
printf("Please enter the score : ") ; // 结构成员赋值
scanf("%f" , & p1 -> score) ; // 结构成员赋值
p1 -> next = NULL ; // 结构成员赋值
if(p2) p2 -> next = p1 ; // p1 不是首节点,让上一个节点的 next 域指向 p1
elsehead = p1 ; // p1 是首节点,让链表头指针指向首节点 p1
p2 = p1 ; // 腾出 p1 准备新建下一个节点
} else { // 如果内存分配失败
for(p1 = head ; p1 ; p1 = p2) { // 释放所有链表节点所占用的内存
p2 = p1 -> next ; // 释放所有链表节点所占用的内存
free(p1) ; // 释放所有链表节点所占用的内存
}
fprintf(stderr , "\n") ;
fprintf(stderr , "Failed to allocate memeory .\n") ;
fprintf(stderr , "\n") ;
}
} else { // 输入 num 为 0 或负值结束链表创建
break ; // 结束循环
}
}
return head ; // 返回头节点指针
} jackz007 发表于 2021-1-19 17:47
为你重写了链表创建函数,并加上了详细注释
谢谢,但是我还是那个疑问啊,链表头指针是怎么指向下一个的,head=p1;是把p1内容给head吗,如果是指向p1不应该是head->next=p1,这样把p1的地址给head的内容吗,然后才能链接上吗? 本帖最后由 jackz007 于 2021-1-20 10:41 编辑
MeowMoo 发表于 2021-1-20 09:35
谢谢,但是我还是那个疑问啊,链表头指针是怎么指向下一个的,head=p1;是把p1内容给head吗,如果是指向p ...
head = p1 就是让 head 指向链表首节点。
head 和 p1 都是指针,你可以把它理解成一种特殊的整型变量,是可以被赋值的,其数值就是内存地址,就好比是宾馆的房间编号。有 3 位客人入住一家宾馆,第一个人被分配到1802,p1 = 1802,head = p1,p2 = p1,第二个客人被分配到1303, p1 = 1303,1802 的客人知道这个信息, p2 -> next = p1 , p2 = p1,第三个客人被分配到1605,p1 = 1605,1303 的客人知道这个信息,p2 -> next = p1,我们想要找到所有的 3 个客人,只需要知道 head = 1802,这样,三位客人不都可以被找到了吗。 jackz007 发表于 2021-1-20 10:28
head = p1 就是让 head 指向链表首节点。
head 和 p1 都是指针,你可以把它理解成一 ...
意思是这个传递过程只有结构体变量地址的传递,没有结构体变量成员的值的传递吗? MeowMoo 发表于 2021-1-20 10:56
意思是这个传递过程只有结构体变量地址的传递,没有结构体变量成员的值的传递吗?
是的,你得清楚,指针和节点是有本质区别的,客人是节点,而指针,只是门牌号 -- 只不过是一个数字而已。 jackz007 发表于 2021-1-20 11:26
是的,你得清楚,指针和节点是有本质区别的,客人是节点,而指针,只是门牌号 -- 只不过是一个数 ...
好的,明白了,非常感谢大佬!
页:
[1]