c语言从无到有建立链表,求代码详解

typedef struct Student
{
int age;
int score;

struct Student * next;
}ST;

ST * create_list()
{
ST * head;
ST * tail;
int len, i;

head = (ST *)malloc( sizeof(ST) );
if(head == NULL)
{
printf("内存分配失败,程序退出!\n");
exit(-1);
}

tail = head;
tail->next = NULL;

printf("您想创建几个节点?\n");
scanf("%d", &len);

for(i=0; i<len; i++)
{

ST * pNew = (ST *)malloc( sizeof(ST) );
if(pNew == NULL)
{
printf("创建了%d个链表,剩余%d个创建失败,程序退出", i+1, len-1-i);
exit(-1);
}
printf("请输入第%d个学生的年龄和成绩\n", i+1);
scanf("%d %d", &pNew->age, &pNew->score);

tail->next = pNew;
tail = pNew;
pNew->next = NULL;

}

return head;
}
只截取了一部分,其中有这三行代码
tail->next = pNew;
tail = pNew;
pNew->next = NULL;
第一行的意思是将tail中的next域更新成新生成的节点,也就是让前一个节点的指针域指向新生成的节点,第二行执行的tail = pNew,不会将前一个节点的内容给覆盖,或者让前一个节点的内容丢失吗?我总想不通,假如说用户要建立两个节点,
在第一个建立完成后,继续第二次创建,也就是说第一次将pNew中的age和score赋给了tail中的age和score,那么第二次我觉得链表的节点指向好像没有更新啊,如果改成tail = tail->next我还能明白。那么tail = pNew,执行的到底是什么操作呢?求大神详解。
个人想法

  ST * pNew = (ST *)malloc( sizeof(ST));     // 为新节点分配存储空间
  printf("请输入第%d个学生的年龄和成绩\n", i+1);
  scanf("%d %d", &pNew->age, &pNew->score);  // 赋值给新节点的内容
  tail->next = pNew;                         // 现有的链表尾指针指向新节点
  tail = pNew;                               // 移动尾指针至新节点
  // 不会丢失节点,因为链表可以用头指针head遍历
  pNew->next = NULL;                         // 尾节点指针

追问

现在就再糊涂中,先说int *a, *b;
假设b已经分配了一块合法的内存空间,a = b中b给a传递的是什么?在
tail->next = pNew;
tail = pNew;
中,是不是第一句才是将指针后移的操作呢?还是第二句呢?哎呀,彻底蒙了,求求我吧哥

追答

head -> node1 -> node2 -> node3   pNew

                                               ^

                                               |

                                             tail

假设此时 tail 指向 node3,此时没有指针指向 pNew


tail->next = pNew;  // 这一步的效果如下:

head -> node1 -> node2 -> node3 -> pNew

                                               ^

                                               |

                                             tail



tail = pNew;  // 这一步使得 tail 指向 pNew。

head -> node1 -> node2 -> node3 -> pNew

                                                              ^

                                                              |

                                                            tail


现在可以把 pNew 看作 node4,

head -> node1 -> node2 -> node3 -> node4

                                                              ^

                                                              |

                                                            tail

追问

也就是说每一次的指针指向都是有指针移动的?

追答tail->next = pNew;  // 这一步的效果如下:node3 指向了 pNew,注意tail 本身没有移动

head -> node1 -> node2 -> node3 -> pNew

                                               ^

                                               |

                                             tail



tail = pNew;  // 这一步才移动了 tail

 head -> node1 -> node2 -> node3 -> pNew

                                                              ^

                                                              |

                                                            tail

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-09-30
tail->next = pNew;这一句是让tail指针指向pnew对应的结点地址;tail = pNew;这一句是把pnew对应的结点地址给tail即是让tail指向pnew对应的结点;最后是将pnew结点后继置为空;我也是初学者;希望对你有所帮助。
第2个回答  2013-09-30
tail = pNew

这时候tail指向了后一个结构体,tail只是一个指针,它随着数据添加而向后移动,它的移动不覆盖任何值。
head永远指向头结点,不移动。

做数据结构需要你拿着笔在纸上画一下,这样清晰很多。追问

画了半天了,思路是不是错了?我以前总以为tail里面以前的数据丢失了

追答

tail是一个指向机构体的指针,其中的数据域用不着,只用到指针域,tail有什么数据丢失可言呢?