C语言链表头结点前如何假如新结点

//stduent.h
typedef struct date
{
    int year;
    int month;
    int day;
}DATE;
//姓名、性别、民族、出生日期、班级、地址、手机号码、宿舍
typedef struct student
{
    char xm[20];
    char xb;
    char mz[15];
    DATE csrq;
    char bj[20];
    char dz[50];
    char sj[12];
    char ss[14];
    struct student* next;
}STUDENT;
struct student* head;
struct student* new;




#include "stdio.h"
#include "student.h"
#include "stdlib.h"
#include "string.h"
#pragma warning(disable:4996)
/*
SL:学生信息组成的单链表
newStudent:需要加入进来的新的学生结点 
*/
STUDENT * tianjiaxuesheng(STUDENT * SL,STUDENT * newStudent)
{
    STUDENT *p1,*p2;
    //判断链接  SL是否 为空。
    if(SL==NULL)
    {
        SL=newStudent;
        newStudent->next=NULL;//将新加入结点的指针域,设置为NULL 
    } else
    {
        //定位链表的最后一个结点 
        p1=SL;//让p1指向链表 的第一个结点
        p2=SL;
        while(p1) 
        {
            p2=p1;
            p1=p1->next;
        };
        //当跳出while循环的时候,说明 p1已经指向链表的最后一个结点 
        p2->next = newStudent;
        newStudent->next=NULL;         
    }    
    return SL; 
}
STUDENT * ShanChu(STUDENT * SL,char xm[])
{
    STUDENT *p1,*p2;
    p1=SL;
    p2=SL;
    //检查是否是首结点
    if(strcmp(p1->xm,xm)==0) 
    {
        p2=p1->next;
        free(p1);
        return p2;
    }
    while(p1)
    {
        if(strcmp(p1->xm,xm)==0)//姓名匹配成功,执行删除操作 
        {
            p2->next=p1->next;
            free(p1);
            break;
        }
        p2=p1; 
        p1=p1->next;
    };
    return SL;
}
//对应菜单 添加  的函数 
STUDENT * TianJia(STUDENT * SL)
{    
    STUDENT *pNew;
    pNew=(STUDENT *)malloc(sizeof(STUDENT));
    int year,month,day;
    DATE cs={1976,1,15}; 
    char xm[20],mz[20],bj[20],dz[50],sj[12],ss[50];
    char xb;
    printf("请输入要添加的学生信息:\n");
    printf("姓名:");
    gets(xm);
    strcpy(pNew->xm,xm);
    printf("性别(M/F):");
    xb=getchar();
    getchar(); 
    pNew->xb=xb;
    printf("民族:");
    gets(mz);
    strcpy(pNew->mz,mz) ;
    printf("出生日期(year-month-day):");
    scanf("%d-%d-%d",&year,&month,&day);
    pNew->csrq.year=year;pNew->csrq.month=month;pNew->csrq.day=day;
    getchar();//吸收所按的回车键 
    printf("班级:");
    gets(bj);    
    strcpy(pNew->bj,bj);
    printf("地址:");
    gets(dz);    
    strcpy(pNew->dz,dz);
    printf("手机:");
    gets(sj);
    strcpy(pNew->sj,sj);
    printf("宿舍:");
    gets(ss);    
    strcpy(pNew->ss,ss);
    pNew->next=NULL;
        
    SL=tianjiaxuesheng(SL,pNew);
    //printf("TianJia-SL:%s\n",SL->bj); 
    return ;
}



