c语言的动态链表创建的代码明明是按照树上打的,却不对

c语言的动态链表创建的代码明明是按照树上打的,却不对,求解惑。
#include<stdio.h>
#include<malloc.h>
struct link
{
int num;
char name;
struct link *next;
};
struct link *create()
{
char ch;
struct link *p1,p2,h=NULL;
p1=(struct link
)malloc (sizeof(struct link));
scanf("%d %s",&p1->num,&p1->name);
while(p1->num!=0){
if(h==NULL){
h=p2=p1;
}else{
p2->next=p1;
p2=p1;
}
p1=(struct link
)malloc (sizeof(struct link));
scanf("%d %s",&p1->num,&p1->name);
}
p2->next=NULL;
return h;
}

struct link *hprintf(struct link *h)
{
struct link *p;
if(h=NULL){
printf("链表为空");
}else {
p=h;
}
while(p!=NULL){
printf("%s %d",p->name,p->num);
p=p->next;
}

}
int main()
{
struct link *pt;
pt=create();
hprintf(pt);
return 0;
}
问题就出现在这里,会直接跳过循环条件判断,而且printf也无法运行。
while(p!=NULL){
printf("%s %d",p->name,p->num);
p=p->next;
}

修改处见注释,供参考:

#include <stdio.h>
#include <malloc.h>
struct link
{
    int  num;
    char name[16];  //char name;  修改
    struct link* next;
};
struct link* create()
{
    //char ch;    修改
    struct link* p1, * p2, * h = NULL;
    p1 = (struct link*)malloc(sizeof(struct link));
    scanf("%d %s", &p1->num, p1->name);
    //scanf("%d %s", &p1->num, &p1->name);  修改
    while (p1->num != 0) {
        if (h == NULL) {
            h = p2 = p1;
        }
        else {
            p2->next = p1;
            p2 = p1;
        }
        p1 = (struct link*)malloc(sizeof(struct link));
        scanf("%d %s", &p1->num, p1->name);
        //scanf("%d %s", &p1->num, &p1->name); 修改
    }
    p2->next = NULL;
    return h;
}

void  hprintf(struct link* h)
//struct link* hprintf(struct link* h)  修改
{
    struct link* p;
    if (h == NULL) {   //if (h = NULL)  修改
        printf("链表为空");
    }
    else {
        p = h;
        while (p != NULL) {
            printf("%s %d\n", p->name, p->num); //修改
            p = p->next;
        }
    }
}
int main()
{
    struct link* pt;
    pt = create();
    hprintf(pt);
    return 0;
}