My Queue implementation is correct?
1 It would be more natural to have a field size instead of tail:

struct queue {
    int array[MAX];
    int head;
    int tail;   
};


2 If you had size field, checking whether the queue is empty or 
full would be a simple one-liner.

    if((p-&gt;tail == MAX-1 &amp;&amp; p-&gt;head == 0 ) || (p-&gt;head == p-&gt;tail+1)) {
        printf("\nQUEUE IS FULL!!   ");
        return;
    }


3 It's not cool to print from algorithms unless debugging.

int DEQUEUE(struct queue* p) {
    if(p-&gt;head == p-&gt;tail) {
        printf("\nQUEUE IS EMPTY!!");
        return -1;
    }


4 Can make the output of this more pretty.

void SHOWQUEUE(struct queue* p) {
    ...
}


5 The convention is not to prepend malloc with a type.

Q = (struct queue*) malloc(sizeof (struct queue));


Instead, do this

Q = malloc(sizeof(struct queue));


6 Don't do this:

Q-&gt;head = 1;
Q-&gt;tail = 1; 


Instead, you should write the function that initializes your queue.

7 Above, it's funny that you start indexing from 1.

Summa summarum

You could consider something like the following:

queue.h:

#ifndef QUEUE_H
#define QUEUE_H

#include &lt;stdbool.h&gt;
#include &lt;stdlib.h&gt;

#define CAPACITY 10

typedef struct queue {
    int storage[CAPACITY];
    size_t head;
    size_t size;
} queue;

void queue_init(queue* q);
bool queue_enqueue(queue* q, int element);
int  queue_dequeue(queue* q);
void queue_print(queue* q);

#endif


queue.c

#include "queue.h"
#include &lt;stdlib.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;

void queue_init(queue* q)
{
    if (!q) 
    {
        return;
    }

    q-&gt;head = 0;
    q-&gt;size = 0;
}

bool queue_enqueue(queue* q, int element)
{
    if (!q || q-&gt;size == CAPACITY)
    {
        return false;
    }

    q-&gt;storage[(q-&gt;head + q-&gt;size++) % CAPACITY] = element;
    return true;
}

int queue_dequeue(queue* q)
{
    if (!q || q-&gt;size == 0)
    {
        return 0;
    }

    int ret = q-&gt;storage[q-&gt;head];
    q-&gt;head = (q-&gt;head + 1) % CAPACITY;
    q-&gt;size--;
    return ret;
}

void queue_print(queue* q)
{
    if (!q)
    {
        printf("null");
        return;
    }

    printf("[");

    for (size_t i = 0, index = q-&gt;head; i &lt; q-&gt;size; ++i)
    {
        printf("%d", q-&gt;storage[index]);

        if (i &lt; q-&gt;size - 1)
        {
            printf(", ");
        }

        index = (index + 1) % CAPACITY;
    }

    printf("]");
}


main.c:

#include "queue.h"
#include &lt;stdio.h&gt;

int main() {
    queue q;
    queue_init(&amp;q);

    for (int i = 0; i &lt; 5; ++i)
    {
        queue_enqueue(&amp;q, i);
    }

    for (int i = 0; i &lt; 10; ++i)
    {
        queue_print(&amp;q);
        puts("");
        queue_enqueue(&amp;q, queue_dequeue(&amp;q));
    }

    return 0;
}


Hope that helps.