链表模拟队列问题(c语言)

问题遇到的现象和发生背景

题目如下:
模拟一个队列,实现以下操作
1 x : 将x元素入队(1<=x<=1000)
2: 访问队首,如果队列为空则不输出
3: 出队,如果队列为空则不操作
输入
第一行,一个n表示操作的次数(1<=n<=105)
接下来n行开头是一个数字(1-3),如题目描述所示
对于操作1还有一个数字,表示要入队的元素的值。
输出
对于操作2,你需要输出队首元素

遇到的现象和发生背景,请写出第一个错误信息

无法运行,程序直接结束

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
#include 
#include 
typedef struct NODE
{
    int data;
    struct NODE* next;
}node;
typedef struct PrtQ
{
    node *head;//队列头
    node *tail;//队列尾
}prtq;

prtq *push(prtq *p,int x);
void put(prtq *p);
prtq *pop(prtq *p);

int main()
{
    int n,a;
    prtq *p;
    p->head=p->tail=NULL;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&a);
        if(a==1)
        {
            int x;
            scanf("%d",&x);
            p=push(p,x);
        }
        if(a==2)
            put(p);
        if(a==3)
            p=pop(p);
    }
    return 0;
}
prtq *push(prtq *p,int x)
{
    node * s=(node *)malloc(sizeof(node));
    s->data=x;
    s->next=NULL;
    if(p->head==NULL)
        p->tail=p->head=s;
    else
    {
        p->tail->next=s;
        p->tail=s;
    }
    return p;
}

void put(prtq *p)
{
    if(p->head==NULL)
        return;
    else
        printf("%d\n",p->head->data);
}

prtq *pop(prtq *p)
{
    if(p->head==NULL)
        return p;
    else
    {
        node * s;
        s=p->head;
        p->head=p->head->next;
        free(s);
        return p;
    }
}

运行结果及详细报错内容

程序直接结束,无错误提示

我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

链表模拟队列,PrtQ用来表示队列头尾

帮忙看下哪里出问题了

改动处见注释,供参考:

#include <stdio.h>
#include <stdlib.h>
typedef struct NODE
{
    int data;
    struct NODE* next;
}node;
typedef struct PrtQ
{
    node *head;//队列头
    node *tail;//队列尾
}prtq;
prtq *push(prtq *p,int x);
void put(prtq *p);
prtq *pop(prtq *p);
int main()
{
    int n,a;
    prtq *p = (prtq *)malloc(sizeof(prtq)); //修改
    p->head=NULL;
    p->tail=NULL;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&a);
        if(a==1)
        {
            int x;
            scanf("%d",&x);
            p=push(p,x);
        }
        if(a==2)
            put(p);
        if(a==3)
            p=pop(p);
    }
    return 0;
}
prtq *push(prtq *p,int x)
{
    node * s=(node *)malloc(sizeof(node));
    s->data=x;
    s->next=NULL;
    if(p->head==NULL){
        p->tail=s;
        p->head=s;
    }
    else
    {
        p->tail->next=s;
        p->tail=s;
    }
    return p;
}
void put(prtq *p)
{
    if(p->head==NULL)
        return;
    else
        printf("%d\n",p->head->data);
}
prtq *pop(prtq *p)
{
    if(p->head==NULL)
        return  NULL;    //p; 修改
    else
    {
        node * s;
        s=p->head;
        p->head=p->head->next;
        free(s);
        return p;
    }
}