void LiuLan(STUDENT *SL)
{
    printf("***学生信息浏览***\n");
    printf("姓名\t性别\t民族\t出生日期\t班级\t\t地址\t\t手机\t\t宿舍\n");
    STUDENT *p1,*p2;
    p1=SL;
    while(p1)
    {
        printf("%s\t%c\t%s\t%d-%d-%d\t%s\t%s\t%s\t%s\n",p1->xm,p1->xb,p1->mz,p1->csrq.year,p1->csrq.month,p1->csrq.day,p1->bj,p1->dz,p1->sj,p1->ss);
        p1=p1->next;
    };
    return ;
}
STUDENT * DaKai(STUDENT *SL) 
{
    FILE *fp;
    STUDENT *p1,*p2;
    fp=fopen("student.dat","rb");
    if(fp==NULL)
    {
        printf("文件打开失败\n");
        return;
    }
    while(1)
    {
        p1=(STUDENT *)malloc(sizeof(STUDENT));
        fread(p1,sizeof(STUDENT),1,fp);
        if(feof(fp))  break;//如果文件尾,则结束循环 
        SL=tianjiaxuesheng(SL,p1);
    }
    fclose(fp);
    return SL;
}
//修改指定姓名的学生信息 
STUDENT * XiuGai(STUDENT *SL,char xm[])
{
    STUDENT *p1,*p2;
    p1=SL;
    p2=SL;
    int k;
    char xmNew[20],xbNew,sjNew[12],bjNew[20], dzNew[50], ssNew[50],mzNew[20];
    int newyear,newmonth,newday;
    while(p1)
    {
        if(strcmp(p1->xm,xm)==0)//姓名匹配成功,执行修改操作 
        {
            printf("请选择你要修改的数据字段:\n");
            printf("1.姓名\n");
            printf("2.民族\n");
            printf("3.性别\n");
            printf("4.出生日期\n");
            printf("5.班级\n");
            printf("6.地址\n");
            printf("7.手机\n");
            printf("8.宿舍\n");
            scanf("%d",&k);
            getchar(); 
            switch(k)
            {
                case 1:
                       printf("请输入新的姓名:");
                       gets(xmNew);
                       strcpy(p1->xm,xmNew);
                       break;
                case 2:
                       printf("请输入新的民族:");
                       gets(mzNew);
                       strcpy(p1->mz,mzNew);
                       break;
                case 3:
                       printf("请输入新的性别(M/F):");
                       xbNew=getchar();
                       getchar();
                       p1->xb=xbNew;
                       break;                
                case 4:printf("出生日期(year-month-day):");
                       scanf("%d-%d-%d",&newyear,&newmonth,&newday);
                       p1->csrq.year=newyear;p1->csrq.month=newmonth;p1->csrq.day=newday;
                       getchar();
                       break;
                case 5:
                       printf("请输入新的班级:");
                       gets(bjNew);
                       strcpy(p1->bj,bjNew);
                       break;
                case 6:printf("请输入新的地址:");
                       gets(dzNew);
                       strcpy(p1->dz, dzNew);
                       break;
                case 7:printf("请输入新的手机:");
                       gets(sjNew);
                       strcpy(p1->sj, sjNew);
                       break;
                case 8:printf("请输入新的宿舍:");
                       gets(ssNew);
                       strcpy(p1->ss, ssNew);
                       break;
            } 
        }
        p2=p1; 
        p1=p1->next;
    };
    return SL;
}
void BAOCUN(STUDENT *SL)
{
    FILE *fp;
    STUDENT *p1,*p2;
    fp=fopen("student.dat","wb");
    if(fp==NULL)
    {
        printf("文件打开失败,无法保存学生信息。\n");
        return;
    }
    p1=SL;//让p1指向链表 的第一个结点
    while(p1) 
    {
        p2=p1;
        //将 p2所指向的结点数据,写入文件 fp
         fwrite(p2,sizeof(STUDENT),1,fp);
        p1=p1->next;
    };
    
    fclose(fp);
}
void* sort(STUDENT* SL)
{
    //插入排序
    new = (struct student*)malloc(sizeof(struct student));
    head = (struct student*)malloc(sizeof(struct student));
    head = SL;
    new->next = head; 

    struct student* p = head, * q, * tail;
    int i, j, num = 0;
    while (p->next)
    {
        p = p->next;
        num++;
    }
    for(i=0;i<num-1;i++)
    {
        p = head;
        q = p->next;
        tail = q->next;
        num = num - i - 1;
        while (num--)
        {
            if (strcmp(tail->sj,q->sj))
            {
                q->next = tail->next;
                tail->next = q;
                p->next = tail;
            }
            p = p->next;
            q = p->next;
            tail = q->next;
        }
    }
    printf("链表排序完成!\n");
}

我想再成功进行sort排序,在第一个有数据的结点前再加一个首结点,像问一下,有没有办法解决

你可以建立一个空的头结点,使其指针指向现在的头结点就可以了

你的sort中new->next = head;的意思是在当前第一个有数据的节点前再加了一个首节点new。不过在这里好像没什么意义。
这里要设置head = SL;的话head = (struct student*)malloc(sizeof(struct student))就不需要了。可以直接head = SL;
你这排序好像有点问题,for循环了num-1次相同的内容。建议直接使用while循环来实现,代码参考如下:

struct student *p = head, *q = head;
while (p->next != NULL) {
    student *tail = p;
    q = p->next;
    while (q != NULL) {
        if (strcmp(tail->sj, q->sj)) {
            tail = p;
        }
        q = q->next;
    }
    if (p != tail) {
        // 交换数据
        struct student temp = *p;
        *p = *tail;
        *tail = temp;
        // 交换指针
        temp.next = p->next;
        p->next = tail->next;
        tail->next = temp.next;
    }
    p = p->next;
}
printf("链表排序完成!\n")