链表结点的创建问题

#include <stdio.h> #include <stdlib.h> #include "malloc.h" #define NULL 0 struct student { long int number; char name[20]; float score; struct student *next; }; struct student *creat(struct student *head); void output(struct student *head); void main(void) { struct student *head; head=NULL; head=creat(head); output(head); } struct student *creat(struct student *head) { int n=1; struct student *p1,*p2; p1=p2=(struct student*)malloc(sizeof(struct student)); printf("input %dth number,name,score:\n",n++); scanf("%d%s%f",&p1->number,&p1->name,&p1->score); p1->next=NULL; while(p1->number>0) { if(head==NULL) head=p1; else p2->next=p1; p2=p1;/****/ p1=(struct student*)malloc(sizeof(struct student)); printf("input %dth name,score:\n",n++); scanf("%d%s%f",&p1->number,&p1->name,&p1->score); p1->next=NULL; } free(p1); return head; } void output(struct student *head) { while(head!=NULL) { printf("学号:%ld,姓名:%s,成绩:%5.2f\n",head->number,head->name,head->score); head=head->next; } }求解释心中的疑问。
上面的“struct student *creat(*head)”函数的作用是创建链表结点,在开始的时候指针p1 p2都指向申请好的“struct student”型的地址单元,在给p1所指的空间赋值之后,进入while循环体中,起初判断头指针为空后,后将头指针指向新的结点p1,然后又把p1的地址赋给p2。我的问题是起初申请的空间不是p1 p2 共同指向吗?为何还要再赋?还有头指针非空,执行一次循环体之后回来,通过语句“p2->next=p1”将新创建的结点与上一个结点链接起来,这是p2所指结点的指针域中存放p1,也就是使p2指向了p1,为何还要有“p2=p1'',将p1赋给p2呢?好像怪怪的?
求解